SpringBoot與MybatisPlus3.X整合之通用枚舉(十二)


一 通用枚舉

解決了繁瑣的配置,讓 mybatis 優雅的使用枚舉屬性!

3.1.0開始,可配置默認枚舉處理類來省略掃描通用枚舉配置 默認枚舉配置

  • 升級說明:

    3.1.0 以下版本改變了原生默認行為,升級時請將默認枚舉設置為EnumOrdinalTypeHandler

  • 影響用戶:

    實體中使用原生枚舉

  • 其他說明:

    配置枚舉包掃描的時候能提前注冊使用注解枚舉的緩存

  • 推薦配置:

    • 使用實現

      IEnum

      接口

      • 推薦配置defaultEnumTypeHandler

    • 使用注解枚舉處理

      • 推薦配置typeEnumsPackage

    • 注解枚舉處理與

      IEnum

      接口

      • 推薦配置typeEnumsPackage

    • 與原生枚舉混用

      • 需配置defaultEnumTypeHandlertypeEnumsPackage

申明通用枚舉屬性

方式一: 使用 @EnumValue 注解枚舉屬性 完整示例

public enum GradeEnum {
​
    PRIMARY(1, "小學"),  SECONDORY(2, "中學"),  HIGH(3, "高中");
​
    GradeEnum(int code, String descp) {
        this.code = code;
        this.descp = descp;
    }
​
    @EnumValue//標記數據庫存的值是code
    private final int code;
    //。。。
}

方式二: 枚舉屬性,實現 IEnum 接口如下:

public enum AgeEnum implements IEnum<Integer> {
    ONE(1, "一歲"),
    TWO(2, "二歲"),
    THREE(3, "三歲");
    
    private int value;
    private String desc;
    
    @Override
    public Integer getValue() {
        return this.value;
    }
}

實體屬性使用枚舉類型

public class User{
    /**
     * 名字
     * 數據庫字段: name varchar(20)
     */
    private String name;
    
    /**
     * 年齡,IEnum接口的枚舉處理
     * 數據庫字段:age INT(3)
     */
    private AgeEnum age;
        
        
    /**
     * 年級,原生枚舉(帶{@link com.baomidou.mybatisplus.annotation.EnumValue}):
     * 數據庫字段:grade INT(2)
     */
    private GradeEnum grade;
}

