在和前端开发对接接口过程中经常发现需要一些枚举类的字典参数,虽然可以通过swagger在线文档给前端开发,不过可以直接返回枚举的编码和字典值就可以更直观,所以在项目里怎么实现?可以通过Mybatis的一些接口,自定义枚举类的处理器实现
环境准备
- 开发环境
- JDK 1.8
- SpringBoot2.2.1
- Maven 3.2
- 开发工具
- IntelliJ IDEA
- smartGit
- Navicat15
定义一个接口
先定义一个IEnum接口,@JsonFormat
格式为对象返回
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
,循环匹配
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类型
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
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"}