MyBatis之TypeHandler
在大学写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的更多相关文章
- Mybatis使用TypeHandler实现数据的加解密转换
参考: MyBatis之TypeHandler: https://www.cnblogs.com/yulinfeng/p/5991170.html 前段时间收到这么个需求:为安全起见,要求在数据库 ...
- mybatis 枚举typeHandler
枚举typeHandler 在绝大多数情况下,typeHandler因为枚举而使用,MyBatis已经定义了两个类作为枚举类型的支持,这两个类分别是: •EnumOrdinalTypeHandler. ...
- [转]Mybatis之TypeHandler使用教程
Mybatis之TypeHandler使用教程 https://blog.csdn.net/jokemqc/article/details/81326109 深入浅出Mybatis系列(五)---Ty ...
- 使用Mybatis的TypeHandler加解密数据
使用Mybatis的TypeHandler加解密数据 一.背景 二.解决方案 三.需求 四.实现思路 1.编写一个实体类,凡是此实体类的数据都表示需要加解密的 2.编写一个加解密的`TypeHandl ...
- 关于mybatis中typeHandler的两个案例
在做开发时,我们经常会遇到这样一些问题,比如我有一个Java中的Date数据类型,我想将之存到数据库的时候存成一个1970年至今的毫秒数,怎么实现?再比如我有一个User类,User类中有一个属性叫做 ...
- mybatis的typeHandler
typeHandler作用: 1.传参时将javaType类型转换成jdbcType 2.结果集中ResultSet中取值时,jdbcType转换为javaType; 系统自定义的typeHandle ...
- mybatis的TypeHandler 的使用
今天看了别人的mybatis的教学视频,自己手写了一个简单的自定义的TypeHandler,有些细节记录一下. 1.定义自己的TypeHandler,代码如下: package com.example ...
- Mybatis自定义TypeHandler解决特殊类型转换问题
我们知道,Java和MySQL中的数据类型是不同的,Java中除了基本数据类型,还有对象. 有时候使用MySQL存储数据,或者从MySQL中读取数据时,会有一些特殊需求
- 深入浅出Mybatis系列(五)---TypeHandler简介及配置(mybatis源码篇)
上篇文章<深入浅出Mybatis系列(四)---配置详解之typeAliases别名(mybatis源码篇)>为大家介绍了mybatis中别名的使用,以及其源码.本篇将为大家介绍TypeH ...
随机推荐
- [.NET] 一步步打造一个简单的 MVC 电商网站 - BooksStore(三)
一步步打造一个简单的 MVC 电商网站 - BooksStore(三) 本系列的 GitHub地址:https://github.com/liqingwen2015/Wen.BooksStore &l ...
- MongoDB基础教程系列--第三篇 MongoDB基本操作(二)
1.集合操作 1.1.创建集合 MongoDB 用 db.createCollection(name, options) 方法创建集合. 格式 db.createCollection(name, op ...
- 手机自动化测试:Appium代码之Logger
手机自动化测试:Appium代码之Logger poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.poptest推出手机自动化测 ...
- ajax 大洋与小样的第二步
一.Ajax的对象 XMLHttpRequest的方法 方法 描述 abort() 停止当前请求 getAllResponseHeaders() 把 HTTP请求的所有响应首部作为健/值对返回 get ...
- jQuery基础学习(二)—jQuery选择器
一.jQuery基本选择器 1.CSS选择器 在学习jQuery选择器之前,先介绍一下之前学过的CSS选择器. 选择器 语法 描述 示例 标签选择器 E { ...
- 01 The Learning Problem
什么时候适合用机器学习算法? 1.存在某种规则/模式,能够使性能提升,比如准确率: 2.这种规则难以程序化定义,人难以给出准确定义: 3.存在能够反映这种规则的资料. 所以,机器学习就是设计算法A,从 ...
- RabbitMQ-从基础到实战(6)— 与Spring集成
0.目录 RabbitMQ-从基础到实战(1)- Hello RabbitMQ RabbitMQ-从基础到实战(2)- 防止消息丢失 RabbitMQ-从基础到实战(3)- 消息的交换(上) Rabb ...
- 关于苹果真机 getFullYear()返回值为NAN的问题
问题描述: 在html页面中获得后台传过来的一个时间并显示在页面上,我用getFullYear() ,getMonth(),getDate()分别获得了年月日在电脑上和三星手机上页面都能正确的显示时间 ...
- css常用技巧集合
1 不想让按钮touch时有蓝色的边框或半透明灰色遮罩(根据系统而定) /*解决方式一*/ -webkit-tap-highlight-color:rgba(0,0,0,0); -webkit-use ...
- 解决IE6下 PNG图片有背景问题
IE6下有时候png格式的图片会存在背景的问题,以下是我常用的解决办法: <!--[if IE 6]> <script src="js/DD_belatedPNG_0.0. ...