MyBatisPlus(十七)枚举(接口参数、枚举、数据库字段,支持互相转换)
说明
MyBatis-Plus 优雅地使用枚举
。
保存到数据库时,自动使用枚举的指定属性值
进行保存;在读取数据库的时候,自动把数据库的值转换为枚举。
声明通用枚举属性
实现 IEnum 接口(推荐)
package com.example.web.enumeration;
import com.baomidou.mybatisplus.annotation.IEnum;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.AllArgsConstructor;
/**
* 性别枚举
*/
@AllArgsConstructor
public enum GenderEnum implements IEnum<Integer> {
UNKNOWN(0, "未知"),
MALE(1, "男"),
FEMALE(2, "女");
@JsonValue // 序列化枚举值为 接口出参;接口入参(RequestBody),反序列化为枚举值
private final Integer value;
private final String description;
@Override
public Integer getValue() {
return value; // 标记数据库存的值是 value
}
}
使用 @EnumValue 注解枚举属性(不推荐)
不推荐的原因是,这样做没法兼容后续的接口查询Query参数(url中的参数)转换。
package com.example.web.enumeration;
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.AllArgsConstructor;
/**
* 性别枚举
*/
@AllArgsConstructor
public enum GenderEnum {
UNKNOWN(0, "未知"),
MALE(1, "男"),
FEMALE(2, "女");
@EnumValue // 标记数据库存的值是 value
@JsonValue // 序列化枚举值为 接口出参;接口入参(RequestBody),反序列化为枚举值
private final int value;
private final String description;
}
实体属性使用枚举类型
package com.example.web.entity;
import com.example.web.enumeration.GenderEnum;
import lombok.Data;
@Data
public class User {
private Long id;
private String name;
private Integer age;
private String email;
private Integer deleted;
private GenderEnum gender;
}
数据库关系模式
测试
新增测试
代码
/**
* 插入用户(男性)
*/
@Test
public void insertMale() {
User user = new User();
user.setId(10L);
user.setName("钱一");
user.setAge(26);
user.setEmail("qianyi@example.com");
user.setGender(GenderEnum.MALE);
mapper.insert(user);
}
/**
* 插入用户(女性)
*/
@Test
public void insertFemale() {
User user = new User();
user.setId(11L);
user.setName("钱二");
user.setAge(26);
user.setEmail("qianer@example.com");
user.setGender(GenderEnum.FEMALE);
mapper.insert(user);
}
/**
* 插入用户(未填写性别)
*/
@Test
public void insertUnknown() {
User user = new User();
user.setId(12L);
user.setName("钱三");
user.setAge(26);
user.setEmail("qiansan@example.com");
mapper.insert(user);
}
结果
插入用户(男性):
插入用户(女性):
插入用户(未填写性别):
数据库中的数据:
查询测试
@Test
public void selectById() {
User user = mapper.selectById(10);
log.info("user:{}", user);
}
序列化枚举值为接口参数值
实现方式
- 序列化枚举值为
接口出参
; 接口入参
(RequestBody),反序列化为枚举值。
这两种实现,都是通过 @JsonValue
注解实现的。
测试:序列化枚举值为接口出参
@GetMapping
public List<User> selectAll() {
return userService.list();
}
测试:接口入参
(RequestBody),反序列化为枚举值
@PostMapping
public void addUser(@Valid @RequestBody User param) {
log.info("新增用户:param={}", param);
}
服务器接收到的数据,打印log
新增用户:param=User(id=70, name=小明, age=20, email=xiaoming@qq.com, deleted=0, gender=MALE)
Query参数,使用枚举
接口入参(Query参数,即url中传递的参数),反序列化为枚举值。
当前方法,使用枚举的值反序列化;同时也支持,使用枚举的名字作为请求参数,反序列化。
当前的转换器,依赖于 MyBatis-Plus 的 IEnum 接口。
配置代码
转换器
package com.example.core.converter;
import com.baomidou.mybatisplus.annotation.IEnum;
import org.springframework.core.convert.converter.Converter;
import java.util.regex.Pattern;
public class EnumConverter<T extends Enum<?> & IEnum<Integer>> implements Converter<String, T> {
private final Class<T> cls;
EnumConverter(Class<T> cls) {
this.cls = cls;
}
@Override
public T convert(String source) {
if (!isValid(source)) {
throw new RuntimeException("不是合法的自然数");
}
T[] enumConstants = cls.getEnumConstants();
Integer sourceInteger = Integer.valueOf(source);
for (T enumConstant : enumConstants) {
if (sourceInteger.equals(enumConstant.getValue())) {
return enumConstant;
}
}
throw new RuntimeException("无效枚举类型");
}
/**
* 是合法的自然数
*/
private static boolean isValid(String input) {
String regex = "^(0|[1-9]\\d*)$";
return Pattern.matches(regex, input);
}
}
转换器工厂
package com.example.core.converter;
import com.baomidou.mybatisplus.annotation.IEnum;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConverterFactory;
public class EnumConverterFactory<T extends Enum<?> & IEnum<Integer>> implements ConverterFactory<String, T> {
@Override
public <T1 extends T> Converter<String, T1> getConverter(Class<T1> targetType) {
return new EnumConverter<>(targetType);
}
}
WebMvcConfigurer 配置
package com.example.core.config;
import com.example.core.converter.EnumConverterFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverterFactory(new EnumConverterFactory<>());
}
}
接口测试
代码
@GetMapping("selectByUser")
public List<User> selectByUser(User query) {
log.info("查询用户:query={}", query);
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(!ObjectUtils.isEmpty(query.getGender()), User::getGender, query.getGender());
return userService.list(wrapper);
}
结果
注意,使用 枚举的名字
,也是能够正常转化为的。
Log日志
查询用户:query=User(id=null, name=null, age=null, email=null, deleted=null, gender=FEMALE, tags=null, contacts=null, createTime=null, updateTime=null)
参考
https://blog.csdn.net/hy6533/article/details/126178825
还没有评论,来说两句吧...