11/*
2- * Copyright 2018-2022 the original author or authors.
2+ * Copyright 2018-2025 the original author or authors.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
1616package org .mybatis .scripting .thymeleaf ;
1717
1818import java .lang .reflect .InvocationTargetException ;
19+ import java .util .ArrayList ;
1920import java .util .Arrays ;
2021import java .util .Collection ;
2122import java .util .HashMap ;
2223import java .util .HashSet ;
24+ import java .util .List ;
2325import java .util .Locale ;
2426import java .util .Map ;
2527import java .util .Optional ;
2628import java .util .Properties ;
2729import java .util .Set ;
2830import java .util .function .BiFunction ;
2931
32+ import org .apache .ibatis .builder .ParameterMappingTokenHandler ;
3033import org .apache .ibatis .builder .SqlSourceBuilder ;
3134import org .apache .ibatis .mapping .BoundSql ;
35+ import org .apache .ibatis .mapping .ParameterMapping ;
3236import org .apache .ibatis .mapping .SqlSource ;
37+ import org .apache .ibatis .parsing .GenericTokenParser ;
3338import org .apache .ibatis .reflection .MetaClass ;
3439import org .apache .ibatis .scripting .xmltags .DynamicContext ;
3540import org .apache .ibatis .session .Configuration ;
@@ -54,7 +59,6 @@ private static class TemporaryTakeoverKeys {
5459
5560 private final Configuration configuration ;
5661 private final SqlGenerator sqlGenerator ;
57- private final SqlSourceBuilder sqlSourceBuilder ;
5862 private final String sqlTemplate ;
5963 private final Class <?> parameterType ;
6064
@@ -76,7 +80,6 @@ private static class TemporaryTakeoverKeys {
7680 this .sqlGenerator = sqlGenerator ;
7781 this .sqlTemplate = sqlTemplate ;
7882 this .parameterType = parameterType ;
79- this .sqlSourceBuilder = new SqlSourceBuilder (configuration );
8083 }
8184
8285 /**
@@ -101,13 +104,23 @@ public BoundSql getBoundSql(Object parameterObject) {
101104 customVariables .put (TemporaryTakeoverKeys .PROCESSING_PARAMETER_TYPE , processingParameterType );
102105 String sql = sqlGenerator .generate (sqlTemplate , parameterObject , bindings ::put , customVariables );
103106
104- SqlSource sqlSource = sqlSourceBuilder . parse (sql , processingParameterType , bindings );
107+ SqlSource sqlSource = parse (configuration , sql , parameterObject , bindings );
105108 BoundSql boundSql = sqlSource .getBoundSql (parameterObject );
106109 bindings .forEach (boundSql ::setAdditionalParameter );
107110
108111 return boundSql ;
109112 }
110113
114+ private static SqlSource parse (Configuration configuration , String originalSql , Object parameterObject ,
115+ Map <String , Object > additionalParameters ) {
116+ Class <?> parameterType = parameterObject == null ? Object .class : parameterObject .getClass ();
117+ List <ParameterMapping > parameterMappings = new ArrayList <>();
118+ ParameterMappingTokenHandler handler = new ParameterMappingTokenHandler (parameterMappings , configuration ,
119+ parameterObject , parameterType , additionalParameters , true );
120+ GenericTokenParser parser = new GenericTokenParser ("#{" , "}" , handler );
121+ return SqlSourceBuilder .buildSqlSource (configuration , parser .parse (originalSql ), parameterMappings );
122+ }
123+
111124 /**
112125 * The factory class for Thymeleaf's context.
113126 *
@@ -120,7 +133,7 @@ static class ContextFactory implements BiFunction<Object, Map<String, Object>, I
120133 @ Override
121134 public IContext apply (Object parameter , Map <String , Object > customVariable ) {
122135 Configuration configuration = (Configuration ) customVariable .remove (TemporaryTakeoverKeys .CONFIGURATION );
123- Map <String , Object > bindings = (Map <String , Object >) customVariable .remove (TemporaryTakeoverKeys .DYNAMIC_CONTEXT );
136+ Map <String , Object > bindings = (Map <String , Object >) customVariable .remove (TemporaryTakeoverKeys .DYNAMIC_CONTEXT );
124137 Class <?> processingParameterType = (Class <?>) customVariable
125138 .remove (TemporaryTakeoverKeys .PROCESSING_PARAMETER_TYPE );
126139 MyBatisBindingContext bindingContext = new MyBatisBindingContext (
0 commit comments