typeHandler类型处理器作用
MyBatis在预处理语句(PreparedStatement)中设置一个参数时,或者从结果集(ResultSet)中取出一个值时,都会用注册了的typeHandler经行处理。
由于数据库可能来自于不同的厂商,不同的厂商设置的参数可能有所不同,同时数据库也可以自定义数据类型,typeHandler允许根据项目的需要自定义设置Java传递到数据库的参数中,或者从数据库读出数据,我们也需要进行特殊的处理,这些都可以在自定义的typeHandler中处理,尤其是在使用枚举的时候我们常常需要使用typeHandler进行转换。
typeHandler常用的配置为Java类型(javaType)、JDBC类型(jdbcType)。typeHandler的作用就是将参数从javaType转化为jdbcType,或者从数据库取出结果时把jdbcType转化为javaType。
typeHandler类型处理器用法
typeHandler和别名一样,分为MyBatis系统定义和用户自定义两种。一般来说,使用MyBatis系统定义就可以实现大部分功能。在本文中就不讲解MyBatis系统定义typeHandler用法,感兴趣的话,可以去看看org.apache.ibatis.type.TypeHandlerRegistry源码。
自定义typeHandler
自定义typeHandler前,首先需要明确两个问题:
- 现有的typeHandler能否满足使用的要求?
- 自定义的typeHandler需要处理什么类型【需特殊处理的Java类型(javaType)和对应处理数据库的类型jdbcType】?
第一步:注册自定义typehandler
<typeHandlers>
<!--自定义typeHandler类-->
<typeHandler jdbcType="VARCHAR" javaType="string" handler="com.demo.typeHandler.MyStringTypeHandler"/>
<!--也可以使用扫描注册-->
<package name="com.demo.typeHandler" />
</typeHandlers>
上述代码是配置在mybatis-config.xml配置文件中的。意味着通知系统,当Java的参数为string类型的时候,请使用自定义的MyStringTypeHandler类型处理器进行处理。
第二步:编写MyStringTypeHandler.java
@MappedType({String.class})
@MappedJdbcTypes(jdbgType.VARCHAR)
public class MyStringTypeHandler implements TypeHandler<String> {
private Logger log = Logger.getLogger(MyStringTypeHandler.class);
@Override
public void setParameter(PreparedStatement ps,int index,String value,JdbcType jt) throws SQLException {
log.info("使用自定义的TypeHandler")
ps.setString(index,value);
}
@Override
public String getResult(ResultSet rs,String colName) throws SQLException {
log.info("使用自定义的TypeHandler,ResultSet列名获取字符串");
return rs.getString(colName);
}
@Override
public String getResult(ResultSet rs,int index) throws SQLException {
log.info("使用自定义的TypeHandler,ResultSet下标获取字符串");
return rs.getString(index);
}
@Override
public String getResult(CallableStatement cs,int index) throws SQLException {
log.info("使用自定义的TypeHandler,CallableStatement下标获取字符串");
return cs.getString(index);
}
}
自定义的TypeHandler里使用注解配置JdbcType和JavaType。
@MappedType定义的是JavaType类型,可以指定哪些Java类型被拦截;@MappedJdbcType定义的是JdbcType类型,它需要满足枚举类org.apache.ibatis.type.JdbcType所列的枚举类型;
第三步:修改映射文件
<?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="这里填写mapper类的【实体类】的全路径限定名,列如com.demp.mapper.RoleMapper">
<resultMap type="role" id="roleMap">
<!--定义结果类型转化器标识,才能使用类型转换器-->
<id column="id" property="id" javaType="long" jdbcType="BIGINT" />
<result column="role_name" property="roleName" javaType="string" jdbcType="VARCHAR" />
<result column="note" property="note" typeHandler="com.demo.typeHandler.MyStringTypeHandler" />
</resultMap>
<select id="getRole" parameterType="long" resultMap="roleMap">
select id,role_name,note from t_role where id=#{id}
</select>
<select id="findRole" parameterType="string" resultMap="roleMap">
select id,role_name,note from t_role where role_name like concat('%',#{roleName javaType=string,jdbcType=VARCHAR,typeHandler=com.demo.typeHandler.MyStringTypeHandler},'%')
</select>
<insert id="insertRole" parameterType="role">
insert into t_role(role_name,note) values (#{roleName}.#{note})
</insert>
<delete id="deleteRole" parameterType="long">
delete from t_role where id=#{id}
</delete>
</mapper>
配置文件中引入了resultMap,它提供了映射规则,给出了3种typeHandler的使用方法。
- 在配置文件里配置,在结果集的roleName定义jdbcType和javaType。只有定义的jdbcType、javaType和用户自定义在配置里面的typeHandler是一致的,MyBatis才能够知道用自定义的类型转化器进行转换。
- 映射集里面直接定义具体的typeHandler,这样就不需要再在配置里面定义了。
- 在参数中制定typeHandler,这样MyBatis就会用对应的typeHandler进行转换。这样也不需要在配置里面定义了。
原创文章,作者:ZERO,如若转载,请注明出处:https://www.edu24.cn/course/mybatis-typehandler.html