代码
文章涉及的代码都将统一存放到此仓库,文章涉及的案例代码存放在包: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
点击:加群讨论