Mybatis在预处理语句(PreparedStatement)中设置一个参数时,会用默认的typeHandler进行处理。

这句话是什么意思呢,当你想用姓名查询一个人的信息时

<select id="getRole" parameterType="string" resultRole="role">
select rolename,phonenumber from t_role where rolename = #{rolname}
</select>

Mybatis调用这个查询语句时会先生成预处理语句

select rolename,phonenumber from t_role where rolename = ?

这个‘?’也就是占位符里面应该填什么值呢?

这时候因为rolename是String类型的,rolename就会去找StringTypeHandler这个Mybatis自己已经实现的处理器

public class StringTypeHandler implements TypeHandler<String> {

	@Override
public void setParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, parameter);
} @Override
public String getResult(ResultSet rs, String columnName) throws SQLException {
return rs.getString(columnName);
} @Override
public String getResult(ResultSet rs, int columnIndex) throws SQLException {
return rs.getString(columnIndex);
} @Override
public String getResult(CallableStatement cs, int columnIndex) throws SQLException {
return cs.getString(columnIndex);
}
}

我们现在只需要看第一个方法,rolename看到这个方法就会知道,这个‘?’占位符原来应该填我自己。

结果集和存储过程同理。

假如Mybatis找不到类型的转换器就不知道该干嘛了,像下面这句代码

<insert id="addPerson" parameterType="person">
insert into people(id, name, phonenumber)
values(#{id}, #{name},#{phonenumber})
</insert>

phonenumber这个类是自己创建的,长这样:

private String countryCode;
private String stateCode;
private String number;
public PhoneNumber() {
}
// 021-3359-3216
public PhoneNumber(String str) {
String[] number = str.split("[-]");
this.countryCode = number[0];
this.stateCode = number[1];
this.number = number[2];
}
// 021,3359,3216
public PhoneNumber(String countryCode, String stateCode, String number) {
this.countryCode = countryCode;
this.stateCode = stateCode;
this.number = number;
}
public String getAsString() {
return countryCode + "-" + stateCode + "-" + number;
}
public String getCountryCode() {
return countryCode;
}
public void setCountryCode(String countryCode) {
this.countryCode = countryCode;
}
public String getStateCode() {
return stateCode;
}
public void setStateCode(String stateCode) {
this.stateCode = stateCode;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}

所以我们需要告诉Mybatis应该在预处理语句占位符中填什么,这时候就需要自己重新定义一个typeHandler.

public class PhoneTypeHandler extends BaseTypeHandler<PhoneNumber> {
//遇到PhoneNumber参数的时候应该如何在ps中设置值
//ps.setXXX()
@Override
public void setNonNullParameter(PreparedStatement ps, int i, PhoneNumber parameter, JdbcType jdbcType)
throws SQLException {
ps.setString(i, parameter.getAsString());
}
//查询中遇到PhoneNumber类型的应该如何封装(使用列名封装)
//stuedent.setTelPhone(new PhoneNumber("021-3359-3216"))
@Override
public PhoneNumber getNullableResult(ResultSet rs, String columnName) throws SQLException {
return new PhoneNumber(rs.getString(columnName));
}
//查询中遇到PhoneNumber类型的应该如何封装(使用列的下标)
@Override
public PhoneNumber getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return new PhoneNumber(rs.getString(columnIndex));
}
//CallableStatement使用中遇到了PhoneNumber类型的应该如何封装
@Override
public PhoneNumber getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return new PhoneNumber(cs.getString(columnIndex));
}
}

想试试的话,这里有代码。源码下载

