Hibernate名前付きクエリ

1概要

HQLとSQLがデータアクセスオブジェクトに分散していることの大きな欠点は、コードが読めなくなることです。したがって、すべてのHQLとSQLを1か所にまとめて、実際のデータアクセスコードでそれらの参照だけを使用することは意味があります。幸いなことに、Hibernateでは名前付きクエリを使ってこれを行うことができます。

名前付きクエリは、定義済みの変更不可能なクエリ文字列を持つ静的に定義されたクエリです。これらはセッションファクトリが作成されたときに検証されるため、エラーが発生した場合にアプリケーションは迅速に失敗します。

  • この記事では、 @ NamedQuery および @ NamedNativeQuery アノテーションを使用してHibernate Named Queriesを定義および使用する方法について説明します。

2エンティティ

この記事で使用するエンティティを最初に見てみましょう。

@Entity
public class DeptEmployee {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private long id;

    private String employeeNumber;

    private String designation;

    private String name;

    @ManyToOne
    private Department department;

   //getters and setters
}

この例では、従業員番号に基づいて従業員を検索します。

3名前付きクエリ

これを名前付きクエリとして定義するには、 org.hibernate.annotations.NamedQuery アノテーションを使用します。 Hibernateの機能でjavax __。persistence.NamedQuery __を拡張します。

これを DeptEmployee クラスのアノテーションとして定義します。

@org.hibernate.annotations.NamedQuery(name = "DeptEmployee__findByEmployeeNumber",
  query = "from DeptEmployee where employeeNumber = :employeeNo")
  • すべての __ @ NamedQuery __アノテーションは、厳密に1つのエンティティクラスまたはマッピングされたスーパークラスに関連付けられていることに注意することが重要です。しかし、 名前付きクエリのスコープは永続化ユニット全体なので、衝突を避けるためにクエリ名を慎重に選択する必要があります。

エンティティに対して複数の名前付きクエリがある場合、これらをグループ化するために @ NamedQueries アノテーションを使用します。

@org.hibernate.annotations.NamedQueries({
    @org.hibernate.annotations.NamedQuery(name = "DeptEmployee__FindByEmployeeNumber",
      query = "from DeptEmployee where employeeNumber = :employeeNo"),
    @org.hibernate.annotations.NamedQuery(name = "DeptEmployee__FindAllByDesgination",
      query = "from DeptEmployee where designation = :designation"),
    @org.hibernate.annotations.NamedQuery(name = "DeptEmployee__UpdateEmployeeDepartment",
      query = "Update DeptEmployee set department = :newDepartment where employeeNumber = :employeeNo"),
...
})

HQLクエリはDMLスタイルの操作にすることができます。したがって、それは select ステートメントだけである必要はありません。たとえば、上記の DeptEmployee UpdateEmployeeDesignation__のように更新クエリを作成できます。

3.1. クエリ機能の設定

__ @ NamedQuery __アノテーションを使用してさまざまなクエリ機能を設定できます。

例を見てみましょう。

@org.hibernate.annotations.NamedQuery(
  name = "DeptEmployee__FindAllByDepartment",
  query = "from DeptEmployee where department = :department",
  timeout = 1,
  fetchSize = 10
)

ここでは、タイムアウト間隔とフェッチサイズを設定しました。これら二つから離れて、私達はまた次のような機能を設定することができます。

  • cacheable - クエリ(結果)がキャッシュ可能かどうか

  • cacheMode - このクエリに使用されるキャッシュモード。これはの1つである場合もあります

GET、IGNORE、NORMAL、PUT、 、または REFRESH ** cacheRegion - クエリ結果がキャッシュ可能な場合は、クエリに名前を付けます。

使用するキャッシュ領域 ** comment - 生成されたSQLクエリに追加されたコメント。のターゲット

DBA ** flushMode - このクエリのフラッシュモード、__ALWAYS、AUTO、

COMMIT、MANUAL、 、または PERSISTENCE CONTEXT

3.2. 名前付きクエリの使用

名前付きクエリを定義したので、それを使って従業員を取得しましょう。

Query<DeptEmployee> query = session.createNamedQuery("DeptEmployee__FindByEmployeeNumber",
  DeptEmployee.class);
query.setParameter("employeeNo", "001");
DeptEmployee result = query.getSingleResult();

ここでは、 createNamedQuery メソッドを使用しました。クエリの名前を取り、 __org.hibernate.query.Query __objectを返します。

4名前付きネイティブクエリ

HQLクエリと同様に、ネイティブSQLを名前付きクエリとして定義することもできます。

これを行うには、 @ NamedNativeQuery アノテーションを使用できます。これは @ NamedQuery と似ていますが、もう少し設定が必要です。

例を使ってこの注釈を調べてみましょう。

@org.hibernate.annotations.NamedNativeQueries(
    @org.hibernate.annotations.NamedNativeQuery(name = "DeptEmployee__GetEmployeeByName",
      query = "select **  from deptemployee emp where name=:name",
      resultClass = DeptEmployee.class)
)
  • これはネイティブのクエリなので、結果をマッピングするエンティティクラスをHibernateに指示する必要があります。そのため、これを行うために __resultClass __propertyを使用しました。

  • 結果をマッピングする別の方法は _resultSetMapping propertyを使うことです。ここで、定義済みの SQLResultSetMapping _ 。** の名前を指定できます。

resultClass resultSetMapping のどちらか一方しか使用できないことに注意してください。

4.1. 名前付きネイティブクエリの使用

名前付きネイティブクエリを使用するには、 Session.createNamedQuery() を使用できます。

Query<DeptEmployee> query = session.createNamedQuery("DeptEmployee__FindByEmployeeName", DeptEmployee.class);
query.setParameter("name", "John Wayne");
DeptEmployee result = query.getSingleResult();

または Session.getNamedNativeQuery() :

NativeQuery query = session.getNamedNativeQuery("DeptEmployee__FindByEmployeeName");
query.setParameter("name", "John Wayne");
DeptEmployee result = (DeptEmployee) query.getSingleResult();

これら2つの方法の唯一の違いは戻り型です。 2番目のアプローチは、 Queryのサブクラスである __NativeQueryを返します。

5ストアドプロシージャと関数

@ NamedNativeQuery アノテーションを使用して、ストアドプロシージャと関数への呼び出しを定義することもできます。

@org.hibernate.annotations.NamedNativeQuery(
  name = "DeptEmployee__UpdateEmployeeDesignation",
  query = "call UPDATE__EMPLOYEE__DESIGNATION(:employeeNumber, :newDesignation)",
  resultClass = DeptEmployee.class)

これは更新クエリですが、 __resultClass propertyを使用しています。これは、Hibernateが純粋なネイティブスカラークエリをサポートしていないためです。そして問題を回避する方法は resultClassまたは resultSetMappingを設定することです。

6. 結論

この記事では、名前付きHQLとネイティブクエリを定義して使用する方法を説明しました。

ソースコードはhttps://github.com/eugenp/tutorials/tree/master/persistence-modules/hibernate5[GitHubで利用可能]です。