我是图片

Mybatis第四篇| 类处理器什么玩意?举个栗子你就知道了


摘要: 今天这篇文章其实接着上一篇,因为在上一篇讲解配置的时候,少讲了一个配置,类型处理器(typeHandlers)。为什么在上一篇文章中没有说呢?因为如果干说,肯定是有点不好理解,所以单独写一篇文章,给大家举个例子,应该就很容易理解了。废话不多说,直接开讲。

前言

今天这篇文章其实接着上一篇,因为在上一篇讲解配置的时候,少讲了一个配置,类型处理器(typeHandlers)。为什么在上一篇文章中没有说呢?因为如果干说,肯定是有点不好理解,所以单独写一篇文章,给大家举个例子,应该就很容易理解了。废话不多说,直接开讲。

类型处理器

什么是类处理器?

我们首先来看看官网怎么说,MyBatis 在设置预处理语句(PreparedStatement)中的参数或从结果集中取出一个值时, 都会用类型处理器将获取到的值以合适的方式转换成 Java 类型。

可能这个不太好理解,简单点来说,我们在mapper映射器编写sql语句的时候,mapper映射器会自动帮我们进行JDBC类型和Java类型的转换。首先我们需要弄懂什么是JDBC类型和Java类型。

在官网中给了我们一份表,在表的第一列是各种各样的类型处理器xxxTypeHandler,这些处理器都是mybatis自带的处理器,会自动帮我们处理一些类。

怎么处理呢?我们看到第二列和第三列,分别是Java类型和JDBC类型,这两种类型不是互通的,而是需要通过类型处理器才能进行转换。例如我Java中的boolean值需要转换成JDBC中的(也可以理解为数据库中的)BOOLEAN类型,我们就需要通过BooleanTypeHandler处理器来进行处理。其他的都是如此。

自定义类处理器

那么理解了类处理器到底是干啥的,我们接下来又会有个疑惑,既然mybatis帮我们自动处理了,我们还要学习干啥?mybatis帮我们处理的只是一些基础常用的Java类型,如果我们需要让它来帮我们处理一个自定义对象,它能理解吗?例如下面的对象↓

public class Address {
    private String country;
    private String province;
    private String city;
    ...

在这个对象里,我们有三个变量,mybatis肯定是没有我们Address这个类处理器的,所以我们需要自己动手来写一个类处理器。

我们首先来看到官方文档

也就是说mybatis支持我们自定义类处理器,并且只需要通过实现 org.apache.ibatis.type.TypeHandler 接口,或继承一个很便利的类 org.apache.ibatis.type.BaseTypeHandler就能够映射成一个JDBC类型。

我们还是根据之前文章中的项目来进行拓展。

假设我的User对象中多了一个属性Address对象,我们来编辑我们的Address对象:

public class Address {
    private String country;
    private String province;
    private String city;
    
    public Address(String addressString) {
        //假设我们是通过 - 来分开country-province-city
        String[] address = addressString.split("-");
        this.country = address[0];
        this.province = address[1];
        this.city = address[2];

    }
   ...
   //下面是get和set以及toString方法

我们设置了Address对象有country、province、city三个属性,并且从构造器中可以看到,我们是通过country-province-city的方式来进行输入信息的,我们通过String的split方法对该字符串进行划分,并且赋给相应的属性。

此时mybatis是没有Address这个类处理器的,这个时候我们创建handler包,在包下创建AddressTypeHandler类。

AddressTypeHandler.java:

public class AddressTypeHandler extends BaseTypeHandler<Address> {
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Address parameter, JdbcType jdbcType) throws SQLException {

         ps.setString(i,parameter.toString());
    }

    //下面三个getXXX方法,将数据库获得的记录集里的address字段转成java Address类型的对象。
    @Override
    public Address getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return new Address(rs.getString(columnName));
    }

    @Override
    public Address getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return new Address(rs.getString(columnIndex));
    }

    @Override
    public Address getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return new Address(cs.getString(columnIndex));
    }
}

我们按照官方文档,继承BaseTypeHandler类并且重写了setNonNullParametergetNullableResult总共四个方法。

三个get方法的作用就是将数据库获得的记录集里的address字段转成java Address类型的对象。set方法是用来将java类型转成数据库存储的类型。

接着我们只需要在配置文件中配置我们的类处理器即可使用了。

<typeHandlers>
  <typeHandler handler="com.kuls.handler.AddressTypeHandler"/>
</typeHandlers>

记得一定要按照相应的顺序进行编写,否则会报错。

最后,我们可以看到输出结果为:

这意味着我们自定义的类处理器成功了。

点赞
3
赞赏


  • 作者:kuls
  • 简介:一个热爱编程的小伙子!
  • 版权:转载文章需找站长授权,未经授权转载,必会追究!
二维码

评论

留言