Hibernate Criteriaの例
Hibernate Criteria APIは、Hibernate Query Language(HQL)のよりオブジェクト指向でエレガントな代替です。 これは、多くのオプションの検索条件を持つアプリケーションに対する常に優れたソリューションです。
HQLと基準の例
これは、StockDailyRecordのリストを取得するケーススタディであり、オプションの検索条件(開始日、終了日とボリューム、日付順)があります。
1. HQLの例
HQLでは、これが「where」構文を追加する最初の基準であるかどうかを比較し、日付を適切な形式にフォーマットする必要があります。 動作しますが、長いコードは見苦しく、扱いにくく、エラーが発生しやすい文字列の連結により、SQLインジェクションなどのセキュリティ上の懸念が生じる可能性があります。
public static List getStockDailtRecord(Date startDate,Date endDate, Long volume,Session session){ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); boolean isFirst = true; StringBuilder query = new StringBuilder("from StockDailyRecord "); if(startDate!=null){ if(isFirst){ query.append(" where date >= '" + sdf.format(startDate) + "'"); }else{ query.append(" and date >= '" + sdf.format(startDate) + "'"); } isFirst = false; } if(endDate!=null){ if(isFirst){ query.append(" where date <= '" + sdf.format(endDate) + "'"); }else{ query.append(" and date <= '" + sdf.format(endDate) + "'"); } isFirst = false; } if(volume!=null){ if(isFirst){ query.append(" where volume >= " + volume); }else{ query.append(" and volume >= " + volume); } isFirst = false; } query.append(" order by date"); Query result = session.createQuery(query.toString()); return result.list(); }
2. 基準の例
Criteriaでは、これが「where」構文を追加する最初の基準であるかどうかを比較したり、日付をフォーマットしたりする必要はありません。 コードの行が減り、すべてがよりエレガントでオブジェクト指向の方法で処理されます。
public static List getStockDailyRecordCriteria(Date startDate,Date endDate, Long volume,Session session){ Criteria criteria = session.createCriteria(StockDailyRecord.class); if(startDate!=null){ criteria.add(Expression.ge("date",startDate)); } if(endDate!=null){ criteria.add(Expression.le("date",endDate)); } if(volume!=null){ criteria.add(Expression.ge("volume",volume)); } criteria.addOrder(Order.asc("date")); return criteria.list(); }
基準API
一般的なCriteria API関数をいくつか見てみましょう。
1. 基準基本クエリ
基準オブジェクトを作成し、データベースからすべての「StockDailyRecord」レコードを取得します。
Criteria criteria = session.createCriteria(StockDailyRecord.class);
2. 基準注文クエリ
結果は、「日付」で昇順に並べ替えられます。
Criteria criteria = session.createCriteria(StockDailyRecord.class) .addOrder( Order.asc("date") );
結果は「日付」で降順でソートされます。
Criteria criteria = session.createCriteria(StockDailyRecord.class) .addOrder( Order.desc("date") );
3. 基準制限クエリ
Restrictionsクラスには、比較操作を行うための多くのメソッドが用意されています。
Restrictions.eq
ボリュームが10000に等しいことを確認します。
Criteria criteria = session.createCriteria(StockDailyRecord.class) .add(Restrictions.eq("volume", 10000));
Restrictions.lt, le, gt, ge
音量が10000未満であることを確認してください。
Criteria criteria = session.createCriteria(StockDailyRecord.class) .add(Restrictions.lt("volume", 10000));
音量が10000以下であることを確認してください。
Criteria criteria = session.createCriteria(StockDailyRecord.class) .add(Restrictions.le("volume", 10000));
音量が10000より大きいことを確認してください。
Criteria criteria = session.createCriteria(StockDailyRecord.class) .add(Restrictions.gt("volume", 10000));
音量が10000以上であることを確認してください。
Criteria criteria = session.createCriteria(StockDailyRecord.class) .add(Restrictions.ge("volume", 10000));
Restrictions.like
銘柄名が「MKYONG」で始まり、任意の文字が続くことを確認してください。
Criteria criteria = session.createCriteria(StockDailyRecord.class) .add(Restrictions.like("stockName", "MKYONG%"));
Restrictions.between
日付が開始日と終了日の間にあることを確認してください。
Criteria criteria = session.createCriteria(StockDailyRecord.class) .add(Restrictions.between("date", startDate, endDate));
Restrictions.isNull, isNotNull
ボリュームがヌルであることを確認してください。
Criteria criteria = session.createCriteria(StockDailyRecord.class) .add(Restrictions.isNull("volume"));
ボリュームがnullでないことを確認してください。
Criteria criteria = session.createCriteria(StockDailyRecord.class) .add(Restrictions.isNotNull("volume"));
3. 結果のページング基準
基準には、ページネーションを非常に簡単にするための機能がほとんどありません。 20番目のレコードから開始し、データベースから次の10レコードを取得します。
Criteria criteria = session.createCriteria(StockDailyRecord.class); criteria.setMaxResults(10); criteria.setFirstResult(20);
なぜ基準はありませんか!?
Criteria APIにはいくつかの欠点があります。
1. パフォーマンスの問題
Hibernateによって生成されたSQLクエリを制御する方法はありません。生成されたクエリが遅い場合、クエリの調整が非常に難しく、データベース管理者はそれを気に入らないかもしれません。
1. メンテナンスの問題
すべてのSQLクエリはJavaコードに散在しています。クエリが失敗した場合、アプリケーションで問題のあるクエリを見つけるために時間を費やす可能性があります。 一方、Hibernateマッピングファイルに保存されている名前付きクエリは、メンテナンスがはるかに簡単です。
結論
完璧なものは何もありません。プロジェクトのニーズを考慮し、賢明に使用してください。