本文参考了网上文章,同时结合了自己的使用。

参考的文章: 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>


项目下载地址:

https://gitee.com/luckiness/SpringbootMybatisEnumDemo