Как использовать список перечислений в качестве параметров в MyBatis Spring Boot? - PullRequest
0 голосов
/ 01 марта 2019

Как использовать List перечислений в качестве параметра для запроса MyBatis?Я уже создал обработчик типа для него и указал сопоставленный тип, как описано в этом другом вопросе .Он возвращает счет 0, когда он должен быть тысяч.

@Mapper
public interface BadgeMapper {
    @Select("select count(*) from badges where appType in (#{appTypes})")
    int countByType(@Param("appTypes") List<AppType> appTypes);

package com.example.mapper;
@MappedTypes({AppType.class})
public class AppTypeTypeHandler implements TypeHandler<AppType> {

    @Override
    public void setParameter(PreparedStatement ps, int i, AppType parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i, parameter.toString()); // use toString not name()
    }

public static enum AppType {
    ANDROID("A", "Android"), THEME("T", "Theme"), ...
    private String val;
    private String desc;
    AppType(String v, String d) { val = v; desc = d; }
    public String toString() {
        return val;
    }
application.properties
mybatis.type-handlers-package=com.example.mapper

Журналы отладки отображаются с правильными значениями ('A',' T ',' ST '), но для подсчета выводится 0.

            System.out.println(badgeMapper.countByType(appTypes));
Console
c.s.s.mapper.BadgeMapper.countByType     : ==>  Preparing: select count(*) from badges where appType in (?)
c.s.s.mapper.BadgeMapper.countByType     : ==> Parameters: [A, T, ST](ArrayList)                           
0
MySQL
mysql> select count(*) from badges where appType in ('A', 'T', 'ST');
+----------+
| count(*) |
+----------+
|     2365 |

Справочная документация для MyBatis XML: http://www.mybatis.org/mybatis-3/configuration.html#typeHandlers

1 Ответ

0 голосов
/ 01 марта 2019

Проблема в том, что вы вводите обработчик вообще не вызывается.

Прежде всего, весь список обрабатывается как единое целое и обрабатывается как один аргумент подготовленного оператора JDBC.Это означает, что отдельные элементы не обрабатываются с помощью указанного вами обработчика типа.

Нет переносимого способа установить список в IN подготовленный параметр оператора в JDBC и, следовательно, в mybatis (есть способов, чтобы сделать это, если вы используете postgres).

Если вы используете postgresql, вы можете создать обработчик типов, который будет принимать список перечислений и устанавливать его, используя метод, описанный в вопросе выше.

В общем случае вам необходимо динамически сгенерировать запрос для обработки каждого значения в отдельности:

@Select("<script>select count(*) from enu " +
  " where appType in ( " +
  "<foreach item='appType' collection='appTypes' separator=','>" +
  "   #{appType,typeHandler=AppTypeTypeHandler}" +
  "</foreach>)</script>")
int countByType(@Param("appTypes") List<AppType> appTypes);

В качестве альтернативы вы можете использовать @SelectProvider и строить запрос с использованием кода Java.

...