diff --git a/src/main/java/org/mybatis/scripting/velocity/ParameterMappingCollector.java b/src/main/java/org/mybatis/scripting/velocity/ParameterMappingCollector.java index a83c045..29de2a8 100644 --- a/src/main/java/org/mybatis/scripting/velocity/ParameterMappingCollector.java +++ b/src/main/java/org/mybatis/scripting/velocity/ParameterMappingCollector.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,9 @@ import java.util.Map; import org.apache.ibatis.mapping.ParameterMapping; +import org.apache.ibatis.mapping.ParameterMode; +import org.apache.ibatis.reflection.MetaObject; +import org.apache.ibatis.reflection.property.PropertyTokenizer; import org.apache.ibatis.session.Configuration; public class ParameterMappingCollector { @@ -28,8 +31,8 @@ public class ParameterMappingCollector { private final List parameterMappings = new ArrayList<>(); private final Map context; private final Configuration configuration; + private final MetaObject metaParameters; - private int uid = 0; private String itemKey; public ParameterMappingCollector(ParameterMapping[] newParameterMappingSources, Map newContext, @@ -37,6 +40,7 @@ public ParameterMappingCollector(ParameterMapping[] newParameterMappingSources, this.parameterMappingSources = newParameterMappingSources; this.context = newContext; this.configuration = newConfiguration; + this.metaParameters = configuration.newMetaObject(newContext); } public void setItemKey(String value) { @@ -49,12 +53,7 @@ public String getItemKey() { public String g(int mapping) { ParameterMapping parameterMapping = this.parameterMappingSources[mapping]; - PropertyInfo vi = getPropertyInfo(parameterMapping.getProperty()); - if (vi.isIterable) { - parameterMapping = itemize(parameterMapping, vi); - this.context.put(vi.root, this.context.get(this.itemKey)); - } - this.parameterMappings.add(parameterMapping); + this.parameterMappings.add(mappingWithValue(parameterMapping)); return "?"; } @@ -62,41 +61,28 @@ public List getParameterMappings() { return this.parameterMappings; } - private ParameterMapping itemize(ParameterMapping source, PropertyInfo var) { - StringBuilder sb = new StringBuilder().append("_RPTITEM_").append(this.uid++); - var.root = sb.toString(); - String propertyName = sb.append(var.path).toString(); - ParameterMapping.Builder builder = new ParameterMapping.Builder(this.configuration, propertyName, - source.getJavaType()); + private ParameterMapping mappingWithValue(ParameterMapping source) { + String property = source.getProperty(); + ParameterMapping.Builder builder = new ParameterMapping.Builder(this.configuration, property, source.getJavaType()); builder.expression(source.getExpression()).jdbcType(source.getJdbcType()).jdbcTypeName(source.getJdbcTypeName()) .mode(source.getMode()).numericScale(source.getNumericScale()).resultMapId(source.getResultMapId()) .typeHandler(source.getTypeHandler()); - return builder.build(); - } - private PropertyInfo getPropertyInfo(String name) { - PropertyInfo i = new PropertyInfo(); - if (name != null) { - int p = name.indexOf('.'); - if (p == -1) { - i.root = name; + PropertyTokenizer propertyTokenizer = new PropertyTokenizer(property); + Object parameterObject = context.get(SQLScriptSource.PARAMETER_OBJECT_KEY); + if (!ParameterMode.OUT.equals(source.getMode())) { + if (metaParameters.hasGetter(propertyTokenizer.getName())) { + builder.value(metaParameters.getValue(property)); + } else if (parameterObject == null) { + builder.value(null); + } else if (configuration.getTypeHandlerRegistry().hasTypeHandler(parameterObject.getClass())) { + builder.value(parameterObject); } else { - i.root = name.substring(0, p); - i.path = name.substring(p); + MetaObject metaObject = configuration.newMetaObject(parameterObject); + builder.value(metaObject.getValue(property)); } } - i.isIterable = this.itemKey != null && this.itemKey.equals(i.root); - return i; - } - - static class PropertyInfo { - boolean isIterable = false; - String root = ""; - String path = ""; - - public PropertyInfo() { - // Prevent synthetic access - } + return builder.build(); } } diff --git a/src/test/java/org/mybatis/scripting/velocity/use/VelocityLanguageTest.java b/src/test/java/org/mybatis/scripting/velocity/use/VelocityLanguageTest.java index 1371d59..2f7a6e5 100644 --- a/src/test/java/org/mybatis/scripting/velocity/use/VelocityLanguageTest.java +++ b/src/test/java/org/mybatis/scripting/velocity/use/VelocityLanguageTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import java.sql.Connection; import java.sql.DriverManager; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -273,6 +274,31 @@ void testDynamicSelectWithIterationBoundary() { } } + @Test + void testSetInsideRepeat() { + try (SqlSession sqlSession = sqlSessionFactory.openSession()) { + Name[] names = { new Name(2), new Name(5) }; + Map param = new HashMap<>(); + param.put("names", names); + param.put("nid", 4); + List answer = sqlSession.selectList("org.mybatis.scripting.velocity.use.selectWithSetInsideRepeat", param); + assertEquals(2, answer.size()); + assertEquals(2, answer.get(0).getId()); + assertEquals(5, answer.get(1).getId()); + } + } + + @Test + void testNestedRepeat() { + try (SqlSession sqlSession = sqlSessionFactory.openSession()) { + List> ids = Arrays.asList(Arrays.asList(1, 10), Arrays.asList(100, 1000)); + Map param = new HashMap<>(); + param.put("ids", ids); + Integer answer = sqlSession.selectOne("org.mybatis.scripting.velocity.use.selectNestedRepeat", param); + assertEquals(202, answer); + } + } + @Test void testSelectKey() { try (SqlSession sqlSession = sqlSessionFactory.openSession()) { diff --git a/src/test/resources/org/mybatis/scripting/velocity/use/mapper.xml b/src/test/resources/org/mybatis/scripting/velocity/use/mapper.xml index c84b361..15f56df 100644 --- a/src/test/resources/org/mybatis/scripting/velocity/use/mapper.xml +++ b/src/test/resources/org/mybatis/scripting/velocity/use/mapper.xml @@ -1,7 +1,7 @@