1 typeHandler 类型转换器
在 JDBC 中,需要在 PreparedStatement 对象中设置那些已经预编译过的 SQL 语句的参数。在执行 SQL 后,会通过 ResultSet 对象得到数据库的数据,这里涉及到了 Java 数据类型到数据库数据类型的转换, MyBatis 是通过 typeHandler 来实现转换的。
在 typeHandler 中,分为 jdbcType 和 javaType,其中 jdbcType 用于定义数据库中的数据类型,javaType 用于定义 Java 类型,typeHandler 的作用就是承担 jdbcType 和 javaType 之间的相互转换。
在 MyBatis 中已经定义了很多 typeHandler ,所以大多数情况下我们并不需要去自定义 typeHandler 。
2 自定义 typeHandler 类型转换器
这里自定义一个Java类型(Boolean)与数据库类型(int)的类型转换器。
2.1 项目结构
2.2 项目配置
引入依赖
<dependencies>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.34</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
log4j 配置
使用日志可以打印出 MyBatis 的一些运行过程,可以让我们看到相关的 SQL 语句。
##define an appender named console
log4j.appender.console=org.apache.log4j.ConsoleAppender
#The Target value is System.out or System.err
log4j.appender.console.Target=System.out
#set the layout type of the apperder
log4j.appender.console.layout=org.apache.log4j.PatternLayout
#set the layout format pattern
log4j.appender.console.layout.ConversionPattern=[%-5p] %m%n
##define a logger
log4j.rootLogger=debug,console
MyBatis 配置
<?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>
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/kaikeba?characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="sa123456"/>
</properties>
<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>
<package name="cn.wu.mapper" />
</mappers>
</configuration>
2.3 Java类型与数据库类型
这里需要转换的是 flag 字段。它的 Java 类型是 Boolean, 数据库类型是 int 。为了使得它们之间能够相互转换,我们需要自定义 typeHandler。
public class Dept {
private Integer deptNo;
private String dName;
private String loc;
private boolean flag; // Java类型
// seter, gette
}
+--------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+----------------+
| DEPTNO | int(2) | NO | PRI | NULL | auto_increment |
| DNAME | varchar(14) | YES | | NULL | |
| LOC | varchar(13) | YES | | NULL | |
| flag | int(11) | YES | | NULL | |
+--------+-------------+------+-----+---------+----------------+
2.4 自定义 typeHandler
定义 MyTypeHandler
@MappedTypes(Boolean.class) // 指定 Java 类型
@MappedJdbcTypes(JdbcType.INTEGER) // 指定数据库类型
public class MyTypeHandler implements TypeHandler<Boolean> {
// 在 mybatis 构造 Statement 时调用
public void setParameter(PreparedStatement ps, int i, Boolean parameter, JdbcType jdbcType) throws SQLException {
if(parameter == true) {
ps.setInt(i, 1);
} else {
ps.setInt(i, 0);
}
}
// 在 mybatis 读取数据库数据之后,将数据转化为对应的 Bean 时调用
public Boolean getResult(ResultSet rs, String columnName) throws SQLException {
int flag = rs.getInt(columnName);
if (flag == 1) {
return true;
}
return false;
}
public Boolean getResult(ResultSet rs, int columnIndex) throws SQLException {
int flag = rs.getInt(columnIndex);
if (flag == 1) {
return true;
}
return false;
}
public Boolean getResult(CallableStatement cs, int columnIndex) throws SQLException {
int flag = cs.getInt(columnIndex);
if (flag == 1) {
return true;
}
return false;
}
}
注册 MyTypeHandler
需要在 MyBatis 的配置文件中进行注册。
<typeHandlers>
<package name="cn.wu.typehandler" />
<!--两种方式任选其一-->
<!--<typeHandler handler="cn.wu.typehandler.MyTypeHandler" />-->
</typeHandlers>
使用 MyTypeHandler
在使用自定义 typeHandler 时,有两种方式。
- 不显示指定。 当 MyBatis 检测到 Java 类型和数据库类型符合我们自定义的 typeHandler 时,它会自动使用我们自定义的 typeHandler 进行Java类型与数据库类型的转换。
- 显示指定。
显示指定 MyTypeHandler。在 Mapper.xml 文件中显示指定:
<resultMap id="dept" type="cn.wu.model.Dept">
<id property="deptNo" column="deptno"/>
<result property="dName" column="dname"/>
<result property="flag" column="flag"
typeHandler="cn.wu.typehandler.MyTypeHandler"/>
</resultMap>
测试
public static void main(String[] args) throws IOException {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
SqlSession session = factory.openSession();
DeptMapper deptMapper = session.getMapper(DeptMapper.class);
Dept dept = new Dept();
dept.setdName("技术部");
dept.setFlag(false);
dept.setLoc("上海");
deptMapper.insert(dept);
session.commit(); // 提交
Dept rDept = deptMapper.get(dept.getDeptNo());
System.out.println(rDept);
session.close();
}
+--------+--------+------+------+
| DEPTNO | DNAME | LOC | flag |
+--------+--------+------+------+
| 52 | 技术部 | 上海 | 0 |
+--------+--------+------+------+
Dept{deptNo=52, dName='技术部', loc='上海', flag=false}
可以看到成功实现 Java 类型(Boolean)到数据库类型 (int)的相互转换。