• 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
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    使用 @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;
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    实体属性使用枚举类型

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    数据库关系模式

    在这里插入图片描述

    测试

    新增测试

    代码

        /**
         * 插入用户(男性)
         */
        @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);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    结果

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

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

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

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

    查询测试

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

    // TODO 补充查询截图。

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

    实现方式

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

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

    在这里插入图片描述

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

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

    在这里插入图片描述

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

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

    在这里插入图片描述

    服务器接收到的数据,打印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);
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    转换器工厂

    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);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    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<>());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    接口测试

    代码

        @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);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 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

  • 相关阅读:
    【RuoYi-Vue-Plus】扩展笔记 07 - CentOS 7 集成 Prometheus + Grafana 监控初体验
    项目相互依赖调用解决方法两种方法
    Fastadmin后端表格动态展示列
    TIA博途_水处理项目中开启累计运行时间最短的泵_程序示例
    L60.linux命令每日一练 -- 第九章 Linux进程管理命令 -- top和nice
    LeetCode每日一题:2136. 全部开花的最早一天(2023.9.30 C++)
    2023年,下班后可以做什么副业?
    VMware 虚拟机里连不上网的解决方案
    Java程序员毕业N年系列----毕业二年
    html如何携带参数自动跳转页面
  • 原文地址:https://blog.csdn.net/sgx1825192/article/details/133760468