在大学写web应用的时候经常会遇到这么个问题,当我要插入一条数据,某个数据是Date类型,数据库中却是VARCHAR类型,这个时候可能会傻乎乎的先把这个数据自己手动转换成String类型再插入到数据库中,其实大可不必。MyBatis为我们提供了更好的方法即是TypeHandler来应对Java和jdbc字段类型不匹配的情况。MyBatis中内置了不少的TypeHandler,如果我们想要自己自定义一个TypeHandler可以实现TypeHandler接口,也可以继承BaseTypeHandler类。下面我们实现一个将Java中的Date类型利用我们自定义的ExampleTypeHandler来转换为JDBC的VARCHAR类型。

  我们对MyBatis的介绍先局限在使用,在会使用过后我们再究其原理、源码。

 package day_8_mybatis.util;

 import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date; import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType; /**
* 注意在引入Date所在的包时,是java.util.Date,而不是java.sql.Date,这一点不要搞错。
* @author turbo
*
* 2016年10月23日
*/
public class ExampleTypeHandler extends BaseTypeHandler<Date> { /* 根据列名,获取可以为空的结果
* @see org.apache.ibatis.type.BaseTypeHandler#getNullableResult(java.sql.ResultSet, java.lang.String)
*/
@Override
public Date getNullableResult(ResultSet rs, String columnName)
throws SQLException {
String sqlTimetamp = rs.getString(columnName);
if (null != sqlTimetamp){
return new Date(Long.valueOf(sqlTimetamp));
}
return null;
} /* 根据列索引,获取可以为空的结果
* @see org.apache.ibatis.type.BaseTypeHandler#getNullableResult(java.sql.ResultSet, int)
*/
@Override
public Date getNullableResult(ResultSet rs, int columnIndex)
throws SQLException {
String sqlTimetamp = rs.getString(columnIndex);
if (null != sqlTimetamp){
return new Date(Long.valueOf(sqlTimetamp));
}
return null;
} /* * @see org.apache.ibatis.type.BaseTypeHandler#getNullableResult(java.sql.CallableStatement, int)
*/
@Override
public Date getNullableResult(CallableStatement cs, int columnIndex)
throws SQLException {
String sqlTimetamp = cs.getString(columnIndex);
if (null != sqlTimetamp){
return new Date(Long.valueOf(sqlTimetamp));
}
return null;
} /* 设置非空参数
* @see org.apache.ibatis.type.BaseTypeHandler#setNonNullParameter(java.sql.PreparedStatement, int, java.lang.Object, org.apache.ibatis.type.JdbcType)
*/
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Date parameter,
JdbcType jdbcType) throws SQLException {
ps.setString(i, String.valueOf(parameter.getTime()));
} }

  我们已经自定义了一个TypeHandler,接着我们要在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>
<!-- 注意configuration中各个属性配置的顺序应为:properties,settings,typeAliases,typeHandlers,objectFactory,objectWrapperFactory,reflectorFactory,plugins,environments,databaseIdProvider,mappers)-->
<properties>
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="0000"/>
</properties>
<typeHandlers>
<typeHandler handler="day_8_mybatis.util.ExampleTypeHandler" javaType="java.util.Date" jdbcType="VARCHAR"/>
</typeHandlers> <environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="day_8_mybatis/mapper/UserMapper.xml"/>
<mapper resource="day_8_mybatis/mapper/NoteMapper.xml"/>
</mappers> </configuration>

  注意各个属性配置有顺序之分,不能随意穿插。

  准备工作已经做完了,我们接着按部就班的实现POJO类 Note里面包含id和date字段。

 package day_8_mybatis.pojo;

 import java.util.Date;

 /**
* @author turbo
*
* 2016年10月23日
*/
public class Note {
private int id;
private Date date;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
}

接着是负责与数据库交互Dao层的NoteMapper接口,我们只举例查询和插入。

 package day_8_mybatis.mapper;

 import day_8_mybatis.pojo.Note;

 /**
* @author turbo
*
* 2016年10月23日
*/
public interface NoteMapper {
Note queryNote(int id);
void insertNote(Note note);
}

  我们再来看看在NoteMapper.xml中是如何利用我们刚才自定义的TypeHandler。

 <?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="day_8_mybatis.mapper.NoteMapper">
