19
19
import java .util .HashMap ;
20
20
import java .util .List ;
21
21
import java .util .Map ;
22
+ import java .util .concurrent .ConcurrentHashMap ;
22
23
23
24
import org .apache .ibatis .builder .BaseBuilder ;
24
25
import org .apache .ibatis .builder .BuilderException ;
@@ -38,6 +39,7 @@ public class XMLScriptBuilder extends BaseBuilder {
38
39
private boolean isDynamic ;
39
40
private final Class <?> parameterType ;
40
41
private final Map <String , NodeHandler > nodeHandlerMap = new HashMap <>();
42
+ private static final Map <String , SqlNode > emptyNodeCache = new ConcurrentHashMap <>();
41
43
42
44
public XMLScriptBuilder (Configuration configuration , XNode context ) {
43
45
this (configuration , context , null );
@@ -80,6 +82,10 @@ protected MixedSqlNode parseDynamicTags(XNode node) {
80
82
XNode child = node .newXNode (children .item (i ));
81
83
if (child .getNode ().getNodeType () == Node .CDATA_SECTION_NODE || child .getNode ().getNodeType () == Node .TEXT_NODE ) {
82
84
String data = child .getStringBody ("" );
85
+ if (data .trim ().isEmpty ()) {
86
+ contents .add (emptyNodeCache .computeIfAbsent (data , EmptySqlNode ::new ));
87
+ continue ;
88
+ }
83
89
TextSqlNode textSqlNode = new TextSqlNode (data );
84
90
if (textSqlNode .isDynamic ()) {
85
91
contents .add (textSqlNode );
@@ -248,4 +254,18 @@ private SqlNode getDefaultSqlNode(List<SqlNode> defaultSqlNodes) {
248
254
}
249
255
}
250
256
257
+ private static class EmptySqlNode implements SqlNode {
258
+ private final String whitespaces ;
259
+
260
+ public EmptySqlNode (String whitespaces ) {
261
+ super ();
262
+ this .whitespaces = whitespaces ;
263
+ }
264
+
265
+ @ Override
266
+ public boolean apply (DynamicContext context ) {
267
+ context .appendSql (whitespaces );
268
+ return true ;
269
+ }
270
+ }
251
271
}
0 commit comments