Mybatis自定义枚举类处理器优雅地使用枚举

2023-05-26 16:55:24 浏览数 (1)

在和前端开发对接接口过程中经常发现需要一些枚举类的字典参数,虽然可以通过swagger在线文档给前端开发,不过可以直接返回枚举的编码和字典值就可以更直观,所以在项目里怎么实现?可以通过Mybatis的一些接口,自定义枚举类的处理器实现

环境准备

  • 开发环境
    • JDK 1.8
    • SpringBoot2.2.1
    • Maven 3.2
  • 开发工具
    • IntelliJ IDEA
    • smartGit
    • Navicat15

定义一个接口

先定义一个IEnum接口,@JsonFormat格式为对象返回

代码语言:javascript复制
package com.example.springboot.mybatis.common.enumhandler;
import com.fasterxml.jackson.annotation.JsonFormat;

@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public interface IEnum {
    String getCode();
    String getName();
}

枚举工具类

写一个枚举工具类,根据code和name返回对应枚举类,根据反射获取getEnumConstants,循环匹配

代码语言:javascript复制
package com.example.springboot.mybatis.common.enumhandler;


public class EnumUtils {

    public static <T extends Enum<?> & IEnum> T codeOf(Class<T> enumCls , String code) {
        T[] enumConstants = enumCls.getEnumConstants();
        for (T t : enumConstants) {
            if (t.getCode().equals(code)) return t;
        }
        return null;
    }

    public static <T extends Enum<?> & IEnum> T nameOf(Class<T> enumCls , String name) {
        T[] enumConstants = enumCls.getEnumConstants();
        for (T t : enumConstants) {
            if (t.getName().equals(name)) return t;
        }
        return null;
    }

}

自定义类型转换器

自定义Mybatis的类型转换器类,继承BaseTypeHandler,里面有几个需要实现的方法

  • void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) 用于定义设置参数时把Java类型的参数转换为对应的数据库类型
  • T getNullableResult(ResultSet rs, String columnName) 用于定义通过字段名称获取字段数据时把数据库类型转换为对应的Java类型
  • T getNullableResult(ResultSet rs, int columnIndex) 用于定义通过字段索引获取字段数据时把数据库类型转换为对应的Java类型
  • T getNullableResult(CallableStatement cs, int columnIndex) 用定义调用存储过程把数据库类型转换为对应的Java类型
代码语言:javascript复制
package com.example.springboot.mybatis.common.enumhandler;


import cn.hutool.core.lang.Assert;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class MybatisEnumCodeTypeHandler<E extends Enum<E> & IEnum> extends BaseTypeHandler<E>{

    private final Class<E> type;

    public MybatisEnumCodeTypeHandler(Class<E> type) {
        Assert.notNull(type , "type argument can not be null");
        this.type = type;
    }

    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, E e, JdbcType jdbcType) throws SQLException {
        preparedStatement.setString(i , e.getCode());
    }

    @Override
    public E getNullableResult(ResultSet resultSet, String s) throws SQLException {
        String code = resultSet.getString(s);
        return resultSet.wasNull() ? null : EnumUtils.codeOf(this.type , code);
    }

    @Override
    public E getNullableResult(ResultSet resultSet, int i) throws SQLException {
        String code = resultSet.getString(i);
        return resultSet.wasNull() ? null : EnumUtils.codeOf(this.type , code);
    }

    @Override
    public E getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        String code = callableStatement.getString(i);
        return callableStatement.wasNull() ? null : EnumUtils.codeOf(this.type , code);
    }
}

yaml配置类型处理器

application.yml里配置default-enum-type-handler,加上自定义的MybatisEnumCodeTypeHandler

代码语言:javascript复制
mybatis:
    # 指定sql映射文件位置
    mapper-locations: classpath:mybatis/mapper/*.xml
    configuration:
      default-enum-type-handler: com.example.springboot.mybatis.common.enumhandler.MybatisEnumCodeTypeHandler
      map-underscore-to-camel-case: true

项目中使用

需要的枚举类就继承IEnum接口

代码语言:javascript复制
package com.example.springboot.mybatis.bean;


import com.example.springboot.mybatis.common.enumhandler.IEnum;

public enum  Sex implements IEnum {

    MAN("1","男"),
    WOMAN("2","女");

    private String code;
    private String name;

    Sex(String code, String name) {
        this.code = code;
        this.name = name;
    }


    @Override
    public String getCode() {
        return code;
    }

    @Override
    public String getName() {
        return name;
    }
}

写个接口,参数返回json:

代码语言:javascript复制
{"userId":"1","username":"admin","sex":{"code":"1","name":"男"},"password":"11"}

0 人点赞