如何在MyBatis Spring Boot中使用枚举列表作为参数?

问题描述 投票:0回答:1

如何使用List的枚举作为MyBatis查询的参数?我已经为它创建了一个类型处理程序,并指定了映射类型,如in this other question所述。当它应该是数千时,它返回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

java mybatis spring-annotations spring-mybatis java-annotations
1个回答
1
投票

问题是你根本没有调用类型处理程序。

首先,将整个列表视为一个整体并作为JDBC预准备语句的一个参数进行处理。这意味着不会通过您指定的类型处理程序处理单个元素。

没有可移植的方法将列表设置为JDBC中的IN预处理语句参数,因此在mybatis中(如果使用postgres,则有ways可以执行此操作)。

如果您正在使用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代码构建查询。

© www.soinside.com 2019 - 2024. All rights reserved.