likes
comments
collection
share

【MyBatis_01】MyBatis和MyBatisPlus对枚举类型的处理

作者站长头像
站长
· 阅读数 64

之前写过一篇Spring Data Jpa对于枚举类型的处理的文章,为了自己的小强迫症,就顺手写一下Mybatis/MyBatisPlus框架对枚举了类型的处理。

本文主要有以下内容:

  • MyBatis对枚举类型的处理
  • MyBatisPlus对枚举类型的处理

前置条件:请正确搭建Spring Boot项目工程并引入相关的依赖。

MyBatis对枚举类型的处理

MyBatis对枚举类型的处理比MyBatisPlus的处理要复杂一些,因此我们弄明白MyBatis是如何处理枚举类型的。

定义枚举类

我们以常见的性别举例,定义如下的枚举类型。

public enum UserGenderEnum {

    FEMALE(0, "女"),
    MALE(1, "男");


    private Integer code;
    private String desc;

    public static UserGenderEnum convert(Integer code) {
        if (code == null) {
            return null;
        }
        return Stream.of(values())
                .filter(bean -> bean.code.equals(code))
                .findAny()
                .orElse(null);
    }

    UserGenderEnum(Integer code, String desc) {
        this.code = code;
        this.desc = desc;
    }

    public Integer getCode() {
        return code;
    }

    public String getDesc() {
        return desc;
    }
}

定义实体类

在枚举类定义完毕后,我们就需要在实体类中使用枚举类,建立枚举类和实体类的关系。

@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserDO {

    private Integer userId;

    private String userName;

    private String password;

    private UserGenderEnum gender;
}

此时假定有了一个新增insert.do接口和find_one.do接口,此时如果不做任何处理,直接调用将会分别出现服下错误:

新增的错误信息如下:

【MyBatis_01】MyBatis和MyBatisPlus对枚举类型的处理

查询的错误如下:

【MyBatis_01】MyBatis和MyBatisPlus对枚举类型的处理

直接使用是不行的,幸运的是MyBatis给我们提供了一个抽象类让我们实现就可以让错误消失,达到我们预期的效果。

实现自定义枚举Handle

MyBatis中,提供了一个抽象父类BaseTypeHandler用于处理对枚举类型的转换。实现如下:

@Slf4j
public class UserGenderHandler extends BaseTypeHandler<UserGenderEnum> {

    // 存调用 
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, UserGenderEnum parameter, JdbcType jdbcType) throws SQLException {
        log.info("i = {},parameter ={}",i,parameter);
        // 存的值就是枚举对象对应的code
        ps.setInt(i,parameter.getCode());
    }

    // 通过字段查询的时候调用 将db中存的code 转换为对应的枚举对象
    @Override
    public UserGenderEnum getNullableResult(ResultSet rs, String columnName) throws SQLException {
        Integer code = rs.getInt(columnName);
        log.info("columnName = {}",columnName);
        return UserGenderEnum.convert(code);
    }

    // 通过字段索引时调用
    @Override
    public UserGenderEnum getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        int code = rs.getInt(columnIndex);
        log.info("columnIndex: code = {} " ,code);
        return UserGenderEnum.convert(code);
    }

    // 通过存储过程时调用
    @Override
    public UserGenderEnum getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        int code = cs.getInt(columnIndex);
        log.info("CallableStatement columnIndex: code = {} " ,code);
        return UserGenderEnum.convert(code);
    }
}

在写完自定Handler之后,我们只需要在application.yml中添加如下配置即可

server:
  port: 8888
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mybatis_tutorial?useUnicode=true&characterEncoding=utf8
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
  mapper-locations: classpath:/mapper/*.xml
  # 新添枚举类型的处理。
  type-handlers-package: com.mybatis.tutorial.enums.handler
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true

完成上述配置之后,就可以正常使用了。xml和对应的controller代码如下:

controller中的代码:

 @Resource
    UserServiceInt userService;

    @PostMapping("insert.do")
    public UserDO insert(@RequestBody UserDO userDO){

        log.info("user = {}",userDO);
        return userService.insertUser(userDO);
    }

    @GetMapping("find_one.do")
    public UserDO findUserById(Integer userId){
        return userService.findUserByUserId(userId);
    }

Mapper.xml代码如下:

0<select id="findUserByUserId" parameterType="integer" resultType="com.mybatis.tutorial.domain.UserDO">
    select * from user where user_id = #{userId}
</select>

<insert id="insertUser" parameterType="com.mybatis.tutorial.domain.UserDO" useGeneratedKeys="true" keyProperty="userId">
    insert into user(user_name,gender,password) values (#{userName},#{gender},#{password})
</insert>

这就是MyBatis对枚举类型的处理。

MyBatisPlus对枚举类型的处理

MyBatisPlus中对枚举类型的处理很简单只需要使用两个注解即可:

  • @EnumValue:用于标注数据库要存的枚举属性
  • @jsonValue:将数据库存的对象转换为枚举对象之后的序列化的值。

示例代码如下:

@Getter
@AllArgsConstructor
@NoArgsConstructor
public enum GenderEnum {

    FEMALE(0,"女"),
    MALE(1,"男");

    @EnumValue
    private Integer code;

    // 如果不使用此注解 则json对象为FEMALE / MALE
    // 使用此注解后 则为 女 / 男
    @JsonValue
    private String desc;

}

使用@JsonValue的情况:

【MyBatis_01】MyBatis和MyBatisPlus对枚举类型的处理

不使用的情况如下:

【MyBatis_01】MyBatis和MyBatisPlus对枚举类型的处理

不需要写额外的handler和配置简单易用!如果按照上面的步骤出现异常,则将版本更新到最新版即可!

转载自:https://juejin.cn/post/7289662476739477561
评论
请登录