Java

MyBatisでWHERE句を動的に生成する方法

2022年7月27日

MyBatisでWHERE句を動的に生成する方法

WHERE句を静的に生成すると困るケース

例えば、MyBatisで次のような動的SQLを作成したとします。

<select id="search" resultType="com.example.demo.entity.UserInfo">
    SELECT
        *
    FROM
        userinfo
    WHERE
        <if test="id != null">
            id = #{id}
        </if>
        <if test="name != null">
            AND name = #{name}
        </if>
</select>

入力パラメータの「id」が必ず入力されるのであれば問題ありませんが、もし入力パラメータの「id」と「name」がnullの場合

SELECT * FROM userinfo WHERE

という不正なSQL文(WHERE句の後ろに何もない)が作られてしまい、エラーが発生します。

スポンサーリンク

また、入力パラメータの「id」がnullで「name」が入力された場合は

SELECT * FROM userinfo WHERE AND name = #{name}

という不正なSQL文(WHERE句の後にANDがある)が作られてしまい、こちらもエラーが発生します。

このような問題を解消するためにMyBatisではwhere要素が用意されており、where要素を使うことで、必要に応じてWHERE句を動的に生成できます。

「WHERE 1 = 1」の記述で解決することもできますが、where要素の方がおすすめです。

WHERE句を動的に生成する方法(where要素)

MyBatisのwhere要素は、内包するタグのどれかが結果を返すときだけ「WHERE句」を挿入します。更に、内包するタグから返された結果が「AND」または「OR」で始まっていた場合はこれを削除します。

<select id="search" resultType="com.example.demo.entity.UserInfo">
    SELECT
        *
    FROM
        userinfo
    <where>
        <if test="id != null">
            id = #{id}
        </if>
        <if test="name != null">
            AND name = #{name}
        </if>
     </where>
</select>

例えば上記のSQLで、入力パラメータの「id」と「name」がnullの場合

SELECT * FROM userinfo

というSQL文を生成します。(WHEREは必要ないので生成されない)

また、入力パラメータの「id」がnullで「name」が入力された場合は

SELECT * FROM userinfo WHERE name = #{name}

というSQL文を生成します。(WHEREの先頭にあった不要なANDを削除してくれる)

helpful