mybatis之自定义TypeHandler
typehandler有什么用?
首先来讨论下mybatis sql查询回来的结果集如何封装pojo类。在jdbc里,查询回来的结果集是封装在ResultSet里,需要映射成相应的实体类。
mybatis配置里提供了两种方式,提供给我们做结果集的转换
-
resultType:pojo类与结果集里的字段名必须一样(经过简单的处理后一样,比如去除表字段中的下划线,或大小写转换)
<select id="selectBook" resultType="book"> select * from book where id = #{id} </select>
-
resultMap:必须指定每个字段的java类型和jdbc类型,mybatis里有对应的typehandler去处理
<select id="selectBook" resultMap="BaseResultMap"> select * from book where id = #{id} </select>
mybatis已经内置了常见字段类型的转换,通常我们使用默认的typehandler就可以了。
但是有些字段转换的时候我们需要做一些特殊的处理,这时我们就需要自定义typehandler
自定义TypeHandler
可以直接实现TypeHandler,但是要转换时要考虑parameter和jdbcType为null的情况;另外也可以直接继承BaseTypeHandler,BaseTypeHandler也是TypeHandler的一个实现,它里面对一些常见的异常情况做了处理。
public class MyTypeHandler extends BaseTypeHandler<String> { private static final String SAN_GUO = "三国"; @Override public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException { ps.setString(i,parameter); } @Override public String getNullableResult(ResultSet rs, String columnName) throws SQLException { return filter(rs.getString(columnName)) ; } @Override public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException { return filter(rs.getString(columnIndex)); } @Override public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { return filter(cs.getString(columnIndex)); } private String filter(String s){ String result; int index = s.indexOf(SAN_GUO); //书名包括三国两个字的时候,将三国过滤掉 if ( s.indexOf(SAN_GUO) != -1 ){ result = s.substring(index+2); } else { result = s; } return result; } }
这里对书名做了简单的过滤处理,实现完成后,还需要在resultMap里配置
<resultMap id="BaseResultMap" type="com.allen.springbootmybatis.entity.Book"> <!--@Table book--> <result property="id" column="id" jdbcType="INTEGER" /> <result property="name" column="name" jdbcType="VARCHAR" typeHandler="com.allen.springbootmybatis.util.MyTypeHandler"/> <result property="author" column="author" jdbcType="VARCHAR"/> </resultMap>
之后的查询结果,书名包含【三国】这两个字的都会被截取掉。