在大学写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. Django后台设置--遇到的问题与解决方案

    1. 后台如何管理项目中的models 新建的Django工程会自动引用admin 应用,新建后台可以通过 createsuperuser 命令建立后台admin超级管理员,我遇到的第一个问题,就是如 ...

  2. MyBatis使用statementType="STATEMENT"

    statementType="STATEMENT"是使用非预编译,现在我需要动态传人表名和字段名,所以需要用STATEMENT,使用之后所有变量取值都要改成${xxxx},而不是# ...

  3. 6、CC2541修改按键调节广播发送功率例程为持续发送4DB的蓝牙基站

    一.目的 在 OSAL操作系统-实验31 从机广播功率修改-(20141029更新).zip 基础上进行修改,该工程是通过5向按键的上下按键来控制广播功率的加减,总共有4个档位.我们的目的是直接用最高 ...

  4. Java--JDBC连接数据库

         我们知道Java中的jdbc是用来连接应用程序和数据系统的,本篇文章主要就来看看关于JDBC的实现和使用细节.主要包含以下几点内容: JDBC的基本知识(数据驱动程序) JDBC的连接配置 ...

  5. 老李回答:JAVA程序的性能测试方法

    Java 1.5以上都在虚拟机里内建了程序性能跟踪的功能,并提供了Java Profiling API,简称JPA,你可以搜索'java profiling'.Java也提供了简单的性能性能跟踪工具J ...

  6. 5.Redis常用命令:Hash

    我们可以将Redis中的Hashes类型看成具有String Key和String Value的map容器.所以该类型非常适合于存储值对象的信息.如Username.Password和Age等.如果H ...

  7. 在多个Activity中回传值(startActivityForResult())

    业务逻辑: MainActivity打开A,A打开B,B把值传回MainActivity.适用在多个Activity中回传值. 实例:微信中选择国家-->省份-->城市的实现 实现方式分析 ...

  8. javascript数组常用方法详解

    1,splice().   array.splice(index,many,list1,list2....)  参数1.index位置 负数为从结尾处算,倒数第一为-1:参数2,many要删除的项目, ...

  9. grid实例(Asp.net)

    <link href="../../js/jqGrid/css/ui.jqgrid.css" rel="stylesheet" type="te ...

  10. kvc模式详解

    java利用反射机制访问类的 私有变量.OC的KVC模式也是一样,用来访问私有变量用的. 用字符串去访问对象实例变量的机制. //KVC模式-(void)KVCtest{ [_dm valueForK ...