对mybatis的Handler 从使用角度介绍
最近在开发中,涉及到了讲数据库查询的类型,直接转为java需要的类型。 由于对handler 理解不到位 和 使用不当。躺了一些坑。
主要涉及的有2种。
1、varchar 转 List<T>
2、varchar 转Map<T>
如图是写的两个handler。
ListTypeHandler 为了保证 handler的通用性,采取了 将mybatis xml 配置中的type,传入 ListTypeHandler 中直接使用。 后来发现这是个大坑。
public class ListTypeHandler<E> extends BaseTypeHandler<List<E>> {
private Class<E> type;
public ListTypeHandler(Class<E> type) {
if (type == null) {
throw new IllegalArgumentException("Type argument cannot be null");
}
this.type = type;
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, List<E> parameter, JdbcType jdbcType) throws SQLException {
String x = JSON.toJSONString(parameter);
ps.setString(i, x);
}
@Override
public List<E> getNullableResult(ResultSet rs, String columnName) throws SQLException {
String s = rs.getString(columnName);
return StringUtils.isBlank(s) ? null : JSON.parseArray(s, type);
}
@Override
public List<E> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
String s = rs.getString(columnIndex);
return StringUtils.isBlank(s) ? null : JSON.parseArray(s, type);
}
@Override
public List<E> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
String s = cs.getString(columnIndex);
return StringUtils.isBlank(s) ? null : JSON.parseArray(s, type);
}
}
public class MapTypeHandler extends BaseTypeHandler<Map<String, Object>> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Map<String, Object> parameter, JdbcType jdbcType) throws SQLException {
if(MapUtils.isNotEmpty(parameter)) {
String x = JSON.toJSONString(parameter);
ps.setString(i, x);
}else{
ps.setString(i, null);
}
}
@Override
public Map<String, Object> getNullableResult(ResultSet rs, String columnName) throws SQLException {
String s = rs.getString(columnName);
return StringUtils.isBlank(s) ? null : JSON.parseObject(s, new TypeReference<Map<String, Object>>(){}); // JSON.parseObject(s, getRawType());
}
@Override
public Map<String, Object> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
String s = rs.getString(columnIndex);
return StringUtils.isBlank(s) ? null : JSON.parseObject(s, new TypeReference<Map<String, Object>>(){});
}
@Override
public Map<String, Object> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
String s = cs.getString(columnIndex);
return StringUtils.isBlank(s) ? null : JSON.parseObject(s, new TypeReference<Map<String, Object>>(){});
}
}
首先没有在mybatis.xml 总注册,直接通过@result指定使用
@Select("<script>SELECT " + SELECT_FILEDS_AS + " FROM " + TABLE + " WHERE valid =1 and config_id = #{configId} " + SELECT_LIMIT + " </script>")
@Results(value={
@Result(column="operation_content", property="operationContent", javaType=String.class, jdbcType=JdbcType.VARCHAR,typeHandler=ListTypeHandler.class),
})
List<OperateRecord> selectList(@Param("configId") long configId,@Param("offset") int offset,@Param("limit") int limit);
由于希望 ListTypeHandler 可以通用一点,因此采用了传入的javaType 即String,使用, 这个时候查询也没问题。感觉还很完美。
接下来,开始写插入
@Insert({"INSERT INTO " + TABLE + " (config_id, operation_staff, operation_time, action, operation_content, ctime,valid) values "
+"( #{configId}, #{operationStaff}, #{operationTime}, #{action}, #{operationContent, javaType=String, jdbcType=VARCHAR,typeHandler=ListTypeHandler}, unix_timestamp(),1 )"})
int insert(OperateRecord record);
这个时候就开始各种报错,最后经过一顿百度,发现是没有注册,于是增加注册。
<typeHandlers>
<typeHandler handler="com.support.ListTypeHandler" javaType="List" jdbcType="VARCHAR" />
</typeHandlers>
这个时候,在插入,发现成功了。 这个时候,认为全部搞定了,开始部署线下,进行联调。结果最大的问题才刚刚开始。
后头测试查询的时候,发现查询又报错。。。 于是开始debug,发现 'name' 类型varchar,java类型 String。 也开始进入list转换。 一脸懵逼。
于是尝试性的去掉字段的别名,发现居然成功了。。。
然后开始进入另一个大坑。认为和别名有关。
进入下一步的尝试
@Result(column = "initiateName" ,property = "initiateName")
为字段指定result,发现问题完美解决。
这个时候,任务只要@Results(value={}),使用过handler的,其他字段就也要指定。
这个时候,终于认为大功告成,结果。。。。
测试另一个dao的时候,发现,这个dao完全没有使用handler, 查询结果中的字段,也会去转换。。
然后,又开始懵逼。。。 一顿百度,最终恍然大悟。 再mybatisxml配置之后,是全局匹配。
因为不能使用传入的java类型, 再listhandler写死。
结论:
1.查询时候,不需要注册,即可直接通过result使用。type指定也可以生效。
2.插入的时候必须注册。
3.注册后,通过java,jdbc类型,还有名字全局匹配
4.result中可以不写,自动匹配
对mybatis的Handler 从使用角度介绍的更多相关文章
- MyBatis 3.5.2 新特性介绍
1.MyBatis 最新版本 3.5.2 发布 MyBatis最新版本是:3.5.2,发布时间是:2019年7月15日 2.MyBatis 3.5.2 新特征介绍 我们知道,MyBatis 是支持定制 ...
- MyBatis常用对象SqlSessionFactory和SqlSession介绍和运用
学习框架一个比较好的路径阅读源码.本文介绍的SqlSessionFactory和SqlSession.可以通过了解SqlSessionFactory接口和SqlSession接口以及两个的实现类入手, ...
- MyBatis执行流程的各阶段介绍
目录 一.mybatis极简示例 1.1 创建mybatis配置文件 1.2 创建数据库表 1.3 创建javabean 1.4 创建mapper映射文件 1.5 运行测试 二.mybatis的几大“ ...
- Android Bundle、Handler和Message类介绍
Bundle是一个载体,可以存放基本数据类型.对象等内容,相当于一辆汽车,可以装载很多东西,然后运到需要的地方,例如: Bundle mBundle=new Bundle(); mBundle.put ...
- Handler的简单使用介绍
Handler在android程序开发中使用的非常频繁.我们知道android是不允许在子线程中更新UI的,这就需要借助Handler来实现,那么你是否想过为什么一定要这个这样子做呢?而且Handle ...
- mybatis学习(十)——缓存介绍
与Hibernate一样,MyBatis 也提供了一级缓存和二级缓存的支持. 1.一级缓存:(本地缓存)SqlSession级别的缓存,默认一直开启的 , 与数据库同一次会话期间的数据会放到本地缓存中 ...
- Mybatis逆向工程文件标签的详细介绍:
?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUB ...
- Mybatis核心配置文件中的标签介绍
0. 标签顺序 Mybatis核心配置文件中有很多标签,它们谁谁写在前写在后其实是有顺序要求的: 从前到后: properties?,settings?,typeAliases?,typeHandle ...
- Mybatis(二):Mybatis的映射文件sqlmapper详解
MyBatis 真正的力量是在映射语句中.这里是奇迹发生的地方.对于所有的力量,SQL 映射的 XML 文件是相当的简单.当然如果你将它们和对等功能的 JDBC 代码来比较,你会发现映射文件节省了大约 ...
随机推荐
- Elasticsearch从入门到精通之Elasticsearch集群内的原理
上一章节我介绍了Elasticsearch安装与运行,本章节及后续章节将全方位介绍 Elasticsearch 的工作原理 在这个章节中,我将会再进一步介绍 cluster . node . shar ...
- Centos7 pcs pacemaker高可用安装配置详解
- SSM(Spring4.x.x+SpringMVC4.x.x+Mybatis3.4.x)框架整合
本文是参考SSM框架——详细整合教程(Spring+SpringMVC+MyBatis)修改而来的 一.环境 1. Myeclipse2016 2. Mysql 二.具体步骤 1. 整合Spring和 ...
- 高校表白APP-冲刺第三天
第三天,我们进行了第三次会议. 一.任务: 昨日任务:完成APP基本的登陆框架. 今日任务:完成登录界面修改界面注册界面,并解决闪退. 明日任务:完成界面跳转,并彻底解决闪退. 二.遇到的困难: 今天 ...
- CCF后感
3.21,昨天天梯训练赛完后查CCF成绩,300!小开心~~~我是合格的程序员啦~~~ 问题:第四题,如果输入数据有对于1本身来说 S 1 ,R 1有这个我就gg了,考完一直在担心这个反复看题也看不出 ...
- Linux中检查本地系统上的开放端口列表的方法
在 Linux 中很少有用于此目的的实用程序.然而,我提供了四个最重要的 Linux 命令来检查这一点. 你可以使用以下四个命令来完成这个工作.这些命令是非常出名的并被 Linux 管理员广泛使用.n ...
- 搭建一个简单的Eureka程序
Eureka集群主要有三个部分Eureka服务器,服务提供者,服务调用者 简单的来说就是服务提供者将服务注册到Eureka服务器,服务调用者对其服务进行查找调用. Eureka服务程序的搭建可参考官方 ...
- vmware-tools安装——实用
1.vmware中点击安装或重新安装vmware-tools 2.在root终端解压并移动安装文件:tar -xvf VMwareTools-9.9.0-2304977.tar.gz -C /tmp ...
- 自娱自乐RN版小说APP历程记录
当前rn版本 "react": "16.6.3" "react-native": "0.58.5" 通过react-na ...
- 编码原则 之 Stable Dependencies
The Stable Dependencies Principle states that “The dependencies between software packages should be ...