关于Java:如何将整数数组传递给MyBatis中的IN子句

How to pass an Integer Array to IN clause in MyBatis

我的Mybatis中有一个查询,其中包含一个IN子句,该子句基本上是一组ID(整数)

我现在陷入了如何将Integer数组传递给此IN子句的问题,以使它提取正确的记录。尝试通过将包含ID的String传递给IN子句,但这无法按预期工作。铅>

下面的代码示例

使用注释的Mybatis方法

1
2
3
@Select(SEL_QUERY)
    @Results(value = {@Result(property="id",column="ID")})
    List<Integer> getIds(@Param("usrIds") Integer[] usrIds);

查询

1
select distinct ID from table a where a.id in ( #{usrIds} )

方法调用

1
2
3
4
5
Integer[] arr = new Integer[2];
arr[0] = 1;
arr[1] = 2;

mapper.getIds(arr)

这不起作用,当我调用mapper方法时,Mybatis引发错误

请提出任何建议


有关动态SQL的myBatis用户指南,其中有一个示例,说明如何使用foreach循环构建查询字符串,该字符串适用于列表和数组。

在3.2版之前,您必须使用xml配置才能使用动态sql,在较新的版本中,也应该可以在注释中使用动态sql。

1
2
3
4
5
6
7
8
9
<select id="selectPostIn" resultType="domain.blog.Post">
    SELECT *
    FROM POST P
    WHERE ID in
    <foreach item="item" index="index" collection="list"
             open="(" separator="," close=")">
        #{item}
    </foreach>
</select>


是的,您可以使用批注来实现。

如果您使用的是postgresql,则可以在这篇文章中做。

如果您使用的是MySQL,请尝试在代码示例中进行以下更改:

使用注释的Mybatis方法

1
2
3
@Select(SEL_QUERY)
    @Results(value = {@Result(property="id",column="ID")})
    List<Integer> getIds(@Param("usrIds") String usrIds);

查询(使用MySQL)

1
select distinct ID from table a where FIND_IN_SET( a.id, #{usrIds}) <> 0

方法调用

1
2
3
4
5
6
7
8
9
10
Integer[] arr = new Integer[2];
arr[0] = 1;
arr[1] = 2;

String usrIds="";
for (int id : ids) {
    usrIds += id +",";
}

mapper.getIds(usrIds)


您可以创建一个新的类型处理程序,并将其仅用于您的参数。查询将更改为:

1
SELECT ... WHERE FIND_IN_SET(id, #{usrIds, typeHandler=my.pkg.ListTypeHandler}) <> 0

和类型处理程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import java.sql.PreparedStatement;
import java.sql.SQLException;

import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.ObjectTypeHandler;

import com.google.common.base.Joiner;

public class ListTypeHandler extends ObjectTypeHandler {
    @Override
    public void setParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
        ps.setObject(i, Joiner.on(",").join((Iterable< ? >) parameter), JdbcType.OTHER.TYPE_CODE);
    }
}

1
List distinctID = (List) getSqlSession().selectOne("dataMapper.getUniqueData", uniqueIDList);

发送唯一ID列表

1
2
3
4
5
6
7
<select id="getUniqueData" resultType="List">
     select distinct ID from table a where a.id in
      <foreach item="item" index="index" collection="list"
          open="(" separator="," close=")">
            #{item}
      </foreach>
</select>

使用列表时,索引将是当前迭代的数量,而值项将是此迭代中检索到的元素。