自定义 MyBatis 的 typeHandler 类型转换器

本文介绍了如何在MyBatis中自定义TypeHandler,以实现Java的Boolean类型与数据库的int类型之间的转换。详细讲解了项目结构、配置、自定义TypeHandler的步骤,并提供了测试验证转换效果。
摘要由CSDN通过智能技术生成

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)的相互转换。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值