Mybatis中的typehandler 自定义数据转换储存读取

什么是TypeHandler?

在mapper,xml中,我们可能见过这种写法:

is_completed = #{isCompleted,typeHandler=cn.web.common.typehandler.String2IntTypeHandler}

我们知道正常的写法后面跟的是jdbctype 例如:

<update id="deleteClass" parameterType="java.lang.String">
        DELETE FROM aim_class_t WHERE class_code = #{value,jdbcType=VARCHAR}
</update>

TypeHandler的作用

1.例如当你存入List类型数据导数据库,自动转换为varchar类型,并且List中的每个元素间用“,”分割开
2.又例如当你读取varchar类型的数据,将读取结果自动转换为List,以每个“,”分割
3.它的作用不仅仅是这些,他主要的作用是在数据库和java中间操作数据格式

TypeHandler的配制与使用

使用TypeHandler的两种方式

  1. 实现TypeHandler接口
  2. 继承BaseTypeHandler类

举一个工作中遇到的例子,采用了继承BaseTypeHandler类的方法:

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
@MappedTypes(String.class)             //定义了被拦截的Java类型
@MappedJdbcTypes(JdbcType.INTEGER)    //必须要是枚举类org.apache.ibatis.type.JdbcType所枚举的数据类型
public class String2IntTypeHandler extends BaseTypeHandler<String> {

    @Override
    public String getNullableResult(ResultSet rs, String columnName)
            throws SQLException {
        return rs.getString(columnName);

    @Override
    public String getNullableResult(ResultSet rs, int columnIndex)
            throws SQLException {
        return rs.getString(columnIndex);
    }

    @Override
    public String getNullableResult(CallableStatement cs, int columnIndex)
            throws SQLException {
        return cs.getString(columnIndex);
    }

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i,
            String parameter, JdbcType jdbcType) throws SQLException {
        if (parameter!=null&&parameter.length()>0)
                    ps.setInt(i, Integer.parseInt(parameter));
        else 
            ps.setNull(i, Types.INTEGER);
    }
}

当我们调用这个TypeHandler之后,对数据库的操作都会经过此方法,类似于过滤器一样,在setNonNullParameter方法中重写需要写入数据库的数据,其他的为读取转换。

上面完成了读取写入的转换重写,下面就是在xml中具体的配置了

<insert id="addCourse" parameterType="AmcCourse">
        INSERT INTO amc_course_base_t (
        course_code,
        course_title,
        course_logo,
        course_score,
        content_type_id,
        course_kind_id,
        course_keywords,
        course_desc,
        std_fee
        )
        VALUES
        (
        #{courseCode,jdbcType=VARCHAR},
        #{courseTitle,jdbcType=VARCHAR},
        #{courseLogo,jdbcType=VARCHAR},
        #{courseScore,typeHandler=cn.aim.web.typehandler.String2FloatTypeHandler},  
        #{contentTypeId,typeHandler=cn.aim.web.typehandler.String2IntTypeHandler},
        #{courseKindId,typeHandler=cn.aim.web.typehandler.String2IntTypeHandler},
        #{courseKeywords,jdbcType=VARCHAR},
         #{courseDesc,jdbcType=VARCHAR},
        #{stdFee,typeHandler=cn.aim.web.typehandler.String2IntTypeHandler},
        )

    </insert>

在上面的代码中我们可以看出,其中几个字段将原本的jdbcType替换成了typeHandler,值也由JdbcType所枚举的数据类型,改为了刚刚我们配置的TypeHandler类,说明一点 每个表达式中都可以同时写javaType,jdbcType和TypeHandler,也可以只写一个

读取数据也可以在resultMap中配置,举个例子:

<resultMap id="String2IntTypeHandler" type="cn.aim.web.entity.CourseEntity">
        <result typeHandler="cn.aim.web.typehandler.String2IntTypeHandler" column="content_type_id" javaType="java.lang.String"
                jdbcType="Int"
                property="contentTypeId"/>
    </resultMap>

这样写的弊端在于只对返回此resultMap的查询语句有效。

最后在Mybatis的config文件中配置

<!--启动时会扫描包下的所有文件-->
<typeHandlers>
        <package name="cn.aim.web.typehandler"/>
</typeHandlers>


<!--或单个写入要注册的TypeHandler-->
<typeHandlers>
        <typeHandler handler="cn.aim.web.typehandler.String2IntTypeHandler"/>
</typeHandlers>

总结

总的来说TypeHandler可以理解为java于Mybatis中间的过滤器,不论是写入也好,读取也罢,数据经过注册、配置后的TypeHandler,转换为相应的数据格式。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值