Hibernateを使ったストアドプロシージャ

1概要

ストアドプロシージャは、データベース内に存在するコンパイル済みのSQL文のセットです。

この記事では、 Hibernate を使用して MySQLデータベース 内の ストアドプロシージャ を呼び出す方法を説明します。

2 MySQL のストアドプロシージャ

Hibernateからストアドプロシージャを呼び出す方法を説明する前に、それを作成する必要があります。

この簡単なMySQLの例では、 foo からすべてのレコードを取得するためにhttp://dev.mysql.com/doc/refman/5.7/en/create-procedure.html[ストアドプロシージャを作成します]表。

ストアドプロシージャを作成するために、 CREATE PROCEDURE ステートメントを使用します。

DELIMITER//    CREATE PROCEDURE GetAllFoos()
        LANGUAGE SQL
        DETERMINISTIC
        SQL SECURITY DEFINER
        BEGIN
            SELECT **  FROM foo;
        END//DELIMITER;

BEGIN ステートメントの前に、オプションのステートメントを定義できます。公式のhttp://dev.mysql.com/doc/refman/5.7/en/create-procedure.html[MySQLのドキュメント]リンクをたどると、これらのステートメントの詳細にドリルダウンできます。

CALL ステートメントを使用して、プロシージャが希望どおりに動作することを確認できます。

CALL GetAllFoos();

ストアドプロシージャを起動して実行したので、Hibernateから呼び出す方法に直接進みましょう。

3 Hibernate でストアドプロシージャを呼び出す

Hibernate 3から始めて、ストアドプロシージャを含む生のSQLステートメントを使用してデータベースに問い合わせることができます。

このセクションでは、Hibernateを使って GetAllFoos() プロシージャを呼び出す方法を説明する基本的な例を見ていきます。

3.1. 構成

実行できるコードを書き始める前に、Hibernateをプロジェクトに設定しておく必要があります。

もちろん、Mavenの依存関係、MySQLの設定、Hibernateの設定、 SessionFactory のインスタンス化など、すべてのことについては、リンク:/hibernate-4-spring[Hibernateの記事]を参照してください。

3.2. CreateNativeSQL メソッドを使用してストアドプロシージャを呼び出す

Hibernateは直接 ネイティブSQL フォーマットでクエリを表現することを可能にします。

したがって、ネイティブSQLクエリを簡単に作成し、 CALL ステートメントを使用して getAllFoos() ストアドプロシージャを呼び出すことができます。

Query query = session.createSQLQuery("CALL GetAllFoos()").addEntity(Foo.class);
List<Foo> allFoos = query.list();

上記のクエリは、各要素が __Foo o __bjectであるリストを返します。

ネイティブの SQL クエリからエンティティオブジェクトを取得するには addEntity() メソッドを使います。

3.3. @ NamedNativeQueries を使用してストアドプロシージャを呼び出す

ストアドプロシージャを呼び出す別の方法は、 @ NamedNativeQueries アノテーションを使用することです。

  • @ NamedNativeQueries は、永続ユニットを対象とするネイティブSQL 名前付きクエリ の配列を指定するために使用されます。

@NamedNativeQueries({
  @NamedNativeQuery(
    name = "callGetAllFoos",
    query = "CALL GetAllFoos()",
    resultClass = Foo.class)
})
@Entity
public class Foo implements Serializable {
   //Model definition
}

それぞれの名前付きクエリは明らかに name 属性、実際の SQLクエリ 、そして Foo マッピングエンティティを参照する resultClass を持ちます。

Query query = session.getNamedQuery("callGetAllFoos");
List<Foo> allFoos = query.list();

resultClass 属性は、前の例の addEntity() メソッドと同じ役割を果たします。

パフォーマンスまたは生産性に関しては両者の間に実質的な違いはないため、これらのアプローチはどちらも互換的に使用できます。

3.4. @ NamedStoredProcedureQuery を使用してストアドプロシージャを呼び出す

  • JPA 2.1 および Hibernate 実装の EntityManagerFactory および EntityManager ** を使用している場合。

  • @ NamedStoredProcedureQuery ** アノテーションを使用してストアドプロシージャを宣言できます。

@NamedStoredProcedureQuery(
  name="GetAllFoos",
  procedureName="GetAllFoos",
  resultClasses = { Foo.class }
)
@Entity
public class Foo implements Serializable {
   //Model Definition
}

名前付きストアドプロシージャクエリを呼び出すには、 EntityManager、 をインスタンス化し、次に createNamedStoredProcedureQuery() メソッドを呼び出してプロシージャを作成する必要があります。 :

StoredProcedureQuery spQuery =
  entityManager.createNamedStoredProcedureQuery("getAllFoos");

StoredProcedureQuery オブジェクトの execute() メソッドを呼び出すことで、 Foo エンティティのリストを直接取得できます。

4パラメータを持つストアドプロシージャ

ほとんどすべてのストアドプロシージャはパラメータを必要とします。このセクションでは、 Hibernate のパラメータを使ってストアドプロシージャを呼び出す方法を説明します。

  • MySQL ** に getFoosByName() ストアドプロシージャを作成しましょう。

このプロシージャは、name属性が fooName パラメータと一致する Foo オブジェクトのリストを返します。

DELIMITER//    CREATE PROCEDURE GetFoosByName(IN fooName VARCHAR(255))
        LANGUAGE SQL
        DETERMINISTIC
        SQL SECURITY DEFINER
        BEGIN
            SELECT **  FROM foo WHERE name = fooName;
        END//DELIMITER;

GetFoosByName() プロシージャを呼び出すには、名前付きパラメータを使用します。

Query query = session.createSQLQuery("CALL GetFoosByName(:fooName)")
  .addEntity(Foo.class)
  .setParameter("fooName","New Foo");

同様に、名前付きパラメーター :fooName は、 @ NamedNativeQuery アノテーションと共に使用できます。

@NamedNativeQuery(
  name = "callGetFoosByName",
  query = "CALL GetFoosByName(:fooName)",
  resultClass = Foo.class
)

名前付きクエリは次のように呼び出されます。

Query query = session.getNamedQuery("callGetFoosByName")
  .setParameter("fooName","New Foo");
  • @ NamedStoredProcedureQuery アノテーションを使用するときは、 @ StoredProcedureParameter アノテーション** を使用してパラメーターを指定できます。

@NamedStoredProcedureQuery(
  name="GetFoosByName",
  procedureName="GetFoosByName",
  resultClasses = { Foo.class },
  parameters={
    @StoredProcedureParameter(name="fooName", type=String.class, mode=ParameterMode.IN)
  }
)

fooName パラメーターを指定してストアード・プロシージャーを呼び出すために、 registerStoredProcedureParameter() メソッドを使用することができます。

StoredProcedureQuery spQuery = entityManager.
  createNamedStoredProcedureQuery("GetFoosByName")
  .registerStoredProcedureParameter(
    "New Foo",
    String.class ,
    ParameterMode.IN
  );

5結論

この記事では、 Hibernateを使用してMySQLデータベース内のストアドプロシージャを呼び出す方法 さまざまな方法を説明しました。

  • すべてのRDBMSがストアドプロシージャをサポートしているわけではない** ことを言及する価値があります。

この記事で提供されている例は、リンクされたhttps://github.com/eugenp/tutorials/tree/master/persistence-modules/spring-hibernate4[GitHubプロジェクト]で確認できます。