MyBatisPlus(十七)枚举(接口参数、枚举、数据库字段,支持互相转换)

落日映苍穹つ 2024-03-01 08:44 71阅读 0赞

说明

MyBatis-Plus 优雅地使用枚举

保存到数据库时,自动使用枚举的指定属性值进行保存;在读取数据库的时候,自动把数据库的值转换为枚举。

在这里插入图片描述

声明通用枚举属性

实现 IEnum 接口(推荐)

  1. package com.example.web.enumeration;
  2. import com.baomidou.mybatisplus.annotation.IEnum;
  3. import com.fasterxml.jackson.annotation.JsonValue;
  4. import lombok.AllArgsConstructor;
  5. /**
  6. * 性别枚举
  7. */
  8. @AllArgsConstructor
  9. public enum GenderEnum implements IEnum<Integer> {
  10. UNKNOWN(0, "未知"),
  11. MALE(1, "男"),
  12. FEMALE(2, "女");
  13. @JsonValue // 序列化枚举值为 接口出参;接口入参(RequestBody),反序列化为枚举值
  14. private final Integer value;
  15. private final String description;
  16. @Override
  17. public Integer getValue() {
  18. return value; // 标记数据库存的值是 value
  19. }
  20. }

使用 @EnumValue 注解枚举属性(不推荐)

不推荐的原因是,这样做没法兼容后续的接口查询Query参数(url中的参数)转换。

  1. package com.example.web.enumeration;
  2. import com.baomidou.mybatisplus.annotation.EnumValue;
  3. import com.fasterxml.jackson.annotation.JsonValue;
  4. import lombok.AllArgsConstructor;
  5. /**
  6. * 性别枚举
  7. */
  8. @AllArgsConstructor
  9. public enum GenderEnum {
  10. UNKNOWN(0, "未知"),
  11. MALE(1, "男"),
  12. FEMALE(2, "女");
  13. @EnumValue // 标记数据库存的值是 value
  14. @JsonValue // 序列化枚举值为 接口出参;接口入参(RequestBody),反序列化为枚举值
  15. private final int value;
  16. private final String description;
  17. }

实体属性使用枚举类型

  1. package com.example.web.entity;
  2. import com.example.web.enumeration.GenderEnum;
  3. import lombok.Data;
  4. @Data
  5. public class User {
  6. private Long id;
  7. private String name;
  8. private Integer age;
  9. private String email;
  10. private Integer deleted;
  11. private GenderEnum gender;
  12. }

数据库关系模式

在这里插入图片描述

测试

新增测试

代码

  1. /**
  2. * 插入用户(男性)
  3. */
  4. @Test
  5. public void insertMale() {
  6. User user = new User();
  7. user.setId(10L);
  8. user.setName("钱一");
  9. user.setAge(26);
  10. user.setEmail("qianyi@example.com");
  11. user.setGender(GenderEnum.MALE);
  12. mapper.insert(user);
  13. }
  14. /**
  15. * 插入用户(女性)
  16. */
  17. @Test
  18. public void insertFemale() {
  19. User user = new User();
  20. user.setId(11L);
  21. user.setName("钱二");
  22. user.setAge(26);
  23. user.setEmail("qianer@example.com");
  24. user.setGender(GenderEnum.FEMALE);
  25. mapper.insert(user);
  26. }
  27. /**
  28. * 插入用户(未填写性别)
  29. */
  30. @Test
  31. public void insertUnknown() {
  32. User user = new User();
  33. user.setId(12L);
  34. user.setName("钱三");
  35. user.setAge(26);
  36. user.setEmail("qiansan@example.com");
  37. mapper.insert(user);
  38. }

结果

插入用户(男性):
在这里插入图片描述

插入用户(女性):
在这里插入图片描述

插入用户(未填写性别):
在这里插入图片描述

数据库中的数据:
在这里插入图片描述

查询测试

  1. @Test
  2. public void selectById() {
  3. User user = mapper.selectById(10);
  4. log.info("user:{}", user);
  5. }

