【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和配置简单易用!如果按照上面的步骤出现异常,则将版本更新到最新版即可!

相关推荐
麦聪聊数据3 分钟前
Web 原生架构如何重塑企业级数据库协作流?
数据库·sql·低代码·架构
未来之窗软件服务4 分钟前
数据库优化提速(四)新加坡房产系统开发数据库表结构—仙盟创梦IDE
数据库·数据库优化·计算机软考
程序员侠客行1 小时前
Mybatis连接池实现及池化模式
java·后端·架构·mybatis
Honmaple1 小时前
QMD (Quarto Markdown) 搭建与使用指南
后端
PP东1 小时前
Flowable学习(二)——Flowable概念学习
java·后端·学习·flowable
invicinble1 小时前
springboot的核心实现机制原理
java·spring boot·后端
Goat恶霸詹姆斯1 小时前
mysql常用语句
数据库·mysql·oracle
全栈老石2 小时前
Python 异步生存手册:给被 JS async/await 宠坏的全栈工程师
后端·python
大模型玩家七七2 小时前
梯度累积真的省显存吗?它换走的是什么成本
java·javascript·数据库·人工智能·深度学习
曾经的三心草2 小时前
redis-9-哨兵
数据库·redis·bootstrap