之前写过一篇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
给我们提供了一个抽象类让我们实现就可以让错误消失,达到我们预期的效果。
实现自定义枚举Handle
在MyBatis
中,提供了一个抽象父类BaseTypeHandler
用于处理对枚举类型的转换。实现如下:
@Slf4j
public class UserGenderHandler extends BaseTypeHandler {
// 存调用
@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 * from user where user_id = #{userId}
insert into user(user_name,gender,password) values (#{userName},#{gender},#{password})
这就是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
的情况:
不使用的情况如下:
不需要写额外的handler
和配置简单易用!如果按照上面的步骤出现异常,则将版本更新到最新版即可!