在大学写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. C#调用webbrowser,阻止弹出新IE窗口

    本人是用WPF内嵌 winform的webbrowser这种形式开发, 弹出的 //屏蔽弹出新IE窗口 private void webBrowser_NewWindow(object sender, ...

  2. Python之路-Linux命令基础(2)

    作业一: 1)    新建用户natasha,uid为1000,gid为555,备注信息为"master" 2)    修改natasha用户的家目录为/Natasha 3)    ...

  3. 手机自动化测试:Appium源码分析之跟踪代码分析六

    手机自动化测试:Appium源码分析之跟踪代码分析六   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.poptest推出手机自 ...

  4. (转)Java并发编程:并发容器之ConcurrentHashMap

    下面这部分内容转载自: http://www.haogongju.net/art/2350374 JDK5中添加了新的concurrent包,相对同步容器而言,并发容器通过一些机制改进了并发性能.因为 ...

  5. 重写NSArray与NSDictionary的descriptionWithLocale方法

    重写NSArray的descriptionWithLocale方法: NSArray+log.h #import <Foundation/Foundation.h> @interface ...

  6. JavaScript高级程序设计---学习笔记(四)

    1.全局变量不能通过delete操作符删除,而直接在window对象上定义的属性可以. var age = 29; window.color = "red"; delete age ...

  7. mac下安装Java开发环境

    1.安装JDK 打开网页,进入jdk官网下:http://www.oracle.com/technetwork/java/javase/downloads/index.html 下载后,进入finde ...

  8. PHP 魔术方法 __call 与 __callStatic 方法

    PHP 魔术方法 __call 与 __callStatic 方法 PHP 5.3 后新增了 __call 与 __callStatic 魔法方法. __call 当要调用的方法不存在或权限不足时,会 ...

  9. 自定义input默认placeholder样式

    input::input-placeholder { color: #fb4747; } input::-webkit-input-placeholder { color: #fb4747; } in ...

  10. PHP原生DOM对象操作XML'代码'

    对于操作XML类型文件,PHP内置有一套DOM对象可以进行处理.对XML的操作,从创建.添加到修改.删除都可以使用DOM对象中的函数来进行. 创建 创建一个新的XML文件,并且写入一些数据到这个XML ...