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プロジェクト]で確認できます。