对于
mybatis
来说,内置了两个枚举转换器分别是:org.apache.ibatis.type.EnumTypeHandler
和org.apache.ibatis.type.EnumOrdinalTypeHandler
,然而很多情况我们需要自定义枚举转换器来处理枚举转换问题。关于这点可以参考如何在MyBatis中优雅的使用枚举。然而在mybatis plus
中使用枚举属性则相当舒服,解决了繁琐的配置,让 mybatis 优雅的使用枚举属性!
一. 默认行为
版本
compile "com.baomidou:mybatis-plus-boot-starter:3.4.2"
1. application.yml配置如下:
mybatis-plus:
configuration:
# 开启自动驼峰命名规则(camel case)映射,默认就是true
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
insert-strategy: not_null
update-strategy: not_null
2. 实体
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class User extends BaseEntity {
private String name;
private Integer age;
private String email;
private SexEnum sex; // 将之前的例子中的性别字段改为枚举
}
@Data
public class BaseEntity {
/**
* 数据库设置了 ID自增
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 逻辑删除字段
*/
private Boolean isDelete;
/**
* 创建时间 插入时填充字段
*/
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
/**
* 更新时间 插入和更新时填充字段
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
}
3. 枚举
@Getter
@AllArgsConstructor
public enum SexEnum {
// code 定义为10,20是为了和EnumOrdinalTypeHandler效果区分开来
FEMALE(10),
MAIL(20);
private final Integer code;
}
4. 测试
@Test
public void testInsert() {
User user = new User();
user.setName("shiv");
user.setAge(22);
user.setEmail("22@qq.com");
user.setSex(SexEnum.MAIL);
// 插入
userMapper.insert(user);
// 查询结果
User user1 = userMapper.selectById(user.getId());
Assertions.assertNotNull(user1);
}
结果:
==> Preparing: INSERT INTO user ( name, age, email, sex, create_time, update_time ) VALUES ( ?, ?, ?, ?, ?, ? )
==> Parameters: shiv(String), 22(Integer), 22@qq.com(String), MAIL(String), 2021-02-14T11:21:33.706(LocalDateTime), 2021-02-14T11:21:33.709(LocalDateTime)
<== Updates: 1
...
==> Preparing: SELECT id,name,age,email,sex,is_delete,create_time,update_time FROM user WHERE id=?
==> Parameters: 15(Long)
<== Columns: id, name, age, email, sex, is_delete, create_time, update_time
<== Row: 15, shiv, 22, 22@qq.com, MAIL, 0, 2021-02-14 11:21:34, 2021-02-14 11:21:34
<== Total: 1
可见插入到数据库的枚举的名称MAIL
,这是由于mybatis plus
默认的枚举转换配置(不同版本有区别)是org.apache.ibatis.type.EnumTypeHandler
。
我们可以修改这个默认配置,如下:
mybatis-plus:
configuration:
# 修改默认枚举处理类
default-enum-type-handler: org.apache.ibatis.type.EnumOrdinalTypeHandler
# default-enum-type-handler: org.apache.ibatis.type.EnumTypeHandler
# 开启自动驼峰命名规则(camel case)映射,默认就是true
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
insert-strategy: not_null
update-strategy: not_null
再看看效果:
==> Preparing: INSERT INTO user ( name, age, email, sex, create_time, update_time ) VALUES ( ?, ?, ?, ?, ?, ? )
==> Parameters: shiv(String), 22(Integer), 22@qq.com(String), 1(Integer), 2021-02-14T11:26:11.578(LocalDateTime), 2021-02-14T11:26:11.581(LocalDateTime)
<== Updates: 1
...
==> Preparing: SELECT id,name,age,email,sex,is_delete,create_time,update_time FROM user WHERE id=?
==> Parameters: 16(Long)
<== Columns: id, name, age, email, sex, is_delete, create_time, update_time
<== Row: 16, shiv, 22, 22@qq.com, 1, 0, 2021-02-14 11:26:12, 2021-02-14 11:26:12
<== Total: 1
可见这里就是将枚举实例的ordinal属性作为值插入了。
如果我们需要将枚举code
的值保存到数据库,那么需要怎么做呢,当然我们可以按照我们之前使用mybatis
的方法,继承BaseTypeHandler
自定义一个转换器,可参考如何在MyBatis中优雅的使用枚举!
当我们使用mybatis plus
后就不需要繁琐的配置了,怎么做呢?如下:
二. 声明通用枚举属性
方法一:使用@EnumValue
标记属性
@Getter
@AllArgsConstructor
public enum SexEnum {
FEMALE(0),
MAIL(1);
@EnumValue // 标记数据库存的值是code
private final Integer code;
}
方法二: 枚举属性,实现 IEnum 接口如下
@Getter
@AllArgsConstructor
public enum SexEnum implements IEnum<Integer> {
FEMALE(10),
MAIL(20);
private final Integer code;
@Override
public Integer getValue() {
return this.code;
}
}
三. 配置扫描通用属性
application.yml
mybatis-plus:
configuration:
# 开启自动驼峰命名规则(camel case)映射,默认就是true
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
insert-strategy: not_null
update-strategy: not_null
# 支持统配符 * 或者 ; 分割
# 枚举类 扫描路径,如果配置了该属性,会将路径下的枚举类进行注入,让实体类字段能够简单快捷的使用枚举属性
type-enums-package: cn.**.enums
再跑一下测试方法:
==> Preparing: INSERT INTO user ( name, age, email, sex, create_time, update_time ) VALUES ( ?, ?, ?, ?, ?, ? )
==> Parameters: shiv(String), 22(Integer), 22@qq.com(String), 20(Integer), 2021-02-14T11:47:40.104(LocalDateTime), 2021-02-14T11:47:40.107(LocalDateTime)
<== Updates: 1
...
==> Preparing: SELECT id,name,age,email,sex,is_delete,create_time,update_time FROM user WHERE id=?
==> Parameters: 21(Long)
<== Columns: id, name, age, email, sex, is_delete, create_time, update_time
<== Row: 21, shiv, 22, 22@qq.com, 20, 0, 2021-02-14 11:47:40, 2021-02-14 11:47:40
<== Total: 1
可见code
属性已经被插入数据库!如果我们不使用@EnumValue
或者实现IEnum
则还会走默认的转换器逻辑!