同じテーブル関係がこの質問にも関係しているため、質問の 1 つから紹介テキストの一部をコピーして貼り付けています。
以下にリストされているように、Oracle(10g)データベースに多くのテーブルのうち3つがあります。Spring バージョン 3.0.2 で Hibernate Tools 3.2.1.GA を使用しています。
- 製品- 親テーブル
- 色- 親テーブル
- ProductColour -テーブルの結合 - 参照
colourId
とテーブルprodId
のそれぞれColour
Product
テーブルProductColour
は と の間の結合テーブルです。テーブル名が示すように、 と の間には多対多の関係があり、によってマッピングされます。これだけの情報で、データベースの関係性は容易に想像でき、明らかだと思います。したがって、この関係を不必要に詳しく調べるつもりはありません。Product
Colour
Product
Colour
PrductColour
のエンティティ (行)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_colour
Product
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_colour
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();
}
}
}
これは意図したことを実行できますが、そうすると、システムにいくらかのオーバーヘッドが生じる可能性があります。さらに、私が達成したいことは、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
それ以外の方法でページネーションの概念を実現するにはどうすればよいですか (場合によっては不可能です)。