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

来源:互联网 发布:找物流专线软件 编辑:程序博客网 时间:2024/06/08 16:37

什么是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,转换为相应的数据格式。

原创粉丝点击