又被古董级的库坑了—— ibatis typehandler

为了将一个不知道什么类型的java对象存到数据库里面,用了个很恶心的方法:将对象序列化之后,保存到数据库的blob对象。这样整个序列化和反序列化过程,都期望在ibatis中完成,上层就能直接获取到需要的对象了。
第一次安装网上的方式,想直接参考spring的BlobByteArrayTypeHandler,将blob对象保存到数据库。因为这个类是需要的是byte数组,还不满足我的需求,就参照这个类,继承了AbstractLobTypeHandler,重写getResultInternal和setParameterInternal。然后将这个type handler配置到ibatis的sqlmap文件中。一切看上去很顺利,结果启动的时候ibatis报ClassCastException,说这个handler无法强制转换成TypeHandlerCallback。

这个异常看上去很奇怪,去网上搜索了InlineParameterMapParser类,里面的逻辑大致是:
[cce lang=”java”]
} else if (“handler”.equals(field)) {
try {
value = typeHandlerFactory.resolveAlias(value);
Object impl = Resources.instantiate(value);
if (impl instanceof TypeHandlerCallback) {
mapping.setTypeHandler(new CustomTypeHandler((TypeHandlerCallback) impl));
} else if (impl instanceof TypeHandler) {
mapping.setTypeHandler((TypeHandler) impl);
} else {
throw new SqlMapException (“The class ” + value + ” is not a valid implementation of TypeHandler or TypeHandlerCallback”);
}
} catch (Exception e) {
throw new SqlMapException(“Error loading class specified by handler field in ” + token + “. Cause: ” + e, e);
}
[/cce]
也就是说,如果在sql中配置的handler是同时兼容TypeHandlerCallback和TypeHandler接口的,spring的AbstractLobTypeHandler类,实现的是BaseTypeHandler,应该没有问题的啊。

反编译了应用中试用的ibatis(版本是2.1.6),发现里面的逻辑完全不一样:
[cce lang=”java”]
} else if (“handler”.equals(field)) {
try {
value = typeHandlerFactory.resolveAlias(value);
mapping.setTypeHandler(new CustomTypeHandler((TypeHandlerCallback)Resources.classForName(value).newInstance()));
} catch (Exception e) {
throw new SqlMapException(“Error loading class specified by handler field in ” + token + “. Cause: ” + e, e);
}
} else {
throw new SqlMapException(“Unrecognized parameter mapping field: ‘” + field + “‘ in ” + token);
}
[/cce]
这个古董是直接初始化之后强转为TypeHandlerCallback的。没办法,只能自己实现这个接口。

[cce lang=”java”]
public class JavaSerializeBlobHandler implements TypeHandlerCallback {

/*
* (non-Javadoc)
* @see com.ibatis.sqlmap.engine.type.TypeHandler#valueOf(java.lang.String)
*/
public Object valueOf(String s) {
return s;
}

/*
* (non-Javadoc)
* @see
* com.ibatis.sqlmap.client.extensions.TypeHandlerCallback#getResult(com.ibatis.sqlmap.client.extensions.ResultGetter
* )
*/
public Object getResult(ResultGetter paramResultGetter) throws SQLException {
byte[] buf = paramResultGetter.getBytes();
if(buf == null) {
return null;
}
try {
ObjectInputStream inputStream = new ObjectInputStream(new ByteArrayInputStream(buf));
return inputStream.readObject();
} catch (IOException e) {
throw new IllegalArgumentException(e);
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException(e);
}
}

/*
* (non-Javadoc)
* @see com.ibatis.sqlmap.client.extensions.TypeHandlerCallback#setParameter(com.ibatis.sqlmap.client.extensions.
* ParameterSetter, java.lang.Object)
*/
public void setParameter(ParameterSetter paramParameterSetter, Object paramObject) throws SQLException {
if (paramObject == null) {
paramParameterSetter.setNull(Types.BLOB);
} else {
try {
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteStream);
objectOutputStream.writeObject(paramObject);

paramParameterSetter.setBytes(byteStream.toByteArray());
} catch (IOException e) {
throw new IllegalArgumentException(e);
}
}
}
}
[/cce]
不过接口中的valueOf方法,到底是干什么用的,什么时候调用的还没搞清楚。将这个类配置在sqlmap的resultMap或sql中内联,都能够正常的对对象进行存取。

转载自:https://coolex.info/blog/330.html

时间: 2024-08-03 13:00:17

又被古董级的库坑了—— ibatis typehandler的相关文章

android开发-很多手机背单词的app都可以选择4级单词库,6级单词库等等,这些数据是如何获取的?

问题描述 很多手机背单词的app都可以选择4级单词库,6级单词库等等,这些数据是如何获取的? 就是我想获取一些4.6级的单词库的数据,用来开发android 的背单词的app,但是不知道从哪里可以获取到这些数据 解决方案 4.6级单词打印版本http://wenku.baidu.com/link?url=nbvSH9SqHW60UfxmqIcROWIKTH941yePT-uPSMA54BdSkHD0Dk4e-p07Xw5FzyddE2akHgJF0qiRwSNYAKQBs6uojZn6I6HSD

美国政府至今仍在使用软盘和“古董级”IT系统

