Как передать Integer Array в предложение IN в MyBatis - PullRequest
21 голосов
/ 06 января 2012

В моем Mybatis есть запрос, содержащий предложение IN, которое в основном представляет собой набор Id (целых чисел)

Теперь я застрял на том, как я могу передать массив Integer в это предложение IN, чтобы он вытягивалправильные записи. Попытка передачи строки, содержащей идентификаторы, в предложение IN, но это не сработало, как ожидалось.

Пример кода ниже

Метод Mybatis с использованием аннотаций

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

Запрос

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

Вызов метода

Integer[] arr = new Integer[2];
arr[0] = 1;
arr[1] = 2;

mapper.getIds(arr)

Это не работает, Mybatis выдает ошибку, когда я вызываю метод картографа

Любые предложения, пожалуйста

Ответы [ 3 ]

31 голосов
/ 06 января 2012

В руководстве пользователя myBatis по динамическому SQL приведен пример использования цикла foreach для построения строки запроса, которая работает для списков и массивов.

До выпуска 3.2 выпришлось использовать конфигурацию XML для использования динамического SQL, с более новыми версиями также должно быть возможно использовать динамический SQL в аннотациях .

<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>
6 голосов
/ 09 февраля 2012

ДА, вы можете сделать это с помощью аннотаций.

Если вы используете postgresql , вы можете сделать как в этом сообщении .

Если вы используете MySQL , попробуйте внести следующие изменения в пример кода:

Метод Mybatis с использованием аннотаций

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

Запрос (с использованием MySQL)

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

вызов метода

Integer[] arr = new Integer[2];
arr[0] = 1;
arr[1] = 2;

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

mapper.getIds(usrIds) 
0 голосов
/ 08 марта 2019

Вы можете создать обработчик нового типа и использовать его только для своего параметра.Запрос изменится на:

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

И обработчик типа:

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);
    }
}
...