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