自动映射枚举处理器 | Mybatis-Plus

一.枚举声明

1.1注解标记

1.2实现接口

二.springboot如何接收枚举类型?

2.1.请求行接收参数

2.2.请求体接收参数

2.2.1.定义接口实现

2.2.2.配置枚举类型转换器

2.2.3.注册转换器

三.案例测试

例如:条件分页查询话题类型

例如:修改用户性别信息


 

        一般我们在数据库都会定义数值型的枚举常量,不管是序列化还是反序列化都是需要我们手动去转换成枚举类型的,既然这样我们能不能让它们自动转换呢?

        mybatis底层给我们提供了一项功能(TypeHandle)用于我们Java的数据类型与数据库中的类型之间相互转换,其中就包含了一个枚举处理器。但是它并不能满足我们的需求,于是Mybatis-Plus对其进行了扩展:

        在 mybatis 的 EnumOrdinalTypeHandler(基于枚举常量序号) 和 EnumTypeHandler(基于枚举常量名) 之外提供了更加灵活的枚举处理器 MybatisEnumTypeHandler(基于枚举常量属性)
只需要对枚举进行声明,即可实现枚举的自动映射
未进行声明的枚举则根据 mybatisdefaultEnumTypeHandler 的默认值EnumTypeHandler 来进行映射

一.枚举声明

声明该枚举使用 MybatisEnumTypeHandler(基于枚举常量属性) 进行映射

1.1注解标记

枚举属性使用 @EnumValue 注解,指定枚举值在数据库中存储的实际值。支持枚举类中的任意字段,如序号或编码。

@Getter
public enum Sex implements{
    MAN(0, "男"),
    WOMAN(1, "女");
    @EnumValue // 标记数据库存的值是code
    private final Integer value;
    // 其他属性...
}

1.2实现接口

实现 IEnum 接口,实现 getValue 方法,指定枚举值在数据库中存储的实际值。支持枚举类中的任意字段,如序号或编码。


import java.io.Serializable;

/**
 * @author hl
 */
public interface IEnum<T extends Serializable> {

    /**
     * 获取值
     * @return 值
     */
    T getValue();
}
@Getter
@AllArgsConstructor
public enum Sex implements IEnum<Integer> {
    MAN(0, "男"),
    WOMAN(1, "女");
    private final Integer value;
    private final String desc;
    @Override
    public Integer getValue() {
        return this.value;
    }
}

二.springboot如何接收枚举类型?

对于接收不同的参数,我们需给出不同的接收方式,否则会接收失败

2.1.请求行接收参数

如果我们使用的是Param参数发送:Query或Path,我们可以使用注解标记,使用 @EnumValue 注解,指定枚举值在数据库中存储的实际值

