前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Mybatis第四篇| 类处理器什么玩意?举个栗子你就知道了

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

作者头像
Python进击者
发布2020-04-14 18:01:44
5250
发布2020-04-14 18:01:44
举报
文章被收录于专栏:JAVAandPython君JAVAandPython君

原创| kuls

首发: JAVAandPython君

前言

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

类型处理器

什么是类处理器?

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

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

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

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

自定义类处理器

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

代码语言:javascript
复制
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对象:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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类型转成数据库存储的类型。

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

代码语言:javascript
复制
<typeHandlers>
  <typeHandler handler="com.kuls.handler.AddressTypeHandler"/>
</typeHandlers>

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

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

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

本文代码

完整代码:

代码语言:javascript
复制
https://github.com/hellokuls/kuls-mybatis

之后该系列的代码和文章全部放在这个GitHub项目,欢迎大家star!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python进击者 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 类型处理器
    • 什么是类处理器?
      • 自定义类处理器
      • 本文代码
      相关产品与服务
      云数据库 Redis
      腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档