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で利用可能]です。