Mybatis的类型处理器的更多相关文章

  1. MyBatis 示例-类型处理器

    MyBatis 提供了很多默认类型处理器,参考官网地址:链接,除了官网提供的类型处理器,我们也可以自定义类型处理器. 具体做法为:实现 org.apache.ibatis.type.TypeHandl ...

  2. mybatis枚举类型处理器

    1. 定义枚举值的接口 public abstract interface ValuedEnum { int getValue(); } 所有要被mybatis处理的枚举类继承该接口 2. 定义枚举类 ...

  3. mybatis由浅入深day01_6SqlMapConfig.xml(6.2settings全局参数配置_6.3typeAliases(类型别名)_6.4typeHandlers(类型处理器)_6.5mappers(映射配置))

    6 SqlMapConfig.xml mybatis的全局配置文件SqlMapConfig.xml,配置内容和顺序如下: properties(属性) settings(全局配置参数) typeAli ...

  4. MyBatis 源码分析——类型处理器

    官网上面讲到:无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时, 都会用类型处理器将获取的值以合适的方式转换成 Java 类型.那 ...

  5. 浩哥解析MyBatis源码(九)——Type类型模块之类型处理器注册器(TypeHandlerRegistry)

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6709157.html 1.回顾 上一篇研究的是类型别名注册器TypeAliasRegist ...

  6. 浩哥解析MyBatis源码(十)——Type类型模块之类型处理器

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6715063.html 1.回顾 之前的两篇分别解析了类型别名注册器和类型处理器注册器,此二 ...

  7. MyBatis源码解析(十)——Type类型模块之类型处理器TypeHandler

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6715063.html 1.回顾 之前的两篇分别解析了类型别名注册器和类型处理器注册器,此二 ...

  8. MyBatis源码解析(九)——Type类型模块之类型处理器注册器(TypeHandlerRegistry)

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6709157.html 1.回顾 上一篇研究的是类型别名注册器TypeAliasRegist ...

  9. mybatis学习系列五--插件及类型处理器

    2 插件编写(80-81) 单个插件编写 2.1实现interceptor接口(ibatis) invocation.proceed()方法执行必须要有,否则不会无法实现拦截作用 2.2 使用@int ...

随机推荐

  1. MVC+Nhibernate+spring.net(三)

    当前层次已经分好 分层架构 画的不是太好啊,后面我会上代码,大家先将就着看吧. 现在开始搭建spring 搭建spring首先引用类库文件: spring.AopSpring.Corespring.W ...

  2. MongoDB 无法创建抽象类的问题,

     无法创建抽象类BsonClassMap.RegisterClassMap 大家都知道抽象类是无法实例化的,即:不能new. 在以下这些情况会遇到这种问题: 1.基类是抽象类: 2.基类是接口: 由于 ...

  3. [SDOI2011]消耗战(虚树+树形动规)

    虚树dp 虚树的主要思想: 不遍历没用的的节点以及没用的子树,从而使复杂度降低到\(\sum\limits k\)(k为询问的节点的总数). 所以怎么办: 只把询问节点和其LCA放入询问的数组中. 1 ...

  4. C#连接Access2013

    今天测试连接Access2013数据库,遇到错误,综合几个大神建议,解决了 我的系统是windows 2008 64位的,连接字符串如下: <connectionStrings> < ...

  5. 设置iptables NAT出外网

    有时候云上部署环境,不能动态自设路由,没有公网ip地址的服务器,只能通过NAT的方式出外网,下面就记录一下设置过程. 当前状态 服务器A只有一个内网IP,不能上外网,内网IP与服务器B内网相通:服务器 ...

  6. javascript数据结构与算法---检索算法(二分查找法、计算重复次数)

    javascript数据结构与算法---检索算法(二分查找法.计算重复次数) /*只需要查找元素是否存在数组,可以先将数组排序,再使用二分查找法*/ function qSort(arr){ if ( ...

  7. odoo API装饰器one、model、multi的区别

    1.one装饰器详解 odoo新API中定义方式:    date=fields.Date(string="date",compute="_get_date") ...

  8. ActiveMQ新的Master/Slave存储共享机制Replicated LevelDB Store

    ActiveMQ新的Master/Slave存储共享机制Replicated LevelDB Store 使用ZooKeeper协调选择一个node作为master.被选择的master broker ...

  9. tabs高度自适应方法

    1.去掉easyui-tabs类属性,改为id=tabs 2.用js控制高度

  10. SingleThreadExecutor(单线程执行器)

    前要:一般的执行器会为每个任务单独创建线程,起码是分配单独的线程,即每个任务有其自己的线程.这样可以让任务并发执行.   问题:既然这样,为什么只用一个线程处理多个任务呢?     如果是这样,那一个 ...