0

同じテーブル関係がこの質問にも関係しているため、質問の 1 つから紹介テキストの一部をコピーして貼り付けています。


以下にリストされているように、Oracle(10g)データベースに多くのテーブルのうち3つがあります。Spring バージョン 3.0.2 で Hibernate Tools 3.2.1.GA を使用しています。

  1. 製品- 親テーブル
  2. - 親テーブル
  3. ProductColour -テーブルの結合 - 参照colourIdとテーブルprodIdのそれぞれColourProduct

テーブルProductColourは と の間の結合テーブルです。テーブル名が示すように、 と の間には多対多の関係があり、によってマッピングされます。これだけの情報で、データベースの関係性は容易に想像でき、明らかだと思います。したがって、この関係を不必要に詳しく調べるつもりはありません。ProductColourProductColourPrductColour

のエンティティ (行)Productは の任意の数のエンティティに関連付けられColour、 のエンティティ (行) はColourの任意の数のエンティティに関連付けることもできますProduct


これは多対多の関係であるため、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の色の行と一致しない行のみをテーブルから一度に取得することです。この点で、ネイティブの 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

動的なJavaprod_idの有効な数値はどこにありますか。BigDecimal

前述のように、関係は Hibernate で多対多の関係として使用できます。データベース テーブルの POJO クラスproduct_colourは使用できないため、Hibernate でそのような HQL ステートメントを書くのに手探りしています。このような HQL ステートメントを書き込もうとしましたが、成功しませんでした。


[残りの部分で示されるコードは、レビューする必要がまったくない場合があります]

したがって、私は伝統的な方法に従っています。私がやっていることは...最初に、次のようProductな動的な値に基づいて、エンティティ クラスから単一の製品行を取得しています。prodId

List<Product>list=session.createQuery("from Product where prodId=:prodId")
                  .setParameter("prodId", prodId).list();

Colour次に、ループを使用して、セット全体を取得しています-この製品のエンティティで使用できるOraclejava.util.Setのテーブルに対応します。product_colourProduct

Set<Colour>colours=new HashSet<Colour>(0);

for(Product p:list)
{
    if(p!=null)
    {               
        colours=p.getColours();
    }
}

ご覧のとおり、Oracle のテーブルで使用可能colours Setなすべての色の行 (参照行) が取り込まれています。product_colour

これらの行をすべて取得した後、OracleColourのテーブルに対応するエンティティ クラス全体 (その中のすべての行) を取得し、 Oracle テーブルcolourから取得した行に一致する行を削除します (セットで利用可能)。前述のスニペット) など、前述の条件を満たします。product_colourcolours

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); 

質問は、この関係に関して、上記のネイティブ SQL ステートメントのように、エンティティ クラスから、 Oracle テーブルColourの色の行と一致しない行のみを取得できる HQL ステートメントを作成することは可能ですか?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 に答える