天天看点

SpingBoot 中 Mybatis-Plus 使用 通用枚举功能

文章目录

    • 1. 配置文件添加配置
    • 2. 定义枚举
      • 2.1 方式一
      • 2.2 方式二
      • 2.3 方式三
    • 3. 定义实体类
    • 4.测试使用

1. 配置文件添加配置

# MP 配置
mybatis-plus:
  type-enums-package: com.baomidou.mybatisplus.samples.enums.enums
  configuration:
    # 3.0.8之前版本问题默认将枚举注册为EnumOrdinalTypeHandler,这是错误的方式,默认是 org.apache.ibatis.type.EnumTypeHandler
    # 如果项目之中实体统一使用IEnum或注解的方式,可配置成 com.baomidou.mybatisplus.extension.handlers.EnumTypeHandler,也可省略上面的type-enums-package配置
    # 配置type-enums-package只对注解方式的枚举处理能提前加载缓存.
    default-enum-type-handler: org.apache.ibatis.type.EnumOrdinalTypeHandler
           

2. 定义枚举

2.1 方式一

使用

@EnumValue

注解

package com.gangbb.test.enums;

import com.baomidou.mybatisplus.annotation.EnumValue;
import com.fasterxml.jackson.annotation.JsonValue;

/**
 * @Author Gangbb
 * @Description MP测试 状态enum (方式一)
 * @Date 2021/7/22
 **/
public enum StatusEnum{
    DISABLE(1, "禁用"),  ABLE(2, "启用"),  LOCK(3, "锁定");

    StatusEnum(int code, String name) {
        this.code = code;
        this.name = name;
    }

    @EnumValue//标记数据库记录的值是code
    private final int code;

    @JsonValue//标记响应json值
    private final String name;

    public static StatusEnum getEnum(String name) {
        for (StatusEnum item : values()) {
            if (item.getName().equals(name)) {
                return item;
            }
        }
        return null;
    }

    public int getCode() {
        return code;
    }

    public String getName() {
        return name;
    }
}

           

2.2 方式二

枚举属性,实现

IEnum<T>

接口。这里的字段代表值时String类型,

IEnum<T>

的泛型T就填入String类型。

package com.gangbb.test.enums;

import com.baomidou.mybatisplus.annotation.IEnum;
import com.fasterxml.jackson.annotation.JsonValue;

/**
 * @Author Gangbb
 * @Description MP测试 状态enum (方式二)
 * @Date 2021/7/22
 **/
public enum LevelEnum implements IEnum<String> {

    DISABLE("a", "高级"),  ABLE("b", "中级"),  LOCK("c", "低级");

    private final String code;

    private final String name;

    LevelEnum(String code, String name) {
        this.code = code;
        this.name = name;
    }

    @Override
    public String getValue() {
        return code;
    }

    @JsonValue
    public String getName() {
        return name;
    }
}

           

2.3 方式三

其实是方式二的一种衍生。

先定义一个实现

IEnum<T>

接口的自定义

IBaseEnum<T extends Serializable>

接口,其中有一个

getName()

方法,我定的枚举喜欢代表值用code,对应的中文描述用name命名,所以叫

getName()

package com.gangbb.test.enums;

import com.baomidou.mybatisplus.annotation.IEnum;

import java.io.Serializable;

/**
 * @Author Gangbb
 * @Description 自定义基类枚举
 * @Date 2021/7/22
 **/
public interface IBaseEnum<T extends Serializable> extends IEnum<T>{

    String getName();
}
           

然后枚举类实现这个接口,其实就是跟方式二一样的,但是实现这个接口,枚举类同时需要重写

getValue()

getName()

,这样好形成一个规范,不管是命名还是使用上。

package com.gangbb.test.enums;

import com.fasterxml.jackson.annotation.JsonValue;

/**
 * @Author Gangbb
 * @Description TODO
 * @Date 2021/7/22
 **/
public enum VisitStageEnum implements IBaseEnum<Integer>{
    ONE(1, "一访"), TWO(2, "二访"), THREE(3, "三访");

    VisitStageEnum(int code, String name) {
        this.code = code;
        this.name = name;
    }

    private final int code;
    private final String name;

    @Override
    public Integer getValue() {
        return code;
    }

    @Override
    @JsonValue
    public String getName() {
        return name;
    }
}
           

3. 定义实体类

package com.gangbb.test.model.entity;

import com.gangbb.core.model.entity.BaseEntity;
import com.gangbb.test.enums.LevelEnum;
import com.gangbb.test.enums.StatusEnum;
import com.gangbb.test.enums.VisitStageEnum;

import java.io.Serializable;

/**
 * @Author Gangbb
 * @Description 测试mp实体类
 * @Date 2021/7/20
 **/
public class TestMybatisPlus extends BaseEntity implements Serializable {
    private static final long serialVersionUID = 8732481089448556962L;

    /**
     * 姓名
     */
    private String name;

    /**
     * 年龄
     */
    private Integer age;

    /**
     * 性别
     */
    private Integer sex;

    /**
     * 状态,原生枚举(带{@link com.baomidou.mybatisplus.annotation.EnumValue})
     * 数据库字段:status tinyint(2)
     */
    private StatusEnum status;

    /**
     * 等级,IEnum接口的枚举处理
     * 数据库字段:level char(4)
     */
    private LevelEnum level;

	
    private VisitStageEnum visitStage;

    // get/set方法省略
}
           

4.测试使用

测试的用例:
  • 查询使用枚举值的实体,序列化返回前端后,是否会把代表值换成对应的中文值。
  • 使用枚举字段作为条件构造器的传入参数进行查询,看是否会用相应的代表值查询
  • 插入时,枚举字段传入中文值时,存入数据库会不会转成相应的代表值
/**
 * @Author Gangbb
 * @Description 测试MP通用枚举
 * @Date 2021/7/22
 **/
@RestController
@RequestMapping("/test/mp")
public class TestMPEnumController {

    @Autowired
    private TestMPService testMPService;

    @GetMapping("/enum1")
    public List<TestMybatisPlus> enum1(){
        return testMPService.findAll();
    }

    @GetMapping("/enum2")
    public List<TestMybatisPlus> enum2(){
        // 查询所有 启用 的记录
        QueryWrapper<TestMybatisPlus> wrapper = new QueryWrapper<>();
        wrapper.eq("status", StatusEnum.LOCK);
        return testMPService.findAllByWrapper(wrapper);
    }

    @PostMapping("/enum3")
    public ApiRestResponse enum3(){
        TestMybatisPlus mybatisPlus = new TestMybatisPlus();
        mybatisPlus.setName("测试枚举插入2");
        mybatisPlus.setSex(12);
        mybatisPlus.setAge(122);
        // 模拟传入的中文值字段值
        String a = "启用";
        mybatisPlus.setStatus(StatusEnum.getEnum(a));
        mybatisPlus.setLevel(LevelEnum.ABLE);
        mybatisPlus.setVisitStage(VisitStageEnum.ONE);
        testMPService.save(mybatisPlus);
        return ApiRestResponse.success();
    }

}
           

数据库中储存的记录:

SpingBoot 中 Mybatis-Plus 使用 通用枚举功能

结果:

/enum1

SpingBoot 中 Mybatis-Plus 使用 通用枚举功能

/enum2

传入枚举,查询时已转成相应的代表值:

SpingBoot 中 Mybatis-Plus 使用 通用枚举功能

/enum3

SpingBoot 中 Mybatis-Plus 使用 通用枚举功能