MyBatis ThymeleafのSQL生成機能であるSQL GeneratorはMyBatisとは独立して使用できる。基本的には他のO\Rマッパーと共に使用する。今回はmybatis-thymeleaf
単体で使用可能な事を示すためにあえて他の依存性は何も追加せずにSQL生成のみ試す。
ソースコードなど
build.gradle
plugins { id 'java' } group = 'com.example' version = '0.0.1-SNAPSHOT' sourceCompatibility = '17' repositories { mavenCentral() } dependencies { implementation 'org.mybatis.scripting:mybatis-thymeleaf:1.0.4' }
使ってみる
import java.util.Map; import org.mybatis.scripting.thymeleaf.SqlGenerator; public class SqlGeneratorSample1 { public static void main(String[] args) { SqlGenerator sqlGenerator = new SqlGenerator(); Map<String, Object> params = Map.of("id", 100); String sql = sqlGenerator.generate(""" select id , username from my_users where id = /*[# mb:p="id"]*/ 1 /*[/]*/ """, params); System.out.println(sql); } }
出力結果は以下になる。
select id , username from my_users where id = #{id}
プレースホルダの形式をMyBatisから変更
デフォルト設定だとプレースホルダの形式はMyBatisの#{xxx}
なので、これをJdbcTemplateなどで使われる:xxx
に変更する。
import org.mybatis.scripting.thymeleaf.SqlGenerator; import org.mybatis.scripting.thymeleaf.SqlGeneratorConfig; import org.mybatis.scripting.thymeleaf.processor.BindVariableRender; SqlGeneratorConfig config = SqlGeneratorConfig.newInstanceWithCustomizer(c -> c.getDialect() .setBindVariableRenderInstance(BindVariableRender.BuiltIn.SPRING_NAMED_PARAMETER)); SqlGenerator sqlGenerator = new SqlGenerator(config);
出力結果は以下になる。
(略)
where
id = :id
カスタム変数
パラメータとは別にカスタム変数としてSQL生成時に使用する値を渡せる。カスタム変数は二種類ありSqlGenerator
に指定するデフォルトカスタム変数と、生成時に指定するカスタム変数がある。
import java.time.LocalDateTime; import java.util.Map; import org.mybatis.scripting.thymeleaf.SqlGenerator; import org.mybatis.scripting.thymeleaf.SqlGeneratorConfig; import org.mybatis.scripting.thymeleaf.processor.BindVariableRender; public class SqlGeneratorSample1 { public static void main(String[] args) { SqlGeneratorConfig config = SqlGeneratorConfig.newInstanceWithCustomizer(c -> c.getDialect() .setBindVariableRenderInstance(BindVariableRender.BuiltIn.SPRING_NAMED_PARAMETER)); SqlGenerator sqlGenerator = new SqlGenerator(config); Map<String, Object> defaultCustomVariables = Map.of("anyStaticValue", "hoge"); sqlGenerator.setDefaultCustomVariables(defaultCustomVariables); Map<String, Object> customVariables = Map.of("now", LocalDateTime.now()); Map<String, Object> params = Map.of("id", 100); String sql = sqlGenerator.generate(""" select id , /*[# th:utext=\"${now} "]*/ '2023-05-07T20:20:47' /*[/]*/ from my_users where id = /*[# mb:p="id"]*/ 1 /*[/]*/ /*[# th:if="${anyStaticValue} == 'hoge'"]*/and hoge = 'hoge'/*[/]*/ """, params, customVariables); System.out.println(sql); } }
出力結果は以下になる。
select id , 2023-05-07T20:25:20.484348200 from my_users where id = :id and hoge = 'hoge'
カスタムバインド変数の追加
SQLテンプレート処理でバインド変数を追加生成する場合にこれを使う。たとえば、以下はドキュメントの例そのままだが、name
をLIKE
で使うためにエスケープ処理したバインド変数patternName
を追加している。このためにSqlGenerator
のcustomBindVariableBinder
にバインド変数追加用のBiConsumer<String, Object>
を指定する。
import java.util.HashMap; import java.util.Map; import org.mybatis.scripting.thymeleaf.SqlGenerator; import org.mybatis.scripting.thymeleaf.SqlGeneratorConfig; import org.mybatis.scripting.thymeleaf.processor.BindVariableRender; public class SqlGeneratorSample2 { public static void main(String[] args) { SqlGeneratorConfig config = SqlGeneratorConfig.newInstanceWithCustomizer(c -> c.getDialect() .setBindVariableRenderInstance(BindVariableRender.BuiltIn.SPRING_NAMED_PARAMETER)); SqlGenerator sqlGenerator = new SqlGenerator(config); Map<String, Object> params = new HashMap<>(); params.put("name", "ho%_\\ge"); String sql = sqlGenerator.generate(""" /*[# mb:bind='patternName=|${#likes.escapeWildcard(name)}%|' /]*/ select id, name from my_users where name = /*[# mb:p='patternName']*/ 'Sato' /*[/]*/ """, params, params::put); System.out.println(sql); System.out.println(params); } }
select id, name from my_users where name = :patternName
以下のように、バインド変数params
はname
とpatternName
の2つになる。
{patternName=ho\%\_\\ge%, name=ho%_\ge}