MyBatis自定义类型处理器(typeHandler)
MyBatis自定义类型处理器(typeHandler)
我们执行sql
语句通过PreparedStatement
语句实现,PreparedStatement
会设置?
值,类型处理器帮PreparedStatement
找到对应的set
方法,到底是选择setInt
、setString
或setDate...
注意:类型处理器默认可以处理基本的数据类型以及对应的包装类,uitl.Date、sql.Date
等,但无法默认处理自定义类型。
当MyBatis
将一个Java
对象作为输入参数执行INSERT
语句操作时,它会创建一个PreparedStatement
对象,并且使用setXXX()
方法对占位符设置相应的参数值。这里,XXX
可以是Int
,String
,Date
等Java
对象属性类型的任意一个。示例如下:
<insert id="insertStudent" parameterType="Student"> INSERT INTO STUDENTS(STUD_ID,NAME,EMAIL,DOB) VALUES(#{studId},#{name},#{email},#{dob})
</insert>
为了执行这个语句,MyBatis
将采取以下一系列动作:
创建一个有占位符的PreparedStatement接口,如下:
PreparedStatement ps = connection.prepareStatement("INSERT INTO STUDENTS(STUD_ID,NAME,EMAIL,DOB) VALUES(?,?,?,?)");
检查Student
对象的属性studId
的类型,然后使用合适setXXX()
方法去设置参数值。这里studId
是Integer
类型,所以会使用setInt()
方法:
ps.setInt(1,student.getStudId());
类似地,对于name
和email
属性都是String
类型的,MyBatis
使用setString()
方法设置参数。
至于dob
属性, MyBatis
会使用setDate()
方法设置dob
处占位符位置的值。MyBaits
会将java.util.Date
类型转换为java.sql.Timestamp
并设值:
ps.setTimestamp(4, new Timestamp((student.getDob()).getTime()));
但MyBatis
是怎么知道对于Integer
类型属性使用setInt()
和String
类型属性使用setString()
方法呢?其实MyBatis
是通过使用类型处理器typeHandlers
来决定这么做的。
MyBatis
对于以下的类型使用内建的类型处理器:所有的基本数据类型、基本类型的包装类型、byte[]
、java.util.Date
、java.sql.Date
、java,sql.Time
、java.sql.Timestamp
、java枚举类型
等。所以当MyBatis
发现属性的类型属于上述类型,他会使用对应的类型处理器将值设置到PreparedStatement
中,同样地,当SQL
结果集封装成java
类对象的时候,也有类似的过程。
那如果有一个自定义的类型,怎么存储存储到数据库呢?示例如下:假设表STUDENTS
有一个 PHONE
字段,类型为 VARCHAR2(15)
,而 Student
类有一个自定义类型PhoneNumber
,这个类型包括三个属性:国家编号、区号、电话号码。
public class PhoneNumber{ private String countryCode; private String stateCode; private String number; public PhoneNumber(){ } public PhoneNumber(String countryCode, String stateCode, String number) { this.countryCode = countryCode; this.stateCode = stateCode; this.number = number; } public String getAsString() { return countryCode + "-" + stateCode + "-" + number; } // Setters and getters
} public class Student{ private Integer id; private String name; private String email; private PhoneNumber phone; // Setters and getters
}
StudentMapper.xml
配置如下:
<insert id="insertStudent" parameter Type="Student"> insert into students(name,email,phone) values(#{name},#{email},#{phone})
</insert>
这个xml
文件里面,参数对象中的属性phone
的值需要传递给#{phone}
,而参数对象的属性phone
是 PhoneNumber
类型。但是,MyBatis
并不知道该怎样来处理这个类型的对象。为了让MyBatis
明白怎样处理这个自定义的Java
对象类型,如PhoneNumber
,我们可以创建一个自定义的类型处理器,MyBatis
提供了抽象类BaseTypeHandler<T>
,我们可以继承此类创建自定义类型处理器。代码如下:
package com.au.typehandlers;import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;import com.briup.pojo.PhoneNumber;public class PhoneTypeHandler extends BaseTypeHandler<PhoneNumber>{//遇到PhoneNumber参数的时候应该如何在ps中设置值@Overridepublic void setNonNullParameter(PreparedStatement ps, int i, PhoneNumber parameter, JdbcType jdbcType)throws SQLException {ps.setString(i, parameter.getAsString());}//查询中遇到PhoneNumber类型的应该如何封装(使用列名封装)@Overridepublic PhoneNumber getNullableResult(ResultSet rs, String columnName) throws SQLException {return new PhoneNumber(rs.getString(columnName));}//查询中遇到PhoneNumber类型的应该如何封装(使用列的下标)@Overridepublic PhoneNumber getNullableResult(ResultSet rs, int columnIndex) throws SQLException {return new PhoneNumber(rs.getString(columnIndex));}//CallableStatement使用中遇到了PhoneNumber类型的应该如何封装@Overridepublic PhoneNumber getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {return new PhoneNumber(cs.getString(columnIndex));}}
注意:使用ps.setString()
和rs.getString()
方法是因为在数据库的表中phone
列是VARCHAR
类型。
最后需要在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> <properties resource="application.properties" /> <typeHandlers> <typeHandler handler="com.au.typehandlers.PhoneTypeHandler" /> </typeHandlers>
</configuration>
注册PhoneTypeHandler
后,MyBatis
就能够将Phone
类型的对象值存储到VARCHAR
类型的列上。
MyBatis自定义类型处理器(typeHandler)相关推荐
- MyBatis自定义类型处理器 TypeHandler
在项目开发中经常会遇到一个问题: 当我们在javabean中自定义了枚举类型或者其它某个类型,但是在数据库中存储时往往需要转换成数据库对应的类型,并且在从数据库中取出来时也需要将数据库类型转换为jav ...
- 【Mybatis】类型处理器TypeHandler的作用与自定义
一.什么是类型处理器 1.类型处理器(TypeHandler) MyBatis 在设置预处理语句(PreparedStatement)中的参数或从结果集中取出一个值时,都会用类型处理器将获取到的值以合 ...
- Mybatis——类型处理器TypeHandler
在日常开发中使用mybatis时,mybatis的mapper.xml.mapper接口.entity实体一般会由mybatis-generator自动生成,其中实体的每个属性与数据库表的列一一对应, ...
- MyBatis核心源码剖析(SqlSession XML解析 Mapper executor SQL执行过程 自定义类型处理器 缓存 日志)
MyBatis核心源码剖析 MyBatis核心源码剖析 1 MyBatis源码概述 1.1 为什么要看MyBatis框架的源码 1.2 如何深入学习MyBatis源码 1.3 源码分析的5大原则 2 ...
- MyBatis(九):MyBatis类型处理器(TypeHandler)详解
TypeHandler简介 TypeHandler,顾名思义类型转换器,就是将数据库中的类型与Java中的类型进行相互转换的处理器. MyBatis 在设置预处理语句(PreparedStatemen ...
- 在mybatis里如何自定义类型处理器
类型处理器(typeHandlers) MyBatis 在设置预处理语句(PreparedStatement)中的参数或从结果集中取出一个值时, 都会用类型处理器将获取到的值以合适的方式转换成 Jav ...
- 自定义类型处理器的应用
问题描述: 一个JSON字符串在转对象的时候报JSON解析异常的错误,我仔细看了一下错误堆栈,是枚举导致的数组越界问题. [{"fee":0,"amount": ...
- MyBatis之类型处理器typeHandlers
typeHandlers类型处理器 实现java类型与数据库类型之间的转换,可以使用系统提供的类型处理器,也可以自定义类型处理器,这里介绍的是实现自定义类型处理器处理数据库类型与java类型的转换 比 ...
- 类型处理器TypeHandler
作用:用于JavaType和JdbcType之间的转换 解析:当Mybatis将一个Java对象写入数据库时,它会创建一个PreparedStatument对象,并且使用setValue()方法对占位 ...
最新文章
- LeetCode-Unique Binary Search Trees
- 20321关系数据库理论基础
- 求字符串里面数字之和
- openshift命令_使用命令行工具创建WildFly OpenShift应用程序
- JDK Bug系统浪费时间
- 2018 总结 2019 展望
- android Instrumentation 转载
- 精通Android自定义View(八)绘制篇Canvas分析之绘制文本
- 青、取之于蓝,而青于蓝。
- 『007』MySQL
- 高通QFIL烧录错误解决方法
- 163邮箱链接服务器失败是怎么回事,outlook邮箱添加163邮箱账户失败该怎么办?...
- 地砖中间高四边低_客厅棚顶有黑镜在风水里讲怎么样 装修中橱柜里的白色色块用哪个做,怎么施工...
- C语言水电管理系统,小区水电费管理系统C语言.doc
- 中国跨境平台出海,产业带依然是最大优势
- java 实现仿word2007字数统计功能
- Redis 主从复制、哨兵和集群区别
- 计划订单投放成生产任务单时修改生产任务单编号
- python可以p图_用Python来P图!简直耍开PS几条街!
- Keras Regressor回归(一)