MyBatis でパラメータが null 以外の時にカラムを更新する

備忘録。MyBatis における UPDATE 文のパラメータの扱い方について。

やりたいこと

MyBatis を使って Java のオブジェクトの値を元に UPDATE 文を発行する。以下のような単純な例を考える。

CREATE TABLE parson (
  id INTEGER NOT NULL PRIMARY KEY,
  name TEXT,
  age INTEGER
);
package com.example;

public class Person {
  int id;
  public String name;
  public Integer age;
}
<update id="updateParson" parameterType="com.example.Person">
  UPDATE parson SET
    name = #{name},
    age = #{age}
  WHERE id = #{id}
</update>

ただし updateParson は渡された nameagenull だった場合は更新しないようにしたい。(上記だと null が設定されてしまう)

解決案1

MyBatis の choose/otherwise を使う。

<update id="updateParson" parameterType="com.example.Person">
  UPDATE parson SET
    <choose>
      <when test="name != null">
        name = #{name},
      </when>
      <otherwise>
        name = name,
      </otherwise>
    </choose>
    <choose>
      <when test="age != null">
        age = #{age},
      </when>
      <otherwise>
        age = age,
      </otherwise>
    </choose>
  WHERE id = #{id}
</update>

解決案2

MySQLCOALESCE を使う。

<update id="updateParson" parameterType="com.example.Person">
  UPDATE parson SET
    name = COALESCE(#{name}, name),
    age = COALESCE(#{age}, age)
  WHERE id = #{id}
</update>

COALESCE は引数リストの中で最初に見つかった非 NULL 値を、全部 NULL なら NULL を返す。