mybatis的配置元素--typeHandler类型处理器

typeHandler源码分析可参考:http://www.cnblogs.com/dongying/p/4040435.html

typeHandler的作用:可以在bean对象的属性和数据库中存储的对象属性进行转换, 譬如bean中是list属性,存储到数据库中可以是array属性, bean中是java.util.Date属性,数据库中存储的是varchar类型的unix时间戳。

typeHandler 常用的配置为Java类型(javaType),JDBC类型(jdbcType). typeHandler 的作用就是将参数从javaType转化为jdbcType,或者从数据库取出结果时把jdbcType转化成javaType.

typeHandler和别名一样,分为Mybatis系统定义和用户自定义两种. 一般涞水,Mybatis系统定义就可以实现大部分的功能,如果使用用户自定义的typeHandler,我们处理时候务必小心谨慎,以避免不必要的错误.

系统定义的typeHandler

无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时,都会用类型处理器将获取的值以合适的方式转换成 Java 类型。Mybatis默认为我们实现了许多TypeHandler, 当我们没有配置指定TypeHandler时,Mybatis会根据参数或者返回结果的不同,默认为我们选择合适的TypeHandler处理。

mybatis中已经提供的有如下:

image

使用起来其实比较简单,只需要在resultMap中定义转换类型就可以了。表示在获取查询结果生成bean对象的时候,使用org.apache.ibatis.type.DateTypeHandler进行处理。

<mapper namespace="com.wang.MyBatis.model.UserMapper">
<!-- 自定义返回结果集 -->
   <resultMap id="userMap" type="com.wang.MyBatis.model.UserBean">
        <id property="id" column="id" javaType="java.lang.Integer"></id>
        <result property="username" column="username" javaType="java.lang.String"></result>
        <result property="password" column="password" javaType="java.lang.String"></result>
        <result typeHandler="org.apache.ibatis.type.DateTypeHandler" column="regTime" javaType="java.util.Date"
                jdbcType="VARCHAR"
                property="regTime"/>
    </resultMap>
    
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
    insert into t_user_timeStamp (username,password,regTime) values
    (#{username},#{password},#{regTime,typeHandler=org.apache.ibatis.type.DateTypeHandler})
</insert>

在插入和更新的时候自定使用
<update id="updateUser" >
  update t_user_timeStamp set username=#{username},password=#{password},regTime=
  #{regTime,typeHandler=org.apache.ibatis.type.DateTypeHandler} where id=#{id}
</update>   

#{regTime,typeHandler=org.apache.ibatis.type.DateTypeHandler}
表示在插入和更新regTime字段时,使用org.apache.ibatis.type.DateTypeHandler进行处理。
自定义typeHandler
配置typeHandler

<configuration>
    <typeHandlers>
      <!-- 
          当配置package的时候,mybatis会去配置的package扫描TypeHandler
          <package name="com.dy.demo"/>
       -->
      
      <!-- handler属性直接配置我们要指定的TypeHandler -->
      <typeHandler handler=""/>
      
      <!-- javaType 配置java类型,例如String, 如果配上javaType, 那么指定的typeHandler就只作用于指定的类型 -->
      <typeHandler javaType="" handler=""/>
      
      <!-- jdbcType 配置数据库基本数据类型,例如varchar, 如果配上jdbcType, 那么指定的typeHandler就只作用于指定的类型  -->
      <typeHandler jdbcType="" handler=""/>
      
      <!-- 也可两者都配置 -->
      <typeHandler javaType="" jdbcType="" handler=""/>
      
  </typeHandlers>
  
  ......
  
</configuration>

mybatis对于属性转换已经提供了较多的类,如果没有我们所需要的,可以自定义实现一个。属性转换类都实现接口类BaseTypeHandler<T>(package org.apache.ibatis.type;),并且需要实现其中的四个函数:

public abstract void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;

 public abstract T getNullableResult(ResultSet rs, String columnName) throws SQLException;

 public abstract T getNullableResult(ResultSet rs, int columnIndex) throws SQLException;

 public abstract T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException;

举例:

将map装换成字符串存储到数据库,取出时将字符串装换成map

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Map;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.codehaus.jackson.map.ObjectMapper;

import com.winturn.exceptions.RolerServiceException;
import com.winturn.utils.JsonMapUtil;
/**
 * 
* @ClassName: JsonMapTypeHandler 
* @Description: 将map装换成数组存储数据库,取出时将字符串装换成map
* @author sgl
* @date 2015年12月21日 下午6:22:50
 */
public class JsonMapTypeHandler extends BaseTypeHandler<Map<String, Object>> {

    ObjectMapper mapper = new ObjectMapper();

    @Override
    public Map<String, Object> getNullableResult(ResultSet rs, String columnName) {
        try {
            String value = rs.getString(columnName);
            return mapper.readValue(value, Map.class);
        } catch (Exception e) {

        }
        return null;
    }

    @Override
    public Map<String, Object> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        try {
            String value = rs.getString(columnIndex);
            return mapper.readValue(value, Map.class);
        } catch (Exception e) {

        }
        return null;
    }

    @Override
    public Map<String, Object> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        try {
            String value = cs.getString(columnIndex);
            return mapper.readValue(value, Map.class);
        } catch (Exception e) {

        }
        return null;
    }

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Map<String, Object> parameter, JdbcType jdbcType)
            throws SQLException {
        if (parameter == null) {
            ps.setNull(i, Types.VARCHAR);
        } else {
            try {
                ps.setString(i, JsonMapUtil.getJsonStrByMap(parameter));
            } catch (RolerServiceException e) {
                e.printStackTrace();
            }
        }

    }
}


自定义typeHandler 里用注解配置jdbcType和javaType.这两个注解是:
. @MappedTypes 定义的是javaType类型,可以指定那些java类型被拦截
. @MappedJdbcTypes 定义的是JdbcType类型,它需要满足枚举类org.apache.ibatis.type.JdbcType所列的枚举类型

至此我们还不能测试,我们还需要去标识哪些参数或者结果类型去用typeHandler进行转换,在没有任何标识的情况下,MyBatis是不会启用自定义的typeHandler进行转换结果的,所以还要给予对应的标识,比如配置jdbcType和javaType.,或者直接用typeHandler指定,因此我们需要修改映射器的XML配置.

<mapper namespace="com.wang.MyBatis.model.UserMapper">
    <!-- 自定义返回结果集 -->
   <resultMap id="userMap" type="com.wang.MyBatis.model.UserBean">
        <id property="id" column="id" javaType="java.lang.Integer"></id>
        <result property="username" column="username" javaType="java.lang.String"></result>
        <result property="password" column="password" javaType="java.lang.String"></result>
        <!--定义结果类型转换标识,才能使用类型转化器-->
        <result typeHandler="org.apache.ibatis.type.DateTypeHandler" column="regTime"  property="regTime" 
        javaType="java.util.Date" jdbcType="VARCHAR"/>
    </resultMap>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值