本文参考了网上文章,同时结合了自己的使用。
参考的文章: https://blog.csdn.net/u014527058/article/details/62883573
需要枚举类型转换的过程
1. 前台提交的数据(如从form表单提交的数据) -> controller参数(如实体类)
2. 实体类 -> 数据库 (该过程通常发生在Dao层)
3. 数据库 -> 实体类 (该过程通常发生在Dao层)
实体类
package com.entity; import com.enumeration.Level; /** * 用户 */ public class User {// get、set方法省略 private String id; private String name; // 名字 private Level level; // 等级 }
枚举
package com.enumeration; public enum Level implements BaseEnum{ ORDINARY(1, "普通会员"), GOLDEN(2, "黄金会员"); private Integer value; // 值 private String description; // 描述 private Level(int value, String description) { this.value = value; this.description = description; } @Override public Integer getValue() { return value; } public String getDescription() { return description; } }
package com.enumeration; public interface BaseEnum { Integer getValue(); }
1.前台提交的数据 -> controller参数
package com.converter; import java.util.HashMap; import java.util.Map; import java.util.WeakHashMap; import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.ConverterFactory; import com.enumeration.BaseEnum; /** * 枚举类型转换 */ public class BaseEnumConverterFactory implements ConverterFactory<String, BaseEnum> { @SuppressWarnings("rawtypes") private static final Map<Class, Converter> converterMap = new WeakHashMap<>(); @SuppressWarnings({ "rawtypes", "unchecked" }) @Override public <T extends BaseEnum> Converter<String, T> getConverter(Class<T> targetType) { Converter result = converterMap.get(targetType); if(result == null) { result = new IntegerStrToEnum<T>(targetType); converterMap.put(targetType, result); } return result; } class IntegerStrToEnum<T extends BaseEnum> implements Converter<String, T> { @SuppressWarnings("unused") private final Class<T> enumType; private Map<String, T> enumMap = new HashMap<>(); public IntegerStrToEnum(Class<T> enumType) { this.enumType = enumType; T[] enums = enumType.getEnumConstants(); for(T e : enums) { enumMap.put(e.getValue() + "", e); } } @Override public T convert(String source) { T result = enumMap.get(source); if(result == null) { throw new IllegalArgumentException("No element matches " + source); } return result; } } }
注册ConverterFactory
package com.config; import org.springframework.context.annotation.Configuration; import org.springframework.format.FormatterRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import com.converter.BaseEnumConverterFactory; /** * mvc 配置 */ @Configuration public class WebAppConfigurer implements WebMvcConfigurer { @Override public void addFormatters(FormatterRegistry registry) { // 注册ConverterFactory(类型转换器工厂) registry.addConverterFactory(new BaseEnumConverterFactory()); } }
前台传递参数
<form method="post" th:action="@{/user}"> <h2>添加用户</h2> <div> <label for="name">用户名字</label> <input type="text" id="name" name="name" placeholder="名字"> </div> <div> <label>用户等级</label> <label><input type="radio" name="level" value="1" checked>普通会员</label> <label><input type="radio" name="level" value="2">黄金会员</label> </div> <div> <input type="submit" value="添加" /> </div> </form>
controller接收参数
/** * 添加用户 * * @param user * @return */ @RequestMapping(method = RequestMethod.POST) public String Add(User user) { // 代码省略 }
2.实体类 -> 数据库
类型转换实现类
package com.typeHandler; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType; import com.enumeration.BaseEnum; public class BaseEnumTypeHandler<E extends BaseEnum> extends BaseTypeHandler<E> { private Class<E> enumType; private Map<Integer, E> enumMap = new HashMap<>(); public BaseEnumTypeHandler(Class<E> type) { if (type == null) throw new IllegalArgumentException("Type argument cannot be null"); this.enumType = type; E[] enums = enumType.getEnumConstants(); if (enums == null) throw new IllegalArgumentException(type.getSimpleName() + " does not represent an enum type."); for (E e : enums) { enumMap.put(e.getValue(), e); } } @Override public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException { ps.setInt(i, parameter.getValue()); } @Override public E getNullableResult(ResultSet rs, String columnName) throws SQLException { return get(rs.getInt(columnName)); } @Override public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException { return get(rs.getInt(columnIndex)); } @Override public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { return get(cs.getInt(columnIndex)); } private E get(Integer v) { if (v == null) { return null; } return this.enumMap.get(v); } }
mapper文件中对应枚举的字段要指定typeHandler,如
<insert id="insert" parameterType="com.entity.User"> <selectKey keyProperty="id" resultType="String" order="BEFORE"> SELECT UUID() </selectKey> INSERT INTO user (id, name, level) VALUES (#{id,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{level,jdbcType=INTEGER,typeHandler=com.typeHandler.BaseEnumTypeHandler} ) </insert>
3.数据库 -> 实体类
类型转换实现类和2中一致。
mapper文件中,对应枚举的字段要指定javaType和typeHandler,如
<resultMap id="UserResultMap" type="com.entity.User"> <id column="id" jdbcType="VARCHAR" property="id" /> <result column="name" jdbcType="VARCHAR" property="name" /> <result column="level" jdbcType="INTEGER" property="level" javaType="com.enumeration.Level" typeHandler="com.typeHandler.BaseEnumTypeHandler" /> </resultMap> <select id="findAll" resultMap="UserResultMap"> SELECT * from USER </select>
项目下载地址: