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

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

本文主要有以下内容:

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

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

MyBatis对枚举类型的处理

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

定义枚举类

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

java 复制代码
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;
    }
}

定义实体类

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

java 复制代码
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserDO {
​
    private Integer userId;
​
    private String userName;
​
    private String password;
​
    private UserGenderEnum gender;
}

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

新增的错误信息如下:

查询的错误如下:

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

实现自定义枚举Handle

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

java 复制代码
@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中添加如下配置即可

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中的代码:

java 复制代码
 @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代码如下:

java 复制代码
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:将数据库存的对象转换为枚举对象之后的序列化的值。

示例代码如下:

java 复制代码
@Getter
@AllArgsConstructor
@NoArgsConstructor
public enum GenderEnum {
​
    FEMALE(0,"女"),
    MALE(1,"男");
​
    @EnumValue
    private Integer code;
​
    // 如果不使用此注解 则json对象为FEMALE / MALE
    // 使用此注解后 则为 女 / 男
    @JsonValue
    private String desc;
​
}

使用@JsonValue的情况:

不使用的情况如下:

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

相关推荐
花果山总钻风几秒前
MySQL奔溃,InnoDB文件损坏修复记录
数据库·mysql·adb
似水流年流不尽思念1 分钟前
描述一下 Spring Bean 的生命周期 ?
后端·面试
pany18 分钟前
体验一款编程友好的显示器
前端·后端·程序员
Java水解24 分钟前
深度剖析【Spring】事务:万字详解,彻底掌握传播机制与事务原理
后端·spring
开始学java29 分钟前
继承树追溯
后端
何中应35 分钟前
分布式事务的两种解决方案
java·分布式·后端
TDengine (老段)1 小时前
TDengine IDMP 运维指南(管理策略)
大数据·数据库·物联网·ai·时序数据库·tdengine·涛思数据
SimonKing1 小时前
无需重启!动态修改日志级别的神技,运维开发都哭了
java·后端·程序员
Full Stack Developme1 小时前
PostgreSQL interval 转换为 int4 (整数)
数据库·postgresql