一尘不染

基于有关Hibernate中多对多映射的特定条件检索行

jsp

我只是复制并粘贴我的一个问题中的一些介绍性文本,因为此问题中也涉及同一表关系。


我在Oracle(10g)数据库中拥有许多表,如下所示。我使用的是Spring版本3.0.2的Hibernate Tools3.2.1.GA。

  1. 产品 -父表
  2. 颜色 -父表
  3. ProductColour -连接表-引用colourIdprodIdColourProduct表分别

该表ProductColour是和之间的 联接表
。就像表名所暗示的那样,和之间存在多对多关系,并由映射。我认为,数据库中的关系很容易想象,仅通过这么多的信息就可以清楚地知道。因此,我不会不必要地详细探讨这种关系。Product``Colour``Product``Colour``PrductColour

中的实体(行)Product与中的任何数量的实体关联,Colour并且中的实体(行)Colour也可以与中的任何数量的实体关联Product


由于这是一个多对多关系,因此将其映射到ProductColour实体类(POJO)中以及它们各自的对应关系,java.util.Set并且该product_colour表没有直接的POJO类可用。

该类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可以是任何有效BigDecimal的Java的数量是动态的。

如前所述,该关系在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表中的所有可用颜色行(参考行)填充。

在获得所有这些行之后,我将获得与Oracle中Colourcolour表相对应的整个实体类本身(其中的所有行),然后删除与从product_colourOracle表中检索到的行匹配的那些行(可在coloursSet
in中找到)。前面的代码段)满足前面提到的条件,例如,

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_colourOracle表中的颜色行不匹配的那些行,
就像上面显示的本机SQL语句一样

否则,如何实现分页的概念(以防无法实现)?


阅读 181

收藏
2020-06-10

共1个答案

一尘不染

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)
2020-06-10