typeHandler作用:

  1.传参时将javaType类型转换成jdbcType

  2.结果集中ResultSet中取值时,jdbcType转换为javaType;

系统自定义的typeHandler:

  mybatis系统内部定义了一系列的typeHandler;基本涵盖了我们正常使用的类型转换;如下

选取一个系统自定义的typeHandler看看;

在包org.apache.ibatis.type下有一个StringTypeHandler.java

源码如下:

public class StringTypeHandler extends BaseTypeHandler<String> {

  @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 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);
}
}

StringTypeHandler继承了BaseTypeHandler;而BaseTypeHandler实现了接口TypeHandler,

BaseTypeHandler中代码

/**
* Copyright 2009-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ibatis.type; import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException; import org.apache.ibatis.executor.result.ResultMapException;
import org.apache.ibatis.session.Configuration; /**
* @author Clinton Begin
* @author Simone Tripodi
*/
public abstract class BaseTypeHandler<T> extends TypeReference<T> implements TypeHandler<T> { protected Configuration configuration; public void setConfiguration(Configuration c) {
this.configuration = c;
} @Override
public void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
if (parameter == null) {
if (jdbcType == null) {
throw new TypeException("JDBC requires that the JdbcType must be specified for all nullable parameters.");
}
try {
ps.setNull(i, jdbcType.TYPE_CODE);
} catch (SQLException e) {
throw new TypeException("Error setting null for parameter #" + i + " with JdbcType " + jdbcType + " . " +
"Try setting a different JdbcType for this parameter or a different jdbcTypeForNull configuration property. " +
"Cause: " + e, e);
}
} else {
try {
setNonNullParameter(ps, i, parameter, jdbcType);
} catch (Exception e) {
throw new TypeException("Error setting non null for parameter #" + i + " with JdbcType " + jdbcType + " . " +
"Try setting a different JdbcType for this parameter or a different configuration property. " +
"Cause: " + e, e);
}
}
} @Override
public T getResult(ResultSet rs, String columnName) throws SQLException {
T result;
try {
result = getNullableResult(rs, columnName);
} catch (Exception e) {
throw new ResultMapException("Error attempting to get column '" + columnName + "' from result set. Cause: " + e, e);
}
if (rs.wasNull()) {
return null;
} else {
return result;
}
} @Override
public T getResult(ResultSet rs, int columnIndex) throws SQLException {
T result;
try {
result = getNullableResult(rs, columnIndex);
} catch (Exception e) {
throw new ResultMapException("Error attempting to get column #" + columnIndex+ " from result set. Cause: " + e, e);
}
if (rs.wasNull()) {
return null;
} else {
return result;
}
} @Override
public T getResult(CallableStatement cs, int columnIndex) throws SQLException {
T result;
try {
result = getNullableResult(cs, columnIndex);
} catch (Exception e) {
throw new ResultMapException("Error attempting to get column #" + columnIndex+ " from callable statement. Cause: " + e, e);
}
if (cs.wasNull()) {
return null;
} else {
return result;
}
} 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; }

getResult分别用columnName和columnIndex从ResultSet中获取数据,CallableStatement表示从存储过程中获取结果及数据的方法;

下面我们创建自定义typeHandler

RoleMapper.java

package com.learn.charter2.mapper;

import java.util.List;

import com.learn.charter2.po.Role;

public interface RoleMapper {
Role getRole(Long id) throws Exception;
int deleteRole(Long id) throws Exception;
int insertRole(Role role) throws Exception;
List<Role> findRole(Role role) throws Exception;
}

Role.java

package com.learn.charter2.po;

public class Role {
private Long id;
private String roleName;
private String note;
private Integer pk; public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
public Integer getPk() {
return pk;
}
public void setPk(Integer pk) {
this.pk = pk;
} }

SqlSessionFactoryUtil.java

package com.learn.charter2.util;

