二、Mybatis学习实践-自定义TypeHandler

代码

文章涉及的代码都将统一存放到此仓库,文章涉及的案例代码存放在包:com.hzchendou.blog.demo.example下

代码地址:Gitee

分支:lesson2

涉及案例:Case2

简介

上一篇文章搭建了一套Mybatis基础运行程序,以博客系统为背景,提供了创建、查询博客文章信息功能。博客文章状态以Integer类型存储

  • 0-表示无效
  • 1-表示有效

使用Integer类型可以降低存储成本,但是对开发人员不友好,可读性差,后续维护成本高,如果将数据库中的值取出后转化为枚举类型(enum),那么不仅可以降低存储成本,还可以提高程序可读性,降低维护成本。

TypeHandler

Mybatis提供了TypeHandler来解决上述问题,TypeHandler接口定义如下:


public interface TypeHandler<T> {
  
   将输入参数转化为数据库中的值
  void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;

   将数据库中的字段转化为指定类型
  T getResult(ResultSet rs, String columnName) throws SQLException;
  T getResult(ResultSet rs, int columnIndex) throws SQLException;
  T getResult(CallableStatement cs, int columnIndex) throws SQLException;
}

主要提供了两类功能:

  • 将输入参数转化为数据库中的值
  • 将数据库中查询出来的字段转化为指定类型(提供了三个方法,实现了相同功能)

Mybatis系统提供了两个枚举类处理器TypeHandler

  • EnumOrdinalTypeHandler,这将枚举类型使用int类型存储到数据库中
  • EnumTypeHandler,将枚举类型使用字符串类型(枚举类名)存储到数据库中

在本案例中使用EnumOrdinalTypeHandler处理器,有多种配置方式,主要有两类,一类是配置全局默认枚举类处理器,二是在指定枚举类上配置处理器

配置方式一

在mybtais主配置文件中设置(配置文件中省略了不相关配置):

<?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>
  ....
  <!-- 设置信息 -->
  <settings>
    <setting name="defaultEnumTypeHandler" value="org.apache.ibatis.type.EnumOrdinalTypeHandler"/>
  </settings>
  .....
</configuration>

 这种方式针对的全局配置,如果没有特定配置,默认使用该处理来处理枚举类型,建议使用,可以省略大量配置工作

配置方式二

方式二是特定类型配置,配置的方式有很多种,可以在Mybatis配置文件中设置,也可以在Mapper xml文件中配置,如果是自定义处理器还可以使用注解方式进行配置,这里不过多介绍,本文选择在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>
  ....
  <!-- 类型转化 -->
  <typeHandlers>
    <typeHandler handler="org.apache.ibatis.type.EnumOrdinalTypeHandler" javaType="com.hzchendou.blog.demo.enums.BlogStatusEnums"/>
  </typeHandlers>
  .....
</configuration>

这种方式针对特定类型进行配置,只有当输入参数或者是输出参数中包含BlogStatusEnums类型才会调用处理器进行数据转换

程序运行

优化BlogDO

定义一个BlogStatusEnums枚举类:

/**
 * 博客状态枚举类型
 */
public enum BlogStatusEnums {
    INVALID,
    VALID
}
  • INVALID表示无效,存储到数据库中的值是0
  • VALID表示有效,存储到数据库中的值是1

将BlogDO中的status属性修改为BlogStatusEnums类型

结果

运行Case2程序,得到如下结果:

15:32:18.840 [main] DEBUG org.apache.ibatis.logging.LogFactory - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
15:32:18.845 [main] DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
15:32:18.845 [main] DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
15:32:18.845 [main] DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
15:32:18.845 [main] DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
15:32:18.935 [main] DEBUG org.apache.ibatis.transaction.jdbc.JdbcTransaction - Opening JDBC Connection
15:32:19.289 [main] DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - Created connection 1316061703.
15:32:19.290 [main] DEBUG org.apache.ibatis.transaction.jdbc.JdbcTransaction - Setting autocommit to false on JDBC Connection [org.sqlite.SQLiteConnection@4e718207]
15:32:19.292 [main] DEBUG com.hzchendou.blog.demo.mapper.BlogMapper.selectAll - ==>  Preparing: SELECT id, `title`, `author_id`, `tags`, `status` FROM blog
15:32:19.307 [main] DEBUG com.hzchendou.blog.demo.mapper.BlogMapper.selectAll - ==> Parameters: 
15:32:19.317 [main] DEBUG com.hzchendou.blog.demo.mapper.BlogMapper.selectAll - <==      Total: 4
15:32:19.319 [main] INFO com.hzchendou.blog.demo.example.Case2 - 查询博客文章列表信息, [BlogDO(id=1, title=时间海绵博文, authorId=1, tags=博文、时间海绵, status=VALID), BlogDO(id=2, title=时间海绵博文, authorId=1, tags=博文、时间海绵, status=VALID), BlogDO(id=3, title=时间海绵博文, authorId=1, tags=博文、时间海绵, status=VALID), BlogDO(id=4, title=时间海绵博文, authorId=1, tags=博文、时间海绵, status=VALID)]
15:32:19.320 [main] DEBUG org.apache.ibatis.transaction.jdbc.JdbcTransaction - Resetting autocommit to true on JDBC Connection [org.sqlite.SQLiteConnection@4e718207]
15:32:19.320 [main] DEBUG org.apache.ibatis.transaction.jdbc.JdbcTransaction - Closing JDBC Connection [org.sqlite.SQLiteConnection@4e718207]
15:32:19.320 [main] DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - Returned connection 1316061703 to pool.

可以看到输出的结果中status变量的值为VALID,是我们想要的结果。

总结

Mybatis提供了输入输出参数类型转化功能,开发人员可以很方便的使用Typehandler实现数据转化操作,可以提高程序的可读性,同时也能够降低使用成本(使用int存储比字符串存储成本低),我们需要做以下操作

  • 选择系统提供的或者是自定义TypeHandler
  • 将TypeHandler注册到TypeHandlerRegistry中,有多种方法(enum类型处理器比较特殊,所以可以配置全局处理器)
    • 可以使用注册方式,@MappedTypes
    • 可以在Mybatis配置文件中配置
    • 可以在Mapper xml文件中配置,在SQL语句中的输入参数中和ResultMap的字段中配置typeHandler属性

联系方式

技术更新换代速度很快,我们无法在有限时间掌握全部知识,但我们可以在他人的基础上进行快速学习,学习也是枯燥无味的,加入我们学习牛人经验:

QQ:901856121

点击:加群讨论 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值