基本的にSQLが好きで、そのせいというわけではないのだが、仕事で開発しているフレームワークでは、O/RマッパーのベースとしてiBATISを使用している。いくつかのO/Rマッパーを試してみて、一番覚えるのが容易で、また柔軟性に富んでいて、Java、.NETの両方の開発者に対して広く薦められるプロダクトだと判断したためである。
若干の問題点として、IBATISは、Javaと.NETの間にバージョンの差異があることが上げられるのだが、先日、後発に当たるiBATIS.NETにおいて、以下のようにネストした条件判定タグを記述した場合にprepend属性がフラットに判定されるという仕様があることを発見した。
たとえば、少し強引な例だが、WHERE句に以下のようなタグの記述があるとする。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<dynamic prepend="WHERE"> <isNotEmpty prepend="AND" property="RoleId"> UR.ROLE_ID = #RoleId# </isNotEmpty> <isEqaul prepend="AND" property="UseJigyoubuCode" compareValue="y"> ( <isNotEmpty prepend="OR" property="JigyoubuCode"> MYJIG.JIGYOUBU_CODE = #JigyoubuCode# </isNotEmpty> <isNotEmpty prepend="OR" property="SubCode"> MYJIG.SUB_CODE = #SubCode# </isNotEmpty> ) </isEqaul> </dynamic> |
このSQLMapにおいて、UserJigyoubuCode == “y” で、かつ JigyoybyCodeとSubCodeが IsNotEmpty == true の場合、WHERE句の出力結果は以下の通りとなり、実行時にSQLシンタックスの誤りで例外がスローされる。
1 |
WHEREツ黴 ( OR MYJIG.JIGYOUBU_CODE = ? OR MYJIG.SUB_CODE = ?) |
.NET版のiBATISでは、このように、タグのprepend属性の出力はフラットに判定され、タグがネストしていた場合でも一つ前のタグ(この例で言うと、5行目のisEqualタグ)の状態によって判断される。
また、Java版のiBATISについては、以下のように、removeFirstPrepend=”true”を親のタグに記述することによって、ネストしたタグが先頭の場合にprepend属性の出力を抑制することが可能である。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<dynamic prepend="WHERE"> <isNotEmpty prepend="AND" property="RoleId"> UR.ROLE_ID = #RoleId# </isNotEmpty> <isEqaul prepend="AND" removeFirstPrepend="true" property="UseJigyoubuCode" compareValue="y"> ( <isNotEmpty prepend="OR" property="JigyoubuCode"> MYJIG.JIGYOUBU_CODE = #JigyoubuCode# </isNotEmpty> <isNotEmpty prepend="OR" property="SubCode"> MYJIG.SUB_CODE = #SubCode# </isNotEmpty> ) </isEqaul> </dynamic> |