MyBatis(九):MyBatis类型处理器(TypeHandler)详解
TypeHandler简介
TypeHandler,顾名思义类型转换器,就是将数据库中的类型与Java中的类型进行相互转换的处理器。
MyBatis 在设置预处理语句(PreparedStatement)中的参数或从结果集中取出一个值时, 都会用类型处理器将获取到的值以合适的方式转换成 Java 类型
实现讲解
经常自定义类型转换器方式有两种,实现
TypeHandler
接口, 或继承抽象类BaseTypeHandle
,并且可以指定转换后的字段类型。- 其实BaseTypeHandler也是继承了TypeHandler接口,在实现的TypeHandler接口的方法中调用的是自身抽象方法,如下
public abstract class BaseTypeHandler<T> extends TypeReference<T> implements TypeHandler<T> { public T getResult(ResultSet rs, String columnName) throws SQLException {
Object result;
try {
result = this.getNullableResult(rs, columnName);
} catch (Exception var5) {
throw new ResultMapException("Error attempting to get column '" + columnName + "' from result set. Cause: " + var5, var5);
} return rs.wasNull() ? null : result;
} public abstract T getNullableResult(ResultSet var1, String var2) throws SQLException;
}
- 抽象类BaseTypeHandler的抽象方法
// 执行之前,将Java类型转换为对应的jdbc类型,用于赋值sql中参数
public abstract void setNonNullParameter(PreparedStatement var1, int var2, T var3, JdbcType var4) throws SQLException; // 根据列名从resultSet中获取,将JDBC类型转换为Java类型
public abstract T getNullableResult(ResultSet var1, String var2) throws SQLException; // 根据下标从resultSet中获取,将JDBC类型转换为Java类型
public abstract T getNullableResult(ResultSet var1, int var2) throws SQLException; // 用于在执行完存储过程后,将JDBC类型转换为Java类型
public abstract T getNullableResult(CallableStatement var1, int var2) throws SQLException;
自定义类型处理器
假设现在有一个支付标识(0-否 1-是)字段,数据库中我们存入的是tinyint 0/1,但是前端显示却是 是/否,使用TypeHandler就可以实现。具体步骤如下:
- 新建MyTypeHandler,继承BaseTypeHandler类
public class MyTypeHandler extends BaseTypeHandler<String> { /**
* @Description 执行之前,将Java类型转换为对应的jdbc类型,用于赋值sql中参数
**/
@Override
public void setNonNullParameter(PreparedStatement preparedStatement, int i, String s, JdbcType jdbcType) throws SQLException {
preparedStatement.setInt(i,Integer.valueOf(s));
} /**
* @Description 根据列名从resultSet中获取,将JDBC类型转换为Java类型
**/
@Override
public String getNullableResult(ResultSet resultSet, String s) throws SQLException {
return this.convert(resultSet.getInt(s));
} /**
* @Description 根据下标从resultSet中获取,将JDBC类型转换为Java类型
**/
@Override
public String getNullableResult(ResultSet resultSet, int i) throws SQLException {
return this.convert(resultSet.getInt(i));
} /**
* @Description 用于在执行完存储过程后,将JDBC类型转换为Java类型
**/
@Override
public String getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
return this.convert(callableStatement.getInt(i));
} /**
* @Description 对数据库中0/1进行转换
**/
private String convert(int flag){
if (flag==1){
return "是";
}
return "否";
}
}
- 在Mapper中指定需要转换的字段,jdbcType指数据库中的类型,javaType指Java中的类型,typeHandler指定自定义的转换器
<result column="flag" property="flag" jdbcType="TINYINT" javaType="java.lang.String" typeHandler="com.rangers.MyTypeHandler"></result>
- 进行测试
private SqlSession sqlSession ;
private OrderMapper orderMapper; @Before
public void init() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
sqlSession = sqlSessionFactory.openSession();
orderMapper = sqlSession.getMapper(OrderMapper.class);
} // 测试读取时转换
@org.junit.Test
public void testResult(){
Order order = orderMapper.selectOne(1);
System.out.println(order);
} // 测试传入时转换
@org.junit.Test
public void testParameter(){
// 假设前端传入字符串0/1
List<Order> orders = orderMapper.selectOneByFlag("1");
System.out.println(orders);
} @After
public void close(){
sqlSession.close();
}
[Order{id=2, time=Wed Mar 10 17:22:45 CST 2021, total=2.22, uid=1, flag=是}, Order{id=3, time=Wed Mar 10 17:22:57 CST 2021, total=3.33, uid=2, flag=是}]
全局字段转换与单个字段转换
全局转换:在核心配置文件中添加typeHandlers标签
<typeHandlers>
<typeHandler handler="com.rangers.MyTypeHandle"/>
</typeHandlers>
单个字段转换:指定jdbcType、javaType与typeHandler
<result column="flag" property="flag" jdbcType="TINYINT" javaType="java.lang.String" typeHandler="com.rangers.MyTypeHandler"></result>
通常在项目中使用的是单个字段进行转换,经常自定义类型处理器还有日期处理、加密字段处理、List处理,JSON处理等
MyBatis(九):MyBatis类型处理器(TypeHandler)详解的更多相关文章
- MyBatis源码解析(十)——Type类型模块之类型处理器TypeHandler
原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6715063.html 1.回顾 之前的两篇分别解析了类型别名注册器和类型处理器注册器,此二 ...
- 深入浅出Mybatis系列(四)---配置详解之typeAliases别名(mybatis源码篇)
上篇文章<深入浅出Mybatis系列(三)---配置详解之properties与environments(mybatis源码篇)> 介绍了properties与environments, ...
- Mybatis的配置文件和映射文件详解
一.Mybatis的全局配置文件 1.SqlMapConfig.xml是mybatis的全局配置文件,配置内容如下: properties(属性) settings(全局配置参数) typeAlias ...
- 热烈祝贺华清远见《ARM处理器开发详解》第2版正式出版
2014年6月,由华清远见研发中心组织多名业 内顶尖讲师编写的<ARM处理器开发详解>一书正式出版.本书以S5PV210处理器为平台,详细介绍了嵌入式系统开发的各个主要环节,并注重实践,辅 ...
- C#中的预处理器指令详解
这篇文章主要介绍了C#中的预处理器指令详解,本文讲解了#define 和 #undef.#if.#elif.#else和#endif.#warning和#error.#region和#endregio ...
- MyBatis的SQL语句映射文件详解
SQL 映射XML 文件是所有sql语句放置的地方.需要定义一个workspace,一般定义为对应的接口类的路径.写好SQL语句映射文件后,需要在MyBAtis配置文件mappers标签中引用 < ...
- MyBatis魔法堂:Insert操作详解(返回主键、批量插入)
一.前言 数据库操作怎能少了INSERT操作呢?下面记录MyBatis关于INSERT操作的笔记,以便日后查阅. 二. insert元素 属性详解 其属性如下: parameterType ...
- MyBatis魔法堂:Insert操作详解
一.前言 数据库操作怎能少了INSERT操作呢?下面记录MyBatis关于INSERT操作的笔记,以便日后查阅. 二. insert元素 属性详解 其属性如下: parameterType:入参的全限 ...
- MyBatis学习笔记2--配置环境详解
1.MyBatis-config.xml详解 一个完整的配置文件如下所示 <configuration> <!-- <properties resource="jdb ...
随机推荐
- OpenStack Train版-14.安装块存储服务cinder(存储节点)
安装cindoer块存储服务节点(存储节点192.168.0.40)使用默认的LVM卷方法,之后改为ceph存储 安装LVM软件包 [root@cinder01 ~]# yum install lvm ...
- MySQL 主从复制(下)
延时复制 因为延时复制主从数据同一时间不一致, 所以延时从库一般只能做备份,不提供任何对外服务 配置延时复制(已经有主从) 1.停止主从 mysql> stop slave; Query OK, ...
- Playbook 角色(Roles) 和 Include 语句
简介 当我们刚开始学习运用 playbook 时,可能会把 playbook 写成一个很大的文件,到后来可能你会希望这些文件是可以方便去重用的,所以需要重新去组织这些文件. Include 语句 基本 ...
- Spring-cloud-netflix-hystrix
服务注册中心eureka-server已经搭好,并且SPRING-CLOUD-NETFLIX-EUREKA-CLIENT-APPLICATION提供一个hello服务 畏怯还编写一个eureka-cl ...
- Verilog基础语法总结
去年小学期写的,push到博客上好了 Verilog 的基本声明类型 wire w1; // 线路类型 reg [-3:4] r1; // 八位寄存器 integer mem[0:2047]; // ...
- Dart & data type(static / dynamic)
Dart & data type(static / dynamic) Darts 飞镖 标枪 javelin/darts type https://dartpad.dartlang.org/ ...
- Dart & import show & import hide & import as & part & part of
Dart & import show & import hide & import as & part & part of // 部分导入,即仅仅导入 dart ...
- 图解 git 流程
图解 git 流程 Github 开源项目 1 动画 2 web repl 3 online git cli & create remote branch # Create a new bra ...
- Baccarat如何点燃DEFI市场?
目前DeFi是成为了各大生态的"兵家必争之地",与此同时DeFi的高收益也成为吸引散户入局的一个利器.而虽然流动性挖矿板块近期的温度有所下降,但是这其中不乏还是有很多收益颇丰的De ...
- Word带数学公式发布博客
Word公式编辑器无法直接上传博客,一个一个的转换LaTeX还要加$,十分麻烦. 下面是我昨天摸索出来的办法.作为博客新人,这个问题困扰我一晚上,能解决我也是非常高兴的. 如果各位前辈有好方法的话,请 ...