0

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


我在 Oracle (10g) 数据库中有许多表中的三个,如下所示。我正在使用带有 Spring 3.0.2 版的 Hibernate Tools 3.2.1.GA。

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

其中表ProductColour是和之间的连接表。正如表名所暗示的那样, 和 之间存在多对多关系,由 映射。我认为,数据库中的关系很容易想象,只有这么多信息就很清楚了。因此,我不会不必要地详细探讨这种关系。ProductColourProductColourPrductColour

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


由于它是多对多关系,因此它映射ProductColour实体类 (POJO) 及其各自的实体类 (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中的颜色行不匹配的那些行。在这方面,本机 Oracle SQL 语句如下所示。ProductColour

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可以是BigDecimalJava 中动态的任何有效数字。

如前所述,该关系在 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 中的表相Colour对应的整个实体类本身(其中的所有行),colour然后删除与从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();
        }
    }
}

这可以做预期的事情,但这样做可能意味着系统上的一些开销。此外,我想要实现的目标似乎无法通过这种方法实现,即pagination。我不能使用setFirstResult(int)setMaxResults(int)方法来完成分页任务,否则就像下面显示的关于Product实体类的情况一样,

List<Product> products=session.createQuery("from product order by prodId desc")
                       .setMaxResults(0).setFirstResult(4); 

所以问题又来了,关于这种关系,是否可以编写这样一个 HQL 语句,该语句只能从实体类中检索那些与Oracle 表Colour中的颜色行不匹配的行,如上面显示的本机 SQL 语句product_colour

否则如何实现分页的概念(以防万一,这是不可能的)?

4

1 回答 1

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)
于 2012-11-14T22:09:32.493 回答