Skip to content

Commit

Permalink
Allow using actual argument name as bind parameter on a single collec…
Browse files Browse the repository at this point in the history
…tion mybatis#1237
  • Loading branch information
kazuki43zoo committed Mar 29, 2018
1 parent fbe3d38 commit 3a74383
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 92 deletions.
Expand Up @@ -27,6 +27,7 @@
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.defaults.DefaultSqlSession;

public class ParamNameResolver {

Expand All @@ -48,6 +49,7 @@ public class ParamNameResolver {
private final SortedMap<Integer, String> names;

private boolean hasParamAnnotation;
private boolean useActualParamName;

public ParamNameResolver(Configuration config, Method method) {
final Class<?>[] paramTypes = method.getParameterTypes();
Expand Down Expand Up @@ -77,6 +79,8 @@ public ParamNameResolver(Configuration config, Method method) {
// use the parameter index as the name ("0", "1", ...)
// gcode issue #71
name = String.valueOf(map.size());
} else {
useActualParamName = true;
}
}
map.put(paramIndex, name);
Expand Down Expand Up @@ -115,7 +119,12 @@ public Object getNamedParams(Object[] args) {
if (args == null || paramCount == 0) {
return null;
} else if (!hasParamAnnotation && paramCount == 1) {
return args[names.firstKey()];
Object value = args[names.firstKey()];
if (useActualParamName) {
return DefaultSqlSession.wrapCollection(value, map -> map.put(names.get(0), value));
} else {
return value;
}
} else {
final Map<String, Object> param = new ParamMap<Object>();
int i = 0;
Expand Down
@@ -1,5 +1,5 @@
/**
* Copyright 2009-2017 the original author or authors.
* Copyright 2009-2018 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.
Expand All @@ -23,6 +23,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

import org.apache.ibatis.binding.BindingException;
import org.apache.ibatis.cursor.Cursor;
Expand Down Expand Up @@ -318,15 +319,35 @@ private boolean isCommitOrRollbackRequired(boolean force) {
}

private Object wrapCollection(final Object object) {
return wrapCollection(object, null);
}

/**
* Wrap a collection and array into {@link Map}.
*
* @param object a target parameter object
* @param mapConsumer consumer function for a map that wrapped collection and array. If
* {@code object} is collection or array, this function will be called.
* @return If {@code object} is collection or array, return a map that wrapped collection and
* array. Otherwise return a argument object.
* @since 3.5.0
*/
public static Object wrapCollection(final Object object, final Consumer<Map<String, Object>> mapConsumer) {
if (object instanceof Collection) {
StrictMap<Object> map = new StrictMap<Object>();
if (mapConsumer != null) {
mapConsumer.accept(map);
}
map.put("collection", object);
if (object instanceof List) {
map.put("list", object);
}
return map;
} else if (object != null && object.getClass().isArray()) {
StrictMap<Object> map = new StrictMap<Object>();
if (mapConsumer != null) {
mapConsumer.accept(map);
}
map.put("array", object);
return map;
}
Expand Down
@@ -1,5 +1,5 @@
--
-- Copyright 2009-2016 the original author or authors.
-- Copyright 2009-2018 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.
Expand Down

This file was deleted.

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2009-2016 the original author or authors.
Copyright 2009-2018 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.
Expand All @@ -17,19 +17,19 @@
-->
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="org.apache.ibatis.submitted.param_name_resolve.Mapper">
<!-- when compiled with -parameters and useActualParamName enabled, -->
<!-- the first parameter should be accessed by its name 'ids', -->
<!-- in addition with default name 'list' and 'collection'. -->
<select id="getUserCount" resultType="Long">
select count(*)
from users u
where u.id in
<foreach item='item' index='index' collection='ids' open='(' separator=',' close=')'>
#{item}
</foreach>
</select>
<mapper namespace="org.apache.ibatis.submitted.param_name_resolve.ParamNameResolveTest$Mapper">
<!-- when compiled with -parameters and useActualParamName enabled, -->
<!-- the first parameter should be accessed by its name 'ids', -->
<!-- in addition with default name 'list' and 'collection'. -->
<select id="getUserCount" resultType="Long">
select count(*)
from users u
where u.id in
<foreach item='item' index='index' collection='ids' open='(' separator=',' close=')'>
#{item}
</foreach>
</select>
</mapper>
@@ -1,3 +1,18 @@
/**
* Copyright 2009-2018 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ibatis.submitted.param_name_resolve;

import org.apache.ibatis.io.Resources;
Expand All @@ -11,40 +26,43 @@
import java.io.Reader;
import java.sql.Connection;
import java.util.Arrays;
import java.util.List;

import static org.junit.Assert.assertEquals;

public class ParamNameResolveTest {
private static SqlSessionFactory sqlSessionFactory;
private static SqlSessionFactory sqlSessionFactory;

@BeforeClass
public static void setUp() throws Exception {
// create an SqlSessionFactory
Reader reader = Resources.getResourceAsReader("org/apache/ibatis/submitted/param_name_resolve/mybatis-config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
reader.close();
@BeforeClass
public static void setUp() throws Exception {
// create an SqlSessionFactory
try (Reader reader = Resources
.getResourceAsReader("org/apache/ibatis/submitted/param_name_resolve/mybatis-config.xml")) {
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
}

// populate in-memory database
SqlSession session = sqlSessionFactory.openSession();
// populate in-memory database
try (SqlSession session = sqlSessionFactory.openSession();
Connection conn = session.getConnection();
reader = Resources.getResourceAsReader("org/apache/ibatis/submitted/param_name_resolve/CreateDB.sql");
ScriptRunner runner = new ScriptRunner(conn);
runner.setLogWriter(null);
runner.runScript(reader);
conn.close();
reader.close();
session.close();
Reader reader = Resources
.getResourceAsReader("org/apache/ibatis/submitted/param_name_resolve/CreateDB.sql")) {
ScriptRunner runner = new ScriptRunner(conn);
runner.setLogWriter(null);
runner.runScript(reader);
}
}

@Test
public void testSingleParameter() {
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
Mapper mapper = sqlSession.getMapper(Mapper.class);
long count = mapper.getUserCount(Arrays.asList(1, 2));
assertEquals(2, count);
} finally {
sqlSession.close();
}
@Test
public void testSingleParameterWhenUseActualParamNameIsTrue() {
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
Mapper mapper = sqlSession.getMapper(Mapper.class);
long count = mapper.getUserCount(Arrays.asList(1, 2));
assertEquals(2, count);
}
}

interface Mapper {
Long getUserCount(List<Integer> ids);
}

}

This file was deleted.

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
Copyright 2009-2016 the original author or authors.
Copyright 2009-2018 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.
Expand All @@ -17,26 +17,24 @@
-->
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>

<environments default="development">
<environment id="development">
<transactionManager type="JDBC">
<property name="" value="" />
</transactionManager>
<dataSource type="UNPOOLED">
<property name="driver" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:hsqldb:mem:param_name_resolve" />
<property name="username" value="sa" />
</dataSource>
</environment>
</environments>

<mappers>
<mapper class="org.apache.ibatis.submitted.param_name_resolve.Mapper" />
</mappers>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="UNPOOLED">
<property name="driver" value="org.hsqldb.jdbcDriver"/>
<property name="url" value="jdbc:hsqldb:mem:param_name_resolve"/>
<property name="username" value="sa"/>
</dataSource>
</environment>
</environments>

<mappers>
<mapper resource="org/apache/ibatis/submitted/param_name_resolve/Mapper.xml"/>
</mappers>

</configuration>

0 comments on commit 3a74383

Please sign in to comment.