MyBatisの動的SQLについて
こんにちわ。
NOBORIの村越です。
今回は、最近勉強し始めたMyBatisの動的SQLについて書こうと思います。
MyBatisとは何か
XMLを使って、SQL文とオブジェクトをマッピングするフレームワークです。
パラメータを渡し、動的にSQLを発行することが出来ます。
詳しくはこちらを参照ください。
if
<select id="select">
select
*
from
sample_table
where
name = #{name, jdbcType=VARCHAR}
<if test="age != null">
and age = #{age, jdbcType=VARCHAR}
</if>
</select>
条件を満たす場合、特定の処理を行いたい場合は、if文を使用します。
パラメータの age が存在する場合は、name と age を、
存在しない場合は name のみを条件として取得するSQLとなります。
choose
<select id="select">
select
*
from
sample_table
where
<choose>
<when test="number != null">
number = #{number, jdbcType=VARCHAR}
</when>
<when test="name != null">
name = #{name, jdbcType=VARCHAR}
</when>
<otherwise>
age = #{age, jdbcType=VARCHAR}
</otherwise>
</choose>
</select>
条件のうち、どれか一つの処理のみを行いたい場合、choose文を使用します。
パラメータの number が存在する場合は number を、
number が存在せず、name が存在する場合は name を、
どちらも存在しない場合は age を条件として取得するSQLとなります。
where
上で紹介した if 文を使用して、以下のようなパラメータ number、name、age のうち存在するもの全てを条件として取得を行うSQLを書いたとします
<select id="select">
select
*
from
sample_table
where
<if test="number != null">
number = #{number, jdbcType=VARCHAR}
</if>
<if test="name != null">
and name = #{name, jdbcType=VARCHAR}
</if>
<if test="age != null">
and age = #{age, jdbcType=VARCHAR}
</if>
</select>
上記の例の場合、すべての条件が存在しない場合、
select * from sample_table where
というSQLになり、構文エラーとなってしまいます。
また、number が存在せず、name が存在する場合、
select * from sample_table where and name = #{name, jdbcType=VARCHAR}
というSQLになり、こちらも構文エラーになります。
上記のような場合には、where文を使用するといいです。
<select id="select">
select
*
from
sample_table
<where>
<if test="number != null">
number = #{number, jdbcType=VARCHAR}
</if>
<if test="name != null">
and name = #{name, jdbcType=VARCHAR}
</if>
<if test="age != null">
and age = #{age, jdbcType=VARCHAR}
</if>
</where>
</select>
条件のうち、どれか一つでも満たした場合は、whereを挿入し、
where句の最初が and、or で始まってしまうSQL文になる場合は、不要な and、or を削除してくれます。
例えば、name と age が存在する場合は
select * from sample_table where name = #{name, jdbcType=VARCHAR} and age = #{age, jdbcType=VARCHAR}
といったSQLになります。
set
<update id="update">
update
sample_table
<set>
<if test="name != null">
name = #{name, jdbcType=VARCHAR},
</if>
<if test="age != null">
age = #{age, jdbcType=VARCHAR}
</if>
</set>
where
number = #{number, jdbcType=VARCHAR}
</update>
where文の set 版になります。
条件を一つでも満たす場合は set を挿入し、set句の最後が , で終わる場合は , を削除してくれます。
trim
<select id="select">
select
*
from
sample_table
<trim prefix="WHERE" prefixOverrides="AND |OR ">
<if test="number != null">
number = #{number, jdbcType=VARCHAR}
</if>
<if test="name != null">
and name = #{name, jdbcType=VARCHAR}
</if>
<if test="age != null">
and age = #{age, jdbcType=VARCHAR}
</if>
</trim>
</select>
上記の where、set を自分で定義することができるのが trim文です。
上記の where の例を trimで書き換えたものになります。
prefix、suffix で、条件を一つでも満たした場合に先頭、末尾に付与する文字を、prefixOverrides、suffixOverrides で、先頭、末尾の削除する文字を指定できます。
foreach
<select id="select">
select
*
from
sample_table
where
number in
<foreach item="item" collection="numberList" open="(" separator="," close=")">
#{item, jdbcType=VARCHAR}
</foreach>
</select>
配列の要素を条件に指定したい場合は、foreach文を使用します。
collection で指定された配列の要素を separator で区切り、open、closeを最初と最後に付与します。
上記の例では、以下のようなSQLとなります。
select * from sample_table where number in (aaa, bbb, ccc)
include、sql
<sql id="selectAll">
select
*
from
sample_table
</sql>
<select id="selectName">
<include refid="selectAll" />
where
name = #{name, jdbcType=VARCHAR}
</select>
<select id="selectNumber">
<include refid="selectAll" />
where
number = #{number, jdbcType=VARCHAR}
</select>
sql で定義したSQLを、include で呼び出すことが出来ます。
上記の例では、selectName、selectNumberは、それぞれ name、number を指定して sample_table からデータを取得するSQLになります。
select * from sample_table の部分を include を使用して省略しています。
よく使用するSQLを定義しておけば、何度も同じSQLを書く必要がなくなります。
最後に
Mybatisの動的SQLについてまとめてみましたが、いかがだったでしょうか?
動的SQLはとても便利で、使えると記載がすごく楽になります。
今回紹介した動的SQL以外にもMybatisには便利な機能があるので、機会があればまとめてみようかと思います。
今回は以上となります。
今後とも「NOBORI」をよろしくお願い致します。
村越