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?