自定义枚举 --- MyBatis字段映射
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义枚举 --- MyBatis字段映射相关的知识,希望对你有一定的参考价值。
参考技术A data-applicationContext.xmlps: 参考资料写得特别好,我之所以重新写了一下,是资料写得有点啰嗦,比如子类的注册,其实都是自动的,不需要再额外配置
Mybatis-自定义Enum映射
mybatis自定义Enum映射
前言
在使用mybatis作为orm映射时往往会涉及到枚举值的映射,如果mysql数据库中的数据使用的是enum类型,那么映射到系统中对应的值也应该是一个枚举字段,mybatis提供了枚举值的自动映射,分别是EnumTypeHandler和EnumOrdinalTypeHandler两个控制类来实现的,是针对的普通枚举来映射的,但是对于自定义的复杂枚举这两种根本就无法处理,需要自定义一个枚举类型控制器,如下将会详细介绍自定义枚举控制器的方法。
映射具体实现
程序准备
数据结构
CREATE TABLE `product` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT '',
`store` int(11) DEFAULT '0',
`sex` enum('M','F','N') DEFAULT NULL,
`is_enable` smallint(6) DEFAULT '0',
`utime` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`ctime` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
需要映射的实体类
package com.jesse.modules.test;
import com.jesse.modules.test.enums.EnableEnum;
import com.jesse.modules.test.enums.SexEnum;
import java.util.Date;
public class TestModel
private int id;
private String name;
private Integer store;
private Date utime;
private Date ctime;
private SexEnum sex;
private EnableEnum isEnable;
public Integer getStore()
return store;
public void setStore(Integer store)
this.store = store;
public Date getUtime()
return utime;
public void setUtime(Date utime)
this.utime = utime;
public Date getCtime()
return ctime;
public void setCtime(Date ctime)
this.ctime = ctime;
public int getId()
return id;
public void setId(int id)
this.id = id;
public String getName()
return name;
public void setName(String name)
this.name = name;
public SexEnum getSex()
return sex;
public void setSex(SexEnum sex)
this.sex = sex;
public EnableEnum getIsEnable()
return isEnable;
public void setIsEnable(EnableEnum enable)
isEnable = enable;
程序的枚举类
package com.jesse.modules.test.enums;
public enum SexEnum
M("Male","男"),
F("Female","女"),
N("None","未知");
private String sex;
private String type;
SexEnum(String sex,String type)
this.sex=sex;
this.type=type;
public String getSex()
return sex;
public void setSex(String sex)
this.sex = sex;
public String getType()
return type;
public void setType(String type)
this.type = type;
public enum EnableEnum
T(1,true),
F(2,false);
private int index;
private boolean type;
EnableEnum(int index,boolean type)
this.index=index;
this.type=type;
public int getIndex()
return index;
public void setIndex(int index)
this.index = index;
public boolean isType()
return type;
public void setType(boolean type)
this.type = type;
简单枚举映射
上面需要映射的有两中分别是SexEnum和EnableEnum,在处理时由于SexEnum是简单枚举,数据库值对应的就是java实体类的枚举名称,这种不需要自定义枚举,只需在mapper文件中指定typeHandler即可,如下的映射方法:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jesse.modules.test.dao.IDaoReader.ITestReader">
<resultMap id="BaseResultMap" type="com.jesse.modules.test.TestModel">
<id column="id" property="id" jdbcType="BIGINT" />
<result column="name" property="name" jdbcType="VARCHAR" />
<result column="store" property="store" jdbcType="INTEGER" />
<result column="utime" property="utime" jdbcType="TIMESTAMP"/>
<result column="ctime" property="ctime" jdbcType="TIMESTAMP" />
<result column="sex" property="sex" typeHandler="org.apache.ibatis.type.EnumTypeHandler"/>
<result column="is_enable" property="isEnable" javaType="com.jesse.modules.test.enums.EnableEnum"/>
</resultMap>
<sql id="Base_Column_List" >
id, name,store,utime,ctime,sex,is_enable
</sql>
<sql id="tableName">product</sql>
<sql id="where">
<where>
<if test="id!=null and id!=0">
id=#id
</if>
<if test="name!=null">
and name=#name
</if>
<if test="store!=null and store!=0">
and store=#store
</if>
<if test="utime !=null">
and ctime=#ctime
</if>
</where>
</sql>
<select id="getById" parameterType="com.jesse.modules.test.TestModel" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List"/>
FROM
<include refid="tableName"/>
<include refid="where"/>
</select>
</mapper>
使用EnumTypeHandler来自动将数据库的值映射到对应的java实体对象中,不需要自定义复杂实体映射。
复杂枚举映射
对于EnableEnum映射来说,程序就变得很复杂,首先数据库中存的枚举值既不是java枚举类中的索引,又不是java枚举类中的名称,这种EnumTypeHandler和EnumOrdinalTypeHandler都是无法处理的,这时候必须自定义一个复杂的枚举映射控制实现,并且要在mybatis中注册。具体实现方法如下。
添加自定义映射控制类
如下代码是自己添加的自定义的枚举映射控制类,主要实现思路是mybatis在加载时将数据库中的值作为枚举的索引,对应的枚举作为value,缓存到enums属性中,然后通过get获取到指定的枚举。
package com.jesse.modules.typeHandler;
import com.jesse.modules.test.enums.EnableEnum;
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;
import java.util.Hashtable;
public class EnumHandler<E extends EnableEnum> extends BaseTypeHandler<E>
private Class<E> type;
private final Hashtable<Integer,E> enums;
public EnumHandler(Class<E> type)
this.type=type;
E[] enums1=type.getEnumConstants();
enums=new Hashtable<Integer,E>();
for (E e : enums1)
enums.put(e.getIndex(),e);
@Override
public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException
ps.setInt(i,parameter.ordinal());
@Override
public E getNullableResult(ResultSet rs, String columnName) throws SQLException
int i=rs.getInt(columnName);
return enums.get(i);
@Override
public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException
int i=rs.getInt(columnIndex);
return enums.get(i);
@Override
public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException
int i=cs.getInt(columnIndex);
return enums.get(i);
mybatis配置
把下面的mybatis配置放到程序的resources下面的core文件夹中,命名为mybatis-config.xml。
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeHandlers>
<typeHandler handler="com.jesse.modules.typeHandler.EnumHandler" javaType="com.jesse.modules.test.enums.EnableEnum"/>
</typeHandlers>
</configuration>
对应的spring中的注解
<bean id="readerSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="readerDataSource"/>
<property name="mapperLocations" value="classpath*:mybatis/modules/**/reader/*Mapper.xml"/>
<property name="configLocation" value="classpath:core/mybatis-config.xml"/>
</bean>
结语
至此自定义映射部分,已经配置完成,完整的自定义映射需要将配置的控制器注册到对应的处理枚举类中,这就是mybatis-config.xml要做的,接下来运行程序,会自动将枚举值映射到java对象中,很方便。
以上是关于自定义枚举 --- MyBatis字段映射的主要内容,如果未能解决你的问题,请参考以下文章