天天看點

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 使用 通用枚舉功能