This PR is proposition for more convenient way to pass collections into queries.
I added ability to expand collections by introducing new format of parameter operator: #{param...}
. When parsing query, format #{params...}
is resolved as ForEachSqlNode.
In other words existing operator #{param}
is always translated to single param ?
, but #{param...}
expands collections to list of parameters, for example to ?, ?, ?
.
This should cover these cases:
- No need to use
<script>
and<foreach>
tags when using annotations This can be simplified:
@Select({
"<script>select * from users ",
"where id in <foreach item=\"item\" collection=\"ids\" open=\"(\" separator=\",\" close=\")\">#{item}</foreach> ",
"order by id</script>"})
to:
@Select("select * from users where id in (#{ids...}) order by id")
- This works also in xml mappers:
<select id="getUsers" resultType="org.apache.ibatis.submitted.expand_collection_param.model.User">
select * from users where id != #{id} and role in
<foreach item='item' index='index' collection='roles' open='(' separator=',' close=')'>
#{item}
</foreach>
order by id
</select>
vs:
<select id="getUsers" resultType="org.apache.ibatis.submitted.expand_collection_param.model.User">
select * from users
where id != #{id} and role in (#{roles...})
order by id
</select>
- This will also reduce code when using providers:
@SelectProvider(type = StatementProvider.class, method = "getUsers")
public String getUsers(@Param("roles") List<UserRole> roles) {
SQL sql = new SQL().SELECT("*").FROM("users");
if (!roles.isEmpty()) {
sql.WHERE("role in (#{roles...})");
}
sql.ORDER_BY("id");
return sql.toString();
}
What do you think?