import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger; import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder; public class SqlSessionFactoryUtil {
private static SqlSessionFactory sqlSessionFactory=null;
private static final Class class_lock=SqlSessionFactoryUtil.class;
private SqlSessionFactoryUtil() {
}
public static SqlSessionFactory initSqlSessionFactory(){
String resource="mybatis-config.xml";
InputStream inputStream=null;
try {
inputStream=Resources.getResourceAsStream(resource);
} catch (Exception e) {
Logger.getLogger(SqlSessionFactoryUtil.class.getName()).log(Level.SEVERE,null,e);
}
synchronized (class_lock) {
if(sqlSessionFactory==null){
sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
}
}
return sqlSessionFactory;
}
public static SqlSession openSqlSession(){
if(sqlSessionFactory==null){
initSqlSessionFactory();
}
return sqlSessionFactory.openSession();
}
}

log4j.properties

log4j.rootLogger=debug,stdout
log4j.logger.org.mybatis=debug
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p %d %C:%m%n

mybatis-config.xml

 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeHandlers>
<typeHandler handler="com.learn.charter2.util.MyStringTypeHandler" javaType="string" jdbcType="VARCHAR"/>
<typeHandler handler="com.learn.charter2.util.MyIntergerTypeHandler" javaType="int" jdbcType="VARCHAR"/>
</typeHandlers>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC">
<property name="autoCommit" value="false" />
</transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mybatis" />
<property name="username" value="root" />
<property name="password" value="gys" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/learn/charter2/mapper/roleMapper.xml" />
</mappers>
</configuration>

roleMapper.xml

 <?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="com.learn.charter2.mapper.RoleMapper"> <resultMap type="com.learn.charter2.po.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.learn.charter2.util.MyStringTypeHandler"/>
