SpringアプリケーションにおいてMybatisを使用する状況を想定した実装例です。
期待値
IN句に複数のパラメータが設定されたSQL文が発行されること
1 2 3 |
SELECT * FROM tbl WHERE column in ( ? , ? , ? , ? ) |
前提
■アプリケーション構成
・org.springframework.boot 2.6.4
・spring-boot-starter-web
・mybatis-spring-boot-starter 2.2.2
■テーブル構成
Ticketテーブルに対して支払区分(payment_code)をIN句で指定する状況を想定しています。
実装例
Repositoryで指定する引数の型または指定方法によって、XMLのcollectionに指定する値が異なります。
以下にそれぞれのパターンを記載しました。
@Paramによる指定
Repository
1 2 3 |
List<Ticket> selectManyByParam(@Param("paymentCodesParam") List<String> paymentCodes); |
XML
@Paramで指定した名称とcollectionの値を一致させます。
1 2 3 4 5 6 7 8 9 10 11 12 |
<select id="selectManyByParam" resultMap="ticket"> SELECT * FROM Ticket WHERE 0 = 0 <foreach item="paymentCodes" collection="paymentCodesParam" nullable="true" open="AND payment_code in (" separator="," close=")" > #{paymentCodes} </foreach> </select> |
Arrayによる指定
Repository
1 2 3 |
List<Ticket> selectManyByArray(String[] arrayPaymentCodes); |
XML
配列の場合、collectionには「array」を指定します。
1 2 3 4 5 6 7 8 9 10 11 12 |
<select id="selectManyByArray" resultMap="ticket"> SELECT * FROM Ticket WHERE 0 = 0 <foreach item="paymentCodes" collection="array" nullable="true" open="AND payment_code in (" separator="," close=")" > #{paymentCodes} </foreach> </select> |
Collection型による指定(ex. List)
ここではListを例に記載します。
Repository
1 2 3 |
List<Ticket> selectManyByPayments(List<String> paymentCodes); |
XML
1 2 3 4 5 6 7 8 9 10 11 12 |
<select id="selectManyByPayments" resultMap="ticket"> SELECT * FROM Ticket WHERE 0 = 0 <foreach item="paymentCodes" collection="list" nullable="true" open="AND payment_code in (" separator="," close=")" > #{paymentCodes} </foreach> </select> |
オブジェクトによる指定
検索フォームオブジェクトを検索パラメータとして扱う状況で説明します。
(氏名、誕生日はTicketテーブルにはありません。
検索フォームをパラメータとして渡す例として支払区分以外を持たせるためのダミーです)
Form
1 2 3 4 5 6 7 8 |
@Data // lombok public class SearchForm { private String name; private String birthdayFrom; private String birthdayTo; private List<String> paymentCodes; // @DataによりGetter/Setterは実装済 } |
Repository
検索フォームオブジェクトをパラメータとして渡した場合
1 2 3 |
List<Ticket> selectManyByForm(SearchForm form); |
XML
collectionには、Repositoryで指定されたFormのフィールドである「paymentCodes」を指定します。
その際、paymentCodesのGetterを用意しておいてください。
本記事では、lombokの@Dataを使うことでGetter/Setterを実装しています。
1 2 3 4 5 6 7 8 9 10 11 12 |
<select id="selectManyByForm" resultMap="ticket"> SELECT * FROM Ticket WHERE 0 = 0 <foreach item="paymentCodes" collection="paymentCodes" nullable="true" open="AND payment_code in (" separator="," close=")" > #{paymentCodes} </foreach> </select> |
補足
XMLのnullableはcollectionとして渡すフィールドの値がNULLを許容するかの指定です。
falseを指定してNULL値を渡すと、MyBatisSystemExceptionが発生します。
1 2 3 |
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.builder.BuilderException: The expression 'paymentCodes' evaluated to a null value. |
まとめ
-
IN句に設定する方法は以下の通りです。
- @Paramで名称を指定する
- 配列はcollection=arrayと指定する
- Listはcollection=listと指定する
- パラメータとして渡したオブジェクトのフィールドを指定したい場合、collection=[対象のフィールド]と指定する
参考情報
MyBatis – 動的SQL – foreach
https://mybatis.org/mybatis-3/ja/dynamic-sql.html
コメント