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

相关推荐
跟着珅聪学java37 分钟前
spring boot +Elment UI 上传文件教程
java·spring boot·后端·ui·elementui·vue
徐小黑ACG2 小时前
GO语言 使用protobuf
开发语言·后端·golang·protobuf
·薯条大王4 小时前
MySQL联合查询
数据库·mysql
战族狼魂4 小时前
CSGO 皮肤交易平台后端 (Spring Boot) 代码结构与示例
java·spring boot·后端
杉之6 小时前
常见前端GET请求以及对应的Spring后端接收接口写法
java·前端·后端·spring·vue
morris1316 小时前
【redis】redis实现分布式锁
数据库·redis·缓存·分布式锁
hycccccch6 小时前
Canal+RabbitMQ实现MySQL数据增量同步
java·数据库·后端·rabbitmq
bobz9657 小时前
k8s 怎么提供虚拟机更好
后端
这个懒人7 小时前
深入解析Translog机制:Elasticsearch的数据守护者
数据库·elasticsearch·nosql·translog
Yan-英杰7 小时前
【百日精通JAVA | SQL篇 | 第二篇】数据库操作
服务器·数据库·sql