Вы можете использовать обработчик пользовательского типа, чтобы сделать это.Например:
public class InClauseParams extends ArrayList<String> {
//...
// marker class for easier type handling, and avoid potential conflict with other list handlers
}
Зарегистрируйте следующий обработчик типа в вашей конфигурации MyBatis (или укажите в аннотации):
public class InClauseTypeHandler extends BaseTypeHandler<InClauseParams> {
@Override
public void setNonNullParameter(final PreparedStatement ps, final int i, final InClauseParams parameter, final JdbcType jdbcType) throws SQLException {
// MySQL driver does not support this :/
Array array = ps.getConnection().createArrayOf( "VARCHAR", parameter.toArray() );
ps.setArray( i, array );
}
// other required methods omitted for brevity, just add a NOOP implementation
}
Затем вы можете использовать их следующим образом
@Select("SELECT * FROM foo WHERE id IN (#{list})"
List<Bar> select(@Param("list") InClauseParams params)
Однако, это будет не работать для MySQL, потому что коннектор MySQL не поддерживает setArray()
для подготовленных операторов.
Возможный обходной путь для MySQL должен использовать FIND_IN_SET
вместо IN
:
@Select("SELECT * FROM foo WHERE FIND_IN_SET(id, #{list}) > 0")
List<Bar> select(@Param("list") InClauseParams params)
И ваш обработчик типа становится:
@Override
public void setNonNullParameter(final PreparedStatement ps, final int i, final InClauseParams parameter, final JdbcType jdbcType) throws SQLException {
// note: using Guava Joiner!
ps.setString( i, Joiner.on( ',' ).join( parameter ) );
}
Примечание: я не знаю производительность FIND_IN_SET
, так что проверьте это, есливажно