// TODO 补充查询截图。

序列化枚举值为接口参数值

实现方式

  1. 序列化枚举值为接口出参
  2. 接口入参(RequestBody),反序列化为枚举值。

这两种实现,都是通过 @JsonValue 注解实现的。

在这里插入图片描述

测试:序列化枚举值为接口出参

  1. @GetMapping
  2. public List<User> selectAll() {
  3. return userService.list();
  4. }

在这里插入图片描述

测试:接口入参(RequestBody),反序列化为枚举值

  1. @PostMapping
  2. public void addUser(@Valid @RequestBody User param) {
  3. log.info("新增用户:param={}", param);
  4. }

在这里插入图片描述

服务器接收到的数据,打印log

新增用户:param=User(id=70, name=小明, age=20, email=xiaoming@qq.com, deleted=0, gender=MALE)

Query参数,使用枚举

接口入参(Query参数,即url中传递的参数),反序列化为枚举值。

当前方法,使用枚举的值反序列化;同时也支持,使用枚举的名字作为请求参数,反序列化。

当前的转换器,依赖于 MyBatis-Plus 的 IEnum 接口。

配置代码

转换器

  1. package com.example.core.converter;
  2. import com.baomidou.mybatisplus.annotation.IEnum;
  3. import org.springframework.core.convert.converter.Converter;
  4. import java.util.regex.Pattern;
  5. public class EnumConverter<T extends Enum<?> & IEnum<Integer>> implements Converter<String, T> {
  6. private final Class<T> cls;
  7. EnumConverter(Class<T> cls) {
  8. this.cls = cls;
  9. }
  10. @Override
  11. public T convert(String source) {
  12. if (!isValid(source)) {
  13. throw new RuntimeException("不是合法的自然数");
  14. }
  15. T[] enumConstants = cls.getEnumConstants();
  16. Integer sourceInteger = Integer.valueOf(source);
  17. for (T enumConstant : enumConstants) {
  18. if (sourceInteger.equals(enumConstant.getValue())) {
  19. return enumConstant;
  20. }
  21. }
  22. throw new RuntimeException("无效枚举类型");
  23. }
  24. /**
  25. * 是合法的自然数
  26. */
  27. private static boolean isValid(String input) {
  28. String regex = "^(0|[1-9]\\d*)$";
  29. return Pattern.matches(regex, input);
  30. }
  31. }

转换器工厂

  1. package com.example.core.converter;
  2. import com.baomidou.mybatisplus.annotation.IEnum;
  3. import org.springframework.core.convert.converter.Converter;
  4. import org.springframework.core.convert.converter.ConverterFactory;
  5. public class EnumConverterFactory<T extends Enum<?> & IEnum<Integer>> implements ConverterFactory<String, T> {
  6. @Override
  7. public <T1 extends T> Converter<String, T1> getConverter(Class<T1> targetType) {
  8. return new EnumConverter<>(targetType);
  9. }
  10. }

WebMvcConfigurer 配置

  1. package com.example.core.config;
  2. import com.example.core.converter.EnumConverterFactory;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.format.FormatterRegistry;
  5. import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
  6. @Configuration
  7. public class WebMvcConfiguration implements WebMvcConfigurer {
  8. @Override
  9. public void addFormatters(FormatterRegistry registry) {
  10. registry.addConverterFactory(new EnumConverterFactory<>());
  11. }
  12. }

接口测试

代码

  1. @GetMapping("selectByUser")
  2. public List<User> selectByUser(User query) {
  3. log.info("查询用户:query={}", query);
  4. LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
  5. wrapper.eq(!ObjectUtils.isEmpty(query.getGender()), User::getGender, query.getGender());
  6. return userService.list(wrapper);
  7. }

结果

在这里插入图片描述

注意,使用 枚举的名字 ,也是能够正常转化为的。
在这里插入图片描述

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

发表评论

表情:
评论列表 (有 0 条评论,71人围观)

还没有评论,来说两句吧...

相关阅读