<result column="pk" property="pk" typeHandler="com.learn.charter2.util.MyIntergerTypeHandler"/>
</resultMap> <select id="getRole" parameterType="long" resultMap="roleMap">
select id,role_name as roleName,note from t_role where id=#{id}
</select> <select id="findRole" parameterType="com.learn.charter2.po.Role" resultMap="roleMap">
select id,role_name as roleName,note,pk from t_role
<where>
<if test="roleName !=null">
role_name like concat('%',#{roleName,javaType=string,jdbcType=VARCHAR,typeHandler=com.learn.charter2.util.MyStringTypeHandler},'%')
</if>
<if test="pk !=null">
and pk =#{pk,javaType=int,jdbcType=VARCHAR,typeHandler=com.learn.charter2.util.MyIntergerTypeHandler}
</if>
</where> </select> <insert id="insertRole" parameterType="com.learn.charter2.po.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>

MyIntergerTypeHandler.java

 package com.learn.charter2.util;

 import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException; import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import org.apache.ibatis.type.TypeHandler;
import org.apache.log4j.Logger; import sun.security.action.GetIntegerAction; /**
* @MappedTypes({Integer.class})
@MappedJdbcTypes(JdbcType.VARCHAR)
*
*/
public class MyIntergerTypeHandler implements TypeHandler<Integer> { private Logger log=Logger.getLogger(MyIntergerTypeHandler.class); private int getInt(String v){
if("a".equals(v)){
return 10;
}else if("b".equals(v)){
return 20;
}else if("c".equals(v)){
return 30;
}else{
return 60;
}
}
@Override
public Integer getResult(CallableStatement cs, int index)
throws SQLException {
log.info("使用我的IntegerTypeHandler,CallbleStatment下表获取字符串");
return getInt(cs.getString(index));
} @Override
public Integer getResult(ResultSet rs, int index) throws SQLException {
log.info("使用我的IntegerTypeHandler,ResultSet下标获取字符串");
return getInt(rs.getString(index));
} @Override
public Integer getResult(ResultSet rs, String colName) throws SQLException {
log.info("使用我的IntegerTypeHandler,ResultSet 列名获取字符串");
return getInt(rs.getString(colName));
} @Override
public void setParameter(PreparedStatement ps, int index, Integer value,JdbcType jt) throws SQLException {
log.info("使用我的IntegerTypeHandler==index:"+index+";value:"+value);
String v="";
if(value==1){
v="a";
}else if(value==2){
v="b";
}else if(value==3){
v="c";
}else {
v="guoyansi";
}
ps.setString(index, v);
}
}

MyStringTypeHandler.java

 package com.learn.charter2.util;

 import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException; import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import org.apache.ibatis.type.TypeHandler;
import org.apache.log4j.Logger; @MappedTypes({String.class})
@MappedJdbcTypes(JdbcType.INTEGER)
public class MyStringTypeHandler implements TypeHandler<String> {
private Logger log=Logger.getLogger(MyStringTypeHandler.class); @Override
public String getResult(CallableStatement cs, int index)
throws SQLException {
log.info("使用我的StringTypeHandler,CallbleStatment下表获取字符串");
return cs.getString(index);
} @Override
public String getResult(ResultSet rs, int index) throws SQLException {
log.info("使用我的StringTypeHandler,ResultSet下标获取字符串");
return rs.getString(index);
} @Override
public String getResult(ResultSet rs, String colName) throws SQLException {
log.info("使用我的StringTypeHandler,ResultSet 列名获取字符串");
return rs.getString(colName);
} @Override
public void setParameter(PreparedStatement ps, int index, String value,
JdbcType jt) throws SQLException {
value=value+"m";
log.info("使用我的StringTypeHandler==index:"+index+";value:"+value);
ps.setString(index, value);
} }

Charter2Main.java

 package com.learn.charter2.main;

 import java.util.List;

 import org.apache.ibatis.session.SqlSession;

 import com.learn.charter2.mapper.RoleMapper;
import com.learn.charter2.po.Role;
import com.learn.charter2.util.SqlSessionFactoryUtil; public class Charter2Main {
public static void main(String[] args) {
SqlSession sqlSession = null;
try {
sqlSession = SqlSessionFactoryUtil.openSqlSession();
RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
Role role = new Role();
role.setPk(10);
List<Role> list=roleMapper.findRole(role);
for(Role r:list){
System.out.println("id:"+r.getId()+";roleName:"+r.getRoleName()+";note:"+r.getNote()+";pk:"+r.getPk());
}
} catch (Exception e) {
System.err.println(e.getMessage());
sqlSession.rollback();
}finally{
if(sqlSession!=null){
sqlSession.close();
}
}
} }

自定义typeHandler的三个步骤:

1.定义typeHandler(MyIntergerTypeHandler.java     MyStringTypeHandler.java)

2.配置typeHandler(mybatis-config.xml中3-6行)

3.指定入参中哪个字段使用typeHandler(mapper.xml中19-24行)

4.指定出参中哪个字段使用typeHandler(mapper.xml中7-8行)

以MyIntergerTypeHandler为例,运行一下Charter2Main.java

Charter2Main 中传入的pk参数是10,被typeHandler默默的转换成了guoyansi;
因为guoyansi在数据库中找到了值,在被返回到java中,guoyansi又被typeHandler转化成了60;
这个例子展示的就是Integer和String之间的转换。

mybatis的typeHandler的更多相关文章

  1. Mybatis使用TypeHandler实现数据的加解密转换

    参考: MyBatis之TypeHandler: https://www.cnblogs.com/yulinfeng/p/5991170.html   前段时间收到这么个需求:为安全起见,要求在数据库 ...

  2. mybatis 枚举typeHandler

    枚举typeHandler 在绝大多数情况下,typeHandler因为枚举而使用,MyBatis已经定义了两个类作为枚举类型的支持,这两个类分别是: •EnumOrdinalTypeHandler. ...

  3. [转]Mybatis之TypeHandler使用教程

    Mybatis之TypeHandler使用教程 https://blog.csdn.net/jokemqc/article/details/81326109 深入浅出Mybatis系列(五)---Ty ...

  4. 使用Mybatis的TypeHandler加解密数据

    使用Mybatis的TypeHandler加解密数据 一.背景 二.解决方案 三.需求 四.实现思路 1.编写一个实体类,凡是此实体类的数据都表示需要加解密的 2.编写一个加解密的`TypeHandl ...

  5. MyBatis之TypeHandler

    在大学写web应用的时候经常会遇到这么个问题,当我要插入一条数据,某个数据是Date类型,数据库中却是VARCHAR类型,这个时候可能会傻乎乎的先把这个数据自己手动转换成String类型再插入到数据库 ...

  6. 关于mybatis中typeHandler的两个案例

    在做开发时,我们经常会遇到这样一些问题,比如我有一个Java中的Date数据类型,我想将之存到数据库的时候存成一个1970年至今的毫秒数,怎么实现?再比如我有一个User类,User类中有一个属性叫做 ...

  7. mybatis的TypeHandler 的使用

    今天看了别人的mybatis的教学视频,自己手写了一个简单的自定义的TypeHandler,有些细节记录一下. 1.定义自己的TypeHandler,代码如下: package com.example ...

  8. Mybatis自定义TypeHandler解决特殊类型转换问题

    我们知道,Java和MySQL中的数据类型是不同的,Java中除了基本数据类型,还有对象. 有时候使用MySQL存储数据,或者从MySQL中读取数据时,会有一些特殊需求

  9. 深入浅出Mybatis系列(五)---TypeHandler简介及配置(mybatis源码篇)

    上篇文章<深入浅出Mybatis系列(四)---配置详解之typeAliases别名(mybatis源码篇)>为大家介绍了mybatis中别名的使用,以及其源码.本篇将为大家介绍TypeH ...

随机推荐

  1. MinGW-w64安装教程——著名C/C++编译器GCC的Windows版本

    本文主要讲述如何安装 C语言 编译器——MinGW-w64,特点是文章附有完整详细的实际安装过程截图,文字反而起说明提示作用. 编写本文的原因始于我的一个观点:图片可以比文字传达更多的信息,也能让其他 ...

  2. unity中获取七天的日期

    private List<string> Date; private List<string> Day; private string now; private WMG_Axi ...

  3. 【转载】Oracle 中count(1) 、count(*) 和count(列名) 函数的区别

    1)count(1)与count(*)比较: 1.如果你的数据表没有主键,那么count(1)比count(*)快2.如果有主键的话,那主键(联合主键)作为count的条件也比count(*)要快3. ...

  4. vue初体验-ES6 基础知识补充 let 和const

    本人水平有限,如内容有误,欢迎指正,谢谢. let  : 主要特点: 1.作用域只局限于当前代码块.2.使用let 声明的变量作用域不会被提升.3.在相同的作用域下不能声明相同的变量.4.for循环体 ...

  5. 团队项目(MVP------新能源无线充电管理网站)(个人任务3)

    现在我们组的项目已经完成了,之前做的欢迎界面已经废弃掉了,于是我重新制作了一个欢迎界面,主要是分为了团队介绍,充电商品的介绍,现在充电新闻的发展,解决方案,成功案例.其中产品里面又有两个商品的售卖页, ...

  6. 改善Python程序的条条建议

    1:引论   建议1.理解Pythonic概念—-详见Python中的<Python之禅> 建议2.编写Pythonic代码 避免不规范代码,比如只用大小写区分变量.使用容易混淆的变量名. ...

  7. 【转载】 星际争霸2的AI环境搭建

    原文地址: https://blog.csdn.net/qq_40244666/article/details/80957644 作者:BOY_IT_IT 来源:CSDN -------------- ...

  8. javascript 运算符优先级

    JavaScript 运算符优先级(从高到低) https://github.com/xhlwill/blog/issues/16 今天把js函数转换为python 函数时,发现在js运算符优先级这边 ...

  9. linux基础之LSB定义的常用目录详解

    Linux基础之LSB定义的基本目录详解 1.LSB中FHS(Filesystem Hierarchy Standard)定义的一些文件 /boot:主要是存放引导文件的目录,比如内核文件(vmlin ...

  10. 2018.4.24 快排查找第K大

    import java.util.Arrays; /* 核心思想:利用快排思想,先假定从大到小排序,找枢纽,枢纽会把大小分开它的两边,当枢纽下标等于k时, 即分了k位在它左边或右边,也就是最大或最小的 ...