Hibernateでクエリを使用してエンティティをマップする
-
05-07-2019 - |
質問
表を考慮する
sales (id, seller_id, amount, date)
これは、クエリ SELECT Seller_id、SUM(amount)FROM sales GROUP BY Seller_id
sales
から生成されたビューです
total_sales (seller_id, amount)
総売上高のエンティティを作成したいが、SQL側のビューはありません。
このエンティティはクエリから構築されます。私が見つけた最も近いものは this 、しかしそれを機能させることができませんでした。
ローダーを定義しても、Hibernateはエンティティのテーブルを探し、見つからない場合はエラーを返します。テーブルを作成すると、定義した名前付きクエリからエンティティをロードしません。Hibernateはクエリ自体を生成します。
@Loaderを機能させる方法はありますか、またはクエリをエンティティにマッピングする別の方法はありますか?
解決
クエリで new
を使用しないのはなぜですか?
select new TotalSales(seller_id, count(seller_id))
from sales
group by seller_id
seller_idと整数を取るコンストラクターでクラスTotalSalesを記述するだけです。
編集:基準APIを使用する場合、 AliasToBeanResultTransformer
を使用できます( APIドキュメント)。すべてのエイリアス名を同じ名前のプロパティにコピーします。
List list = s.createCriteria(Sales.class)
.setProjection(Projections.projectionList()
.add( Projections.property("id"), "SellerId" )
.add( Projections.rowCount("id"), "Count" ) )
.setResultTransformer(
new AliasToBeanResultTransformer(TotalSales.class) )
.list();
TotalSales
には、 SellerId
および Count
プロパティが必要です。
他のヒント
Stefanの答えに加えて、明示的なHQLクエリを使用して
SELECT seller_id, SUM(amount) FROM sales GROUP BY seller_id
結果は自然にリストに保存されます。このデータ型が都合が悪い場合は、 あなたができる:
- それらを使用して新しいTotalSaleオブジェクトを作成します(おそらくStefanの答えを使用した方が良いでしょう)
- データを保存するマップを作成します(これをリクエストに直接埋め込むこともできます)。
カスタマイズされたローダーを定義することができます。私はこれを使用したことはありませんが、合理的であるようです:
<sql-query name="totalSale">
<return alias="ts" class="TotalSale" />
SELECT seller_id as {ts.seller_id}, SUM(amount) as ts.amount
FROM sales
WHERE seller_id = ?
GROUP BY seller_id
</sql-query>
seller_idのフィルターが必要かどうかわからない。
クラスマッピングでこの名前付きクエリを参照します:
<class name="TotalSale">
<id name="seller_id">
<generator class="increment"/>
</id>
<property name="seller_id" />
<property name="amount" />
<loader query-ref="totalSale"/>
</class>
別の方法として、コードから名前クエリを直接使用できます。これにより、TotalSaleのマッピングが不要になり、コードにクエリを記述する必要がなくなります。名前付きクエリはオブジェクトを返すこともできます。 名前付きクエリの詳細ドキュメント内。
このジョブにのみ特定のエンティティが本当に必要な場合は、カスタムプロパティで「式」を使用できます
<class name="SellerSales" table="Sales" lazy="true">
<id name="SellerId" column="SellerId" type="int">
<generator class="native" />
</id>
<property name="SalesSum" type="float" update="false" insert="false"
formula="select SUM(sal.ammount) from sales sal where sal.seller_id = SellerId)" />
</class>
public class SellerSales
{
public int SellerId {get; set;}
public float SalesSum {get; set;}
}
このように、注文エンジンや制限などの基準エンジンにアクセスできるため、それを使用したい理由だと思います。