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("[email protected]");
        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("[email protected]");
        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("[email protected]");

        mapper.insert(user);
    }

结果

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

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

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

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

查询测试

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

// TODO 补充查询截图。

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

实现方式

  1. 序列化枚举值为接口出参
  2. 接口入参(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 protected], 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

猜你喜欢

转载自blog.csdn.net/sgx1825192/article/details/133760468
今日推荐