我只是复制并粘贴我的一个问题中的一些介绍性文本,因为此问题中也涉及同一表关系。
我在Oracle(10g)数据库中拥有许多表,如下所示。我使用的是Spring版本3.0.2的Hibernate Tools3.2.1.GA。
colourId
prodId
Colour
Product
该表ProductColour是和之间的 联接表 。就像表名所暗示的那样,和之间存在多对多关系,并由映射。我认为,数据库中的关系很容易想象,仅通过这么多的信息就可以清楚地知道。因此,我不会不必要地详细探讨这种关系。Product``Colour``Product``Colour``PrductColour
ProductColour
Product``Colour``Product``Colour``PrductColour
中的实体(行)Product与中的任何数量的实体关联,Colour并且中的实体(行)Colour也可以与中的任何数量的实体关联Product。
由于这是一个多对多关系,因此将其映射到Product和Colour实体类(POJO)中以及它们各自的对应关系,java.util.Set并且该product_colour表没有直接的POJO类可用。
java.util.Set
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我认为,实体之间的实际映射可在文件中找到,关于这个问题,这是不必要的。
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可以是任何有效BigDecimal的Java的数量是动态的。
prod_id
BigDecimal
如前所述,该关系在Hibernate中可以作为多对多关系使用,数据库表product_colour没有可用的POJO类,因此,我在Hibernate中编写这样的HQL语句时感到很困惑。我试图编写这样的HQL语句,但是没有成功。
[本部分其余部分中提供的代码可能完全不需要审查]
因此,我遵循的是传统方式。我正在做的是…我首先Product基于prodId诸如以下的动态值从实体类中检索单个产品行:
List<Product>list=session.createQuery("from Product where prodId=:prodId") .setParameter("prodId", prodId).list();
然后使用循环,获取整个Colour集合- java.util.Set对应product_colour于Oracle中的表,该表在Product该产品的实体中可用,例如,
Set<Colour>colours=new HashSet<Colour>(0); for(Product p:list) { if(p!=null) { colours=p.getColours(); } }
可以看出,colours Set正在使用product_colourOracle表中的所有可用颜色行(参考行)填充。
colours
Set
在获得所有这些行之后,我将获得与Oracle中Colour的colour表相对应的整个实体类本身(其中的所有行),然后删除与从product_colourOracle表中检索到的行匹配的那些行(可在coloursSet in中找到)。前面的代码段)满足前面提到的条件,例如,
colour
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实体类的显示类似,
setFirstResult(int)
setMaxResults(int)
List<Product> products=session.createQuery("from product order by prodId desc") .setMaxResults(0).setFirstResult(4);
因此 ,关于这种关系, 问题又来了 ,是否有可能编写这样的HQL语句,使其只能从Colour实体类中检索与product_colourOracle表中的颜色行不匹配的那些行, 就像上面显示的本机SQL语句一样 ?
否则,如何实现分页的概念(以防无法实现)?
veeeeery长问题的简短答案:
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)