石丸です。
MyBatisで連番のカラム名を持つテーブルに対してのUPDATE文を書く際に知ったテクニックを紹介します。

  • 連番のカラム名を動的に生成
  • if で N より小さいと記述(== か != しかかけないと思っていた)
  • パラメータとして渡されたオブジェクトのメソッドを呼ぶ

MyBatisのバージョンは3.4(SpringBootプロジェクトでmybatis-spring-boot-starter:1.3.1)になります。

対象のテーブル

話を簡単にするため極限までカラム数を減らしていますが、正規化されていないし、COLUMN_Bは1、2しか存在しないし、COLUMN_AとCOLUMN_Bでは連番のフォーマットが違うという3重苦です。

ID COLUMN_A01 COLUMN_B1 COLUMN_A02 COLUMN_B2 COLUMN_A03
1 1-A01 1-B1 1-A02 1-B2 1-A03
2 2-A01 2-B1 2-A02 2-B2 2-A03
3 3-A01 3-B1 3-A02 3-B2 3-A03

mapper

mapper.javaはこんな感じ

テーブルは正規化されていませんが、それでは扱いにくいのでプログラム上ではCOLUMN_AとCOLUMN_Bをフィールドに持つRowクラスのArrayListにしています。
mapper.xmlは次のようになりました。

まず連番のカラム名生成ですが、collectionを回すforeachのindexを利用します。
COLUMN_Bは0から始まるindex+1を末尾にくっつけるだけなので7行目のようになります。
COLUMN_B${index+1}COLUMN_B1 になります。

COLUMN_Aの0埋めされた2桁の連番の生成にはformatterを用意しました。
4行目のbind要素でformatter.formatIndex(index)を実行し、suffix変数に格納します。

bind 要素を使うと、OGNL 式の結果を変数に格納し、その変数を SQL 文中で使用することができます。
http://www.mybatis.org/mybatis-3/ja/dynamic-sql.html#bind

これで COLUMN_A${suffix}COLUMN_A01 になります。

最後にif要素ですが index < 2 と書くとエラーになります。
これは index lt 2 と書くことでうまくいきます。
Mybatis Dynamic SQL StatementにOGNL式で使える演算子の一覧がありました。

TOP
TOP