二 代碼

  • pom.xml

    <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
            </dependency>
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>3.2.0</version>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
            <!-- https://mvnrepository.com/artifact/p6spy/p6spy -->
            <dependency>
                <groupId>p6spy</groupId>
                <artifactId>p6spy</artifactId>
                <version>3.8.0</version>
            </dependency>
            <dependency>
                <groupId>com.h2database</groupId>
                <artifactId>h2</artifactId>
                <scope>runtime</scope>
            </dependency><dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.49</version>
                <scope>test</scope>
            </dependency>
            <!-- for testing -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>RELEASE</version>
                <scope>compile</scope>
            </dependency>
        </dependencies>

     

  • application.yml

    spring:
      datasource:
        driver-class-name: com.p6spy.engine.spy.P6SpyDriver
        url: jdbc:p6spy:h2:tcp://192.168.180.115:19200/~/mem/test
        username: root
        password: test
    ​
    # MP 配置
    mybatis-plus:
      type-enums-package: com.mp.sampleenum.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
  • 配置類

    @Configuration
    @MapperScan("com.mp.sampleenum.mapper")
    public class MybatisPlusConfig {
    ​
    }
  • 實體類

    @EqualsAndHashCode(callSuper = true)
    @Data
    @Accessors(chain = true)
    public class User extends BaseEntity {
    ​
        private String name;
    ​
        private String email;
    ​
        /**
         * IEnum接口的枚舉處理
         */
        private AgeEnum age;
    ​
        /**
         * 原生枚舉: 默認使用枚舉值順序: 0:MALE, 1:FEMALE
         */private GenderEnum gender;
    ​
        /**
         * 原生枚舉(帶{@link com.baomidou.mybatisplus.annotation.EnumValue}):
         * 數據庫的值對應該注解對應的屬性
         */
        @JSONField(serialzeFeatures= SerializerFeature.WriteEnumUsingToString)
        private GradeEnum grade;
    ​
    ​
        private UserState userState;
    ​
    }
    ​
    @Data
    @Accessors(chain = true)
    public class BaseEntity {
      private Long id;
    ​
    }
  • 枚舉

    @Getter
    public enum AgeEnum implements IEnum<Integer> {
      ONE(1, "一歲"),
      TWO(2, "二歲"),
      THREE(3, "三歲");
    ​
      private final int value;
      private final String desc;
    ​
      AgeEnum(final int value, final String desc) {
        this.value = value;
        this.desc = desc;
      }
    ​
      @Override
      public Integer getValue() {
        return value;
      }
    }
    ​
    ​
    public enum GenderEnum {
        MALE,
        FEMALE;
    }
    ​
    @Getter
    //@JSONType(serializeEnumAsJavaBean = true)
    public enum GradeEnum {
    ​
        PRIMARY(1, "小學"),
        SECONDORY(2, "中學"),
        HIGH(3, "高中");
    ​
        GradeEnum(int code, String descp) {
            this.code = code;
            this.descp = descp;
        }
    ​
        //@EnumValue
        private final int code;
        @EnumValue
        private final String descp;
    ​
    }
    ​
    ​
    @Getter
    public enum UserState implements IBaseEnum<Integer> {
    ​
        ACTIVE(1, "A"),
        INACTIVE(2, "I");
    ​
        private final int state;
        private final String descp;
    ​
        UserState(int state, String descp) {
            this.state = state;
            this.descp = descp;
    ​
        }
    ​
        @Override
        public Integer getValue() {
            return state;
        }
    ​
        @Override
        public String getDescription() {
            return descp;
        }
    }
    ​
    public interface IBaseEnum<T extends Serializable> extends IEnum<T>{
    ​
        String getDescription();
    }

    注:推薦加注解的方式,GradeEnum這個枚舉想要插入String類型,用Fastjson進行序列化。

  • 測試類

    @SpringBootTest
    class SampleEnumApplicationTests {
    ​
        @Resource
        private UserMapper mapper;
    ​
        @Test
        public void insert() {
            User user = new User();
            user.setName("K神");
            user.setAge(AgeEnum.ONE);
            user.setGrade(GradeEnum.HIGH);
            user.setGender(GenderEnum.MALE);
            user.setEmail("abc@mp.com");
            user.setUserState(UserState.ACTIVE);
            Assert.assertTrue(mapper.insert(user) > 0);
            // 成功直接拿會寫的 ID
            System.err.println("\n插入成功 ID 為:" + user.getId());
    ​
            List<User> list = mapper.selectList(null);
            for (User u : list) {
                System.out.println(u);
                Assert.assertNotNull("age should not be null", u.getAge());
                if (u.getId().equals(user.getId())) {
                    Assert.assertNotNull("gender should not be null", u.getGender());
                    Assert.assertNotNull("grade should not be null", u.getGrade());
    ​
                }
            }
        }
    ​
        @Test
        public void delete() {
            Assert.assertTrue(mapper.delete(new QueryWrapper<User>()
                    .lambda().eq(User::getAge, AgeEnum.TWO)) > 0);
        }
    ​
        @Test
        public void update() {
            Assert.assertTrue(mapper.update(new User().setAge(AgeEnum.TWO),
                    new QueryWrapper<User>().eq("age", AgeEnum.THREE)) > 0);
        }
    ​
        @Test
        public void select() {
            User user = mapper.selectOne(new QueryWrapper<User>().lambda().eq(User::getId, 2));
            Assert.assertEquals("Jack", user.getName());
            Assert.assertTrue(AgeEnum.THREE == user.getAge());
    ​
            //#1500 github: verified ok. Not a bug
            List<User> userList = mapper.selectList(new QueryWrapper<User>().lambda().eq(User::getUserState, UserState.ACTIVE));
            Assert.assertEquals(3, userList.size());
            Optional<User> userOptional = userList.stream()
                    .filter(x -> x.getId() == 1)
                    .findFirst();
            userOptional.ifPresent(user1 -> Assert.assertTrue(user1.getUserState() == UserState.ACTIVE));
        }
    ​
    }
     
  • 測試結果

     Consume Time:0 ms 2019-10-31 14:42:38
     Execute SQL:INSERT INTO user ( id, gender, user_state, grade, name, age, email ) VALUES ( 1189794788921081858, 0, 1, '高中', 'K神', 1, 'abc@mp.com' )
    ​
    ​
    插入成功 ID 為:1189794788921081858
     Consume Time:6 ms 2019-10-31 14:42:38
     Execute SQL:SELECT id,gender,user_state,grade,name,age,email FROM user
    ​

     


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM