我只是复制&从one of my questions粘贴了一些介绍性文本,因为同样的表格关系也包含在这个问题中。
我在Oracle(10g)数据库中有三个表,如下所示。我正在使用Hibernate Tools 3.2.1.GA和Spring 3.0.2版。
colourId
和prodId
个Colour
和Product
表ProductColour
是Product
和Colour
之间的联接表。正如表名所暗示的那样,Product
和Colour
之间存在多对多关系,由PrductColour
映射。我认为,数据库中的关系很容易想象,只有这么多信息才能清楚。因此,我不会不必要地探讨这种关系。
Product
中的实体(行)与Colour
中的任意数字实体相关联,Colour
中的实体(行)也可以与{Product
中的任意数量的实体相关联1}}。
因为它是多对多关系,所以它在Product
和Colour
实体类(POJO)中映射到它们各自的java.util.Set
并且没有直接的POJO类可以使用product_colour
表。
班级Product
如下所示。
public class Product implements java.io.Serializable
{
private BigDecimal prodId;
private Set<Colour> colours = new HashSet<Colour>(0);
.
.
.
//Other properties with setters and getters.
}
班级Colour
如下所示。
public class Colour implements java.io.Serializable
{
private BigDecimal colourId;
private Set<Product> products = new HashSet<Product>(0);
.
.
.
//Other properties with setters and getters.
}
实体之间的实际映射可以在xxx.hbm.xml
个文件中找到,关于这个问题,我认为这是不必要的。
我想要做的是只检索Colour
表格中与某一特定产品的ProductColour
表中的颜色行不匹配的行。在这方面,本机Oracle SQL语句看起来如下所示。
SELECT colour_id, colour_name, colour_hex
FROM colour
WHERE colour_id not in (SELECT colour_id FROM product_colour WHERE prod_id=81)
ORDER BY colour_id DESC
其中prod_id
可以是Java中任何有效的BigDecimal
个动态数字。
如前所述,该关系在Hibernate中以多对多关系的形式提供,数据库表product_colour
没有POJO类可用,因此,我在编写这样的HQL语句时遇到了麻烦休眠。我曾尝试编写这样的HQL语句,但没有尝试成功。
[部分其余部分提供的代码可能完全没有必要审查]
因此我遵循传统方式。我正在做的是......我首先根据动态值Product
从prodId
实体类中检索单个产品行,例如,
List<Product>list=session.createQuery("from Product where prodId=:prodId")
.setParameter("prodId", prodId).list();
然后使用循环,我得到整个Colour
集合 - java.util.Set
对应于Oracle中的product_colour
表,Product
实体中可用这个产品如,
Set<Colour>colours=new HashSet<Colour>(0);
for(Product p:list)
{
if(p!=null)
{
colours=p.getColours();
}
}
可以看出,colours
Set
正在填充Oracle中product_colour
表中可用的所有颜色行(参考行)。
获取所有这些行之后,我得到了整个Colour
实体类本身(其中的所有行),它对应于Oracle中的colour
表,然后删除那些匹配的行从product_colour
Oracle表中检索到的行(在前面代码段中的colours
中可用),满足前面提到的条件,例如,
List<Colour>colourList=session.createQuery("from Colour order by colourId desc").list();
Iterator<Colour>it=colourList.iterator();
while(it.hasNext())
{
Colour c=(Colour)it.next();
for(Colour pc:colours) //colours is available in the preceding snippet.
{
if(c==pc)
{
it.remove();
}
}
}
这可以做到预期的但是这样做可能意味着系统的一些开销。此外,这种分页的方法似乎无法实现我想要实现的目标。我不能使用setFirstResult(int)
和setMaxResults(int)
方法来完成分页任务,否则就像下面显示的Product
实体类一样,
List<Product> products=session.createQuery("from product order by prodId desc")
.setMaxResults(0).setFirstResult(4);
所以问题又是,关于这种关系,是否可以编写这样一个HQL语句,它只能检索Colour
实体类中与那些不匹配的那些行product_colour
Oracle表中的颜色行与上面显示的本机SQL语句类似?
如何实现分页的概念(如果不可能)?
答案 0 :(得分:1)
对一个长期问题的简短回答:
select colour from Colour colour
where colour.id not in (
select colour2.id from Product product
inner join product.colours colour2
where product.id = :productId)