例如:其中@EnumValue 注解用于指定枚举值在数据库中存储的实际值的对应方式,@JsonValue注解用于标识给前端的返回值(标识在value之上表示返回的是Integer类型,标识在des之上表示返回的是String类型

@Getter
public enum Sex {
    MAN(0, "男"),
    WOMAN(1, "女");
    @EnumValue
    private final Integer value;
    @JsonValue
    private final String desc;
    Sex(Integer value, String desc) {
        this.value = value;
        this.desc = desc;
    }
}

2.2.请求体接收参数

如果我们接收的是 JSON 字符串类型,那么 Jackson 默认是根据下标进行转换的,和我们根据匹配值获取相应枚举不符,所以进行以下设置:

2.2.1.定义接口实现


import java.io.Serializable;

/**
 * @author hl
 */
public interface IEnum<T extends Serializable> {

    /**
     * 获取值
     * @return 值
     */
    T getValue();
}
@Getter
public enum Sex implements IEnum<Integer> {
    MAN(0, "男"),
    WOMAN(1, "女");
    @EnumValue
    private final Integer value;
    @JsonValue
    private final String desc;
    Sex(Integer value, String desc) {
        this.value = value;
        this.desc = desc;
    }
}

2.2.2.配置枚举类型转换器


@Component
public class EnumConvertFactory implements ConverterFactory<String, IEnum<?>> {

    @Override
    public <T extends IEnum<?>> Converter<String, T> getConverter(Class<T> targetType) {
        return new StringToEnum<>(targetType);
    }


    public static class StringToEnum<T extends IEnum<?>> implements Converter<String, T> {

        private final Class<T> targetType;

        public StringToEnum(Class<T> targetType) {
            this.targetType = targetType;
        }

        @Override
        public T convert(String source) {
            if (!StringUtils.hasText(source)) {
                return null;
            }
            return (T) EnumConvertFactory.getEnum(this.targetType, source);
        }
    }

    public static <T extends IEnum<?>> T getEnum(Class<T> targetType, String source) {
        for (T constant : targetType.getEnumConstants()) {
            if (source.equals(String.valueOf(constant.getValue()))) {
                return constant;
            }
        }
        return null;
    }
}

2.2.3.注册转换器

/**
 * 配置类,注册web层相关组件
 */
@Configuration
@Slf4j
public class WebMvcConfiguration extends WebMvcConfigurationSupport {
    @Autowired
    private EnumConvertFactory enumConvertFactory;

    /**
     * 注册自定义枚举类型转换器
     * @param registry
     */
    @Override
    protected void addFormatters(FormatterRegistry registry) {
        log.info("注册自定义枚举类型转换器...");
        registry.addConverterFactory(enumConvertFactory);
    }
}

三.案例测试

例如:条件分页查询话题类型

前端:

请求方式:Get

请求URL:/user/topic/page?page=1&pageSize=5&topicStatus=1

fab127d251f648c2afc1484a6f515fdb.png

后端:

f253c056823c41f983a771cac77444bb.png

例如:修改用户性别信息

前端:

请求方式:Put

请求URL:/user/info

1ec504460c2c45fead882f0af5b5f517.png

后端:

b416b4534dfc423fb39297c8dd31e050.png

 

 

 

MyBatis-Plus 是一个优秀的 MyBatis 增强工具,在实际开发中我们经常需要使用枚举类型来表示一些常量,如订单状态、性别等。而 MyBatis-Plus枚举类型的处理也非常方便,下面我来介绍一下如何使用 MyBatis-Plus 枚举字段映射。 1. 定义枚举类型 首先我们需要定义一个枚举类型,如下所示: ```java public enum StatusEnum { ENABLE(1, "启用"), DISABLE(0, "禁用"); private Integer value; private String desc; StatusEnum(Integer value, String desc) { this.value = value; this.desc = desc; } public Integer getValue() { return value; } public String getDesc() { return desc; } } ``` 2. 实体类中使用枚举类型 在实体类中使用枚举类型,如下所示: ```java public class User { private Long id; private String name; private StatusEnum status; // getter 和 setter 略 } ``` 3. 数据库表中使用枚举字段 在数据库表中使用枚举字段,如下所示: ```sql CREATE TABLE `user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL, `status` tinyint(4) NOT NULL COMMENT '状态:1=启用,0=禁用', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户表'; ``` 其中,`status` 字段类型为 `tinyint`,用于存储枚举类型的值。 4. 枚举字段映射MyBatis-Plus 中,我们可以使用 `@EnumValue` 和 `@EnumValue` 注解来进行枚举字段映射。具体使用方法如下: ```java public class User { private Long id; private String name; @EnumValue private StatusEnum status; // getter 和 setter 略 } ``` 在 `status` 字段上添加 `@EnumValue` 注解,表示该字段是枚举类型的值。 ```java public interface UserMapper extends BaseMapper<User> { } ``` 在 Mapper 中继承 `BaseMapper` 接口即可,无需做任何其他配置。 5. 查询操作 在查询操作时,MyBatis-Plus自动将数据库中存储的枚举类型的值映射为实体类中的枚举类型。例如: ```java User user = userMapper.selectById(1L); System.out.println(user.getStatus()); // 输出:ENABLE ``` 在上述代码中,MyBatis-Plus自动将数据库中的 `status` 字段的值 `1` 映射为实体类中的 `StatusEnum.ENABLE`。 6. 插入和更新操作 在插入和更新操作时,MyBatis-Plus自动将实体类中的枚举类型映射为数据库中的枚举类型的值。例如: ```java User user = new User(); user.setName("张三"); user.setStatus(StatusEnum.ENABLE); userMapper.insert(user); ``` 在上述代码中,MyBatis-Plus自动将实体类中的 `StatusEnum.ENABLE` 映射为数据库中的 `status` 字段的值 `1`。 综上所述,使用 MyBatis-Plus 枚举字段映射非常方便,只需要在实体类中添加 `@EnumValue` 注解即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

汤姆大聪明

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值