Ebean はモデル一体型のORMフレームワーク。
DBの型をクラスに落としこんでなんぼの仕組みです。
ORマッパーってなんじゃらほい?というところはまだ理解できてませんけどね。
ここはそのうち追々‥‥
Ebean を使ってると、クラスとDBをマッチングさせるだけで、
SQLを書く必要もほとんどなくなっちゃいます。便利です。
Play Framework と Ebean についての解説は@ITのこの記事が分かりよいです。
でも、時には直接SQLを発行してみたいときもありますよね。
ストアドプロシージャをコールしたいな~と思ったりだとか。
そういう時は、Ebeanのexecuteメソッドを使います
static int Ebean.execute(CallableSql callableSql)
CallableSqlはプリペアドステートメントを提供するインタフェースです。
実際の簡単な使い方はこんな感じ。
1 2 3 4 5 6 |
String strSql = "EXEC StoredProcedure_1 ?,?;"; CallableSql callSql = Ebean.createCallableSql(strSql); callSql.setParameter(1, 2013); callSql.setParameter(2, "Ebean経由でプロシージャ呼び出し"); Ebean.execute(callSql); |
簡単。
SqlQueryインタフェースと違って、パラメータに名前ラベルを使えないっぽいところが玉に瑕?
さっそく実行すると・・・あれ?プロシージャ実行されない。
executeメソッドの戻り値には “-1” が返ってきます。
“-1” ってなんだっけ・・・うーん?
探っていると、execute(SqlUpdate sqlUpdate)メソッドに記述がありました。
Returns:
the number of rows updated or deleted. -1 if executed in batch.
なんだ、じゃあちゃんと実行されてるんじゃない。
じゃなんでDB側に反映されてないんだろ?
イロイロ調べるうちに、上の書き方が悪いのかプロシージャの書き方が悪いのか、
executeをコールするだけだと、プロシージャの処理が完了していないっぽい様子。
うーん‥‥どうすりゃいいっていうんよ。
詳細わかんないですが、ここらへんを参考に、
トランザクションで括って、commitを多めに発行してみましたー。どうかな?
1 2 3 4 5 6 7 8 9 10 11 |
Ebean.beginTransaction(); String strSql = "EXEC StoredProcedure_1 ?,?;"; CallableSql callSql = Ebean.createCallableSql(strSql); callSql.setParameter(1, 2013); callSql.setParameter(2, "Ebean経由でプロシージャ呼び出し"); Ebean.execute(callSql); Ebean.execute(Ebean.createCallableSql("commit;")); Ebean.commitTransaction(); |
実行実行‥‥動いたー!
最後2度commitしてることになりますけど、これでちゃんと動いてくれたからまあいっか。
ちなみに、今回のお相手のDBはSqlServer2008Expressです。
なので、プロシージャの呼び出しもSQLServer風味。
Oracleだと “{ call StoredProcedure_1(?,?) }” みたいになるんでしょうか?
Oracle詳しくないからなー。
ブラケットは自動的にBEGINとCOMMITに置き換えられるそうな。
でも、ブラケットとの間にスペースを空けないと、ちゃんと動かないよー!
みたいな議論がここらへんにあったので一応メモっておきましょうか‥‥
2度COMMITが必要な問題、やっと理由と解決方法がわかったので記事書きました。ご参考にどうぞ。
http://qiita.com/yuba/items/6ee4f074af4ee2975b64