<resultMap type="day_8_mybatis.pojo.Note" id="note-base">
<result property="id" column="id"/>
<result property="date" column="date" typeHandler="day_8_mybatis.util.ExampleTypeHandler"/>
</resultMap> <select id="queryNote" parameterType="int" resultMap="note-base">
select * from note where id = #{id}
</select>
<insert id="insertNote" parameterType="day_8_mybatis.pojo.Note">
insert into note (id, date) values(#{id}, #{date, typeHandler=day_8_mybatis.util.ExampleTypeHandler})  <!--使用我们自定义的TypeHandler-->
</insert>
</mapper>

  最后我们在客户端测试一下。

 package day_8_mybatis;

 import java.io.IOException;
import java.util.Date; import org.apache.ibatis.session.SqlSession; import day_8_mybatis.mapper.NoteMapper;
import day_8_mybatis.pojo.Note;
import day_8_mybatis.util.SessionFactory; /**
* 客户端
* @author turbo
*
* 2016年9月11日
*/
public class Main { /**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws Exception {
String resource = "day_8_mybatis/mybatis-config.xml"; //获取mybatis配置文件路径
SqlSession sqlSession = SessionFactory.getSqlSession(resource); //通过SessionFactory工具类(此工具类为自己构造即util包中的SessionFactory)构造SqlSession NoteMapper noteMapper = sqlSession.getMapper(NoteMapper.class); Note note = new Note();
note.setId(1);
note.setDate(new Date());
noteMapper.insertNote(note); //插入
sqlSession.commit(); //注意需要手动提交事务 note = noteMapper.queryNote(2); //查询
System.out.println(note.getDate());
} }

  注意在34行代码,需要手动提交事务,默认是关闭自动提交的,所以必须手动提交。开始没有提交事务,无论怎么都没办法插入到数据库,后来debug单步调试的时候发现了autoCommit=false,才想起来在以前大学的时候也遇到过这个这个问题所以一下就定位问题在哪儿了。

  数据库中只有一个note表,字段为id类型为int,date字段为varchar。

  至此我们就完成了自定义的TypeHandler,其实MyBatis为我们提供的TypeHandler已经不少了,不过我们还是自己试验一把,先把MyBatis学会使用,再究其原理。


这是一个能给程序员加buff的公众号

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的两个案例

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

  6. mybatis的typeHandler

    typeHandler作用: 1.传参时将javaType类型转换成jdbcType 2.结果集中ResultSet中取值时,jdbcType转换为javaType; 系统自定义的typeHandle ...

  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. python之字符串

    字符串与文本操作 字符串: Python 2和Python 3最大的差别就在于字符串 Python 2中字符串是byte的有序序列 Python 3中字符串是unicode的有序序列 字符串是不可变的 ...

  2. iOS 历史浏览网页的定向跳转

    在实际的开发过程中,涉及到交互的问题,原生和H5的网页相互嵌套,直接造成跳转的混乱,混乱就应该指定的历史记录中,就需要网页的一些相关的一些属性问题 需要在webview里面的代理方法中执行相对应的操作 ...

  3. ng自带的表单验证

    几点注意:使用ng的表单验证,需要给form,input,textarea一个name 要求:验证输入框的内容(长度,正则,必填,),当验证不通过的时候,就禁用提交按钮 使用的验证:ng-maxlen ...

  4. python 爬取w3shcool的JQuery的课程并且保存到本地

    最近在忙于找工作,闲暇之余,也找点爬虫项目练练手,写写代码,知道自己是个菜鸟,但是要多加练习,书山有路勤为径.各位爷有测试坑可以给我介绍个啊,自动化,功能,接口都可以做. 首先呢,我们明确需求,很多同 ...

  5. 测试开发Python培训:模拟登录新浪微博-技术篇

    测试开发Python培训:模拟登录新浪微博-技术篇   一般一个初学者项目的起点就是登陆功能的自动化,而面临的项目不同实现的技术难度是不一样的,poptest在做测试开发培训中更加关注技术难点,掌握技 ...

  6. Android中的java层的线程暂停和恢复实现

    /**  * 基础线程对象.  *  * @author jevan  * @version (1.0 at 2013-6-17)  * @version (1.1 at 2013-7-2) 增加on ...

  7. 循环神经网络RNN公式推导走读

    0语言模型-N-Gram 语言模型就是给定句子前面部分,预测后面缺失部分 eg.我昨天上学迟到了,老师批评了____. N-Gram模型: ,对一句话切词 我 昨天 上学 迟到 了 ,老师 批评 了 ...

  8. 【CSS】如何用css做一个爱心

    摘要:HTML的标签都比较简单,入门非常的迅速,但是CSS是一个需要我们深度挖掘的东西,里面的很多样式属性掌握几个常用的便可以实现很好看的效果,下面我便教大家如何用CSS做一个爱心. 前期预备知识: ...

  9. JDK8-十大新特性-附demo

    JDK原计划17年上半年就发版,但未成功发版.才发现JDK8的特性还没总结过,特此总结. 一.十大特性. 1.Lambda表达式 2.Stream函数式操作流元素集合 3.接口新增:默认方法与静态方法 ...

  10. MySQL最常用数值函数

    数值函数: 用来处理很多数值方面的运算,使用数值函数,可以免去很多繁杂的判断求值的过程,能够大大提高用户的工作效率. 1.ABS(x):返回 x 的绝对值 mysql> select abs(- ...