近期,一份来自美国联邦会计总署的报告引起了较大范围的关注,报告反映了当前部分美国政府部门仍在使用较为过时的系统,而其中包含了美国国防部的核武器管理系统. 在各类美国大片以及平时的认知中,我们通常会觉得,在美国政府机构使用的各类设备.系统应该都是较为先进的,智能化程度较高的,这样才符合美国相对领先的科技水平.而近期随着美国联邦会计总署(United States Government Accountability Office)发布了一份名为<信息技术:联邦政府需要关注并解决老旧系统问题>(Fe

乔布斯拍卖古董级Apple-1:15万英镑起

新浪科技讯 北京时间11月12日上午消息,据国外媒体报道,苹果CEO史蒂夫·乔布斯(Steve Jobs)车库中的一台1976年苹果 Apple-1电脑将在伦敦佳士得拍卖行(Christie's)公开拍卖,起价为15万英镑.1976年,乔布斯从父母的车库里售出了200台以今天的标准看堪称原始的苹果电脑.他和合伙人史蒂夫·沃兹尼亚克(Steve Wozniak)将售价定为666.66美元,据说这是因为沃兹尼亚克酷爱重复数字.1976年销售的苹果Apple-1电脑这款电脑将由伦敦佳士得拍卖行负责拍卖

《香格里拉》热拍古董战斗机成“宠物”(图)

古董级战斗机 新浪娱乐讯 由著名导演蒋家骏执导,胡歌.王力可.巍子.扎西顿珠等主演的民族史诗传奇大戏<香格里拉>正在云南热拍.除了保家卫国的民族情结,剧中还集中表现了外来文化与藏族民族文化在冲突中的逐步融合.而为了重现宏大的战争场面,剧组还不惜重金"请"来两架60多年前曾在抗日战场上冲锋陷阵的古董级战斗机助阵. 飞虎队邂逅藏族公主 中西文化冲突出彩 文化冲突历来是众多文艺作品,尤其是电视作品中最容易出彩的主题,而<香格里拉>在这一点上则有着天然的优势.作为第一部

搜狗号码通开放SDK,号码库成手机竞争砝码

8月11日消息,手机硬件日趋同质化,使得手机的竞争重点逐渐从硬件转向软件和服务,以用户体验来加强差异化特色.日前,搜狗号码通与 众多手机厂商进行洽谈后宣布,将其亿级号码库通过SDK方式开放给广大手机厂商,共同为用户提供更为优质的移动增值服务.这是移动通信领域首个全面开放的号码库,或将在手机.号码搜索等多个领域产生连锁反应.诞生于2012年的搜狗号码通是"搜狗"旗下一款专业级通信管理软件,其强大的查号功能.业内首创的"标记系统"和来电识别等特色功能,深受广大用户的喜爱

始祖级网游十周年《传奇2》累积销售超127亿元

截止至2010年12月,韩国娱美德(Wemade)公司迎来运营十周年生日的旗下武侠MMORPG<传奇2(Mir2)>,成为韩国单一游戏史上全球累积销售额突破2兆2千亿韩元(RMB约127.6亿元)的最高纪录游戏. 2001年3月起,<传奇2>在韩国投入运营,此后亦在中国网游市场掀起韩流风潮,并相继输出到北美.乌兹别克斯坦等地,至今依然保持其传统性进行运营中,形成一大批拥趸. <传奇2>与运营史超过10年的NCsoft<天堂>和Nexon<风之国度>

漫谈GCD

多线程是程序开发中非常基础的一个概念,大家在开发过程中应该或多或少用过相关的东西.同时这恰恰又是一个比较棘手的概念,一切跟多线程挂钩的东西都会变得复杂.如果使用过程中对多线程不够熟悉,很可能会埋下一些难以预料的坑. iOS中的多线程技术主要有NSThread, GCD和NSOperation.他们的封装层次依次递增,其中: NSThread封装性最差,最偏向于底层,主要基于thread使用 GCD是基于C的API,直接使用比较方便,主要基于task使用 NSOperation是基于GCD封装的N

Java版SLG游戏开发--数据的读取及保存

说到SLG游戏开发,无论其如何运转,里面都离不开各种数据的处理,一般来说,游戏越专业,需要处理的数据量将相对越大,类别也分得越细. 游戏离不开美工,也离不开策划,各项参数的专业划分同样是评价一款SLG游戏是否优秀的必要指标之一.所谓的好游戏仅仅画面出彩,配乐一流是绝对不够的,做"靓"很容易,做"专"则很难. 比如日本的超级机器人大战系列,自90年代初开始出现以来,截止到今天为止其中涉及的动漫超过60部,出场知名人物多达600名以上,几乎涵盖了日本所有知名机器人动画的

PS手把手教你快速打造简约的播放器图标

  在做这个图标之前,我首先翻箱倒柜去找了一个古董级MP3来参考一下,请忽略我渣像素的手机. 观察了一下这个MP3,造型实在令人无法恭维.思考了一下,我决定把一体的按键变成五个,科技感会强一些.在这里我画了一个草图,请无视渣画工. 没错,你真的没有看错,我画的就是这么坑.随便拿了个圆珠笔,拿出一张厕纸,不对,在笔记本上撕了一页,然后随便划拉几下,画出我们想要的轮廓. 大神们别打我,毕竟我只是个渣渣. 闲话休提,我们办正事. 新建一个1000*600的文档,设置前景色为白色#ffffff,背景色为