一 通用枚举
解决了繁琐的配置,让 mybatis 优雅的使用枚举属性!
自
3.1.0
开始,可配置默认枚举处理类来省略扫描通用枚举配置 默认枚举配置
升级说明:
3.1.0
以下版本改变了原生默认行为,升级时请将默认枚举设置为EnumOrdinalTypeHandler
实体中使用原生枚举
其他说明:
配置枚举包扫描的时候能提前注册使用注解枚举的缓存
推荐配置:
使用实现
IEnum
接口
推荐配置
defaultEnumTypeHandler
使用注解枚举处理
推荐配置
typeEnumsPackage
注解枚举处理与
IEnum
接口
推荐配置
typeEnumsPackage
与原生枚举混用
需配置
defaultEnumTypeHandler
与typeEnumsPackage
申明通用枚举属性
方式一: 使用 @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(" 插入成功 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)); } }