Mybatis Plus 系列5 —— 通用枚举


对于mybatis来说,内置了两个枚举转换器分别是:org.apache.ibatis.type.EnumTypeHandlerorg.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则还会走默认的转换器逻辑!


文章作者: shiv
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 shiv !
评论
  目录