解决:oracle+myBatis ResultMap 类型为 map 时,表字段类型有 Long/Blob/Clob 时报错
前言:最近在做一个通用查询单表的组件,所以 sql 的写法就是 select *,然后 resultType="map" 。如果数据库中的表里有字段类型为 Long 等类型时,mybatis 在执行 sql 时会报错,如果表中有 Blob、Clob 类型在转 json 是也会报错,而且我这里也需要将这几种类型都转为 String 类型到前端。
long 类型 sql 报错:

Blob/Clob 转 json 报错:

解决方案:
自定义 typeHandle 来统一处理数据库这些特殊的字段。
这里 typeHandle 里面使用注解配置 JdbcType 和 JavaType。这两个注解的定义是:
- @MappedTypes 定义的是 JavaType 类型,可以指定哪些 Java 类型被拦截。
- @MappedJdbcTypes 定义的是 JdbcType 类型,它需要满足枚举类 org.apache.ibatis.type.JdbcType 所列的枚举类型。
代码如下:
myBatis 的配置文件中加入:
<typeHandlers>
<!--自定义处理 JdbcType.TIMESTAMP 和 java Object(Data)-->
<typeHandler handler="com.yule.querydb.typehandler.MyObjectTimestampTypeHandle"/>
<!--自定义处理 JdbcType.Clob 和 java Object(String)-->
<typeHandler handler="com.yule.querydb.typehandler.MyObjectClobTypeHandle"/>
<!--自定义处理 JdbcType.Blob 和 java Object(String)-->
<typeHandler handler="com.yule.querydb.typehandler.MyObjectBlobTypeHandle"/>
<!--自定义处理 JdbcType.LONGVARCHAR 和 java Object(String)-->
<typeHandler handler="com.yule.querydb.typehandler.MyObjectLongTypeHandle"/>
</typeHandlers>
这些 typeHandle 类源码:
package com.yule.querydb.typehandler; import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes; import java.io.StringReader;
import java.sql.*; /**
* 自定义处理 JdbcType.Blob 和 java Object(String)
* 处理转 json 报错,将 oracle.sql.Clob 类型转为 String 类型
* copy org.apache.ibatis.type.ClobTypeHandler 类的处理
* @author yule
* @date 2018/10/9 17:57
*/
@MappedTypes({Object.class})
@MappedJdbcTypes(value = {JdbcType.CLOB})
public class MyObjectClobTypeHandle extends BaseTypeHandler<Object> { @Override
public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
String parameterStr = (String) parameter;
StringReader reader = new StringReader(parameterStr);
ps.setCharacterStream(i, reader, parameterStr.length());
} @Override
public Object getNullableResult(ResultSet rs, String columnName) throws SQLException {
String value = "";
Clob clob = rs.getClob(columnName);
if(clob != null) {
int size = (int)clob.length();
value = clob.getSubString(1L, size);
} return value;
} @Override
public Object getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
String value = "";
Clob clob = rs.getClob(columnIndex);
if(clob != null) {
int size = (int)clob.length();
value = clob.getSubString(1L, size);
} return value;
} @Override
public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
String value = "";
Clob clob = cs.getClob(columnIndex);
if(clob != null) {
int size = (int)clob.length();
value = clob.getSubString(1L, size);
} return value;
} }
MyObjectBlobTypeHandle
package com.yule.querydb.typehandler; import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes; import java.io.StringReader;
import java.sql.*; /**
* 自定义处理 JdbcType.Blob 和 java Object(String)
* 处理转 json 报错,将 oracle.sql.Blob 类型转为 String 类型
* copy org.apache.ibatis.type.BlobTypeHandler 类的处理
* @author yule
* @date 2018/10/9 17:57
*/
@MappedTypes({Object.class})
@MappedJdbcTypes(value = {JdbcType.BLOB})
public class MyObjectBlobTypeHandle extends BaseTypeHandler<Object> { @Override
public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
byte[] parameterByteArray = (byte[]) parameter;
String parameterStr = new String(parameterByteArray);
StringReader reader = new StringReader(parameterStr);
ps.setCharacterStream(i, reader, parameterStr.length());
} @Override
public Object getNullableResult(ResultSet rs, String columnName) throws SQLException {
Blob blob = rs.getBlob(columnName);
byte[] returnValue = null;
if(null != blob) {
returnValue = blob.getBytes(1L, (int)blob.length());
} return returnValue == null ? "" : new String(returnValue);
} @Override
public Object getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
Blob blob = rs.getBlob(columnIndex);
byte[] returnValue = null;
if(null != blob) {
returnValue = blob.getBytes(1L, (int)blob.length());
} return returnValue == null ? "" : new String(returnValue);
} @Override
public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
Blob blob = cs.getBlob(columnIndex);
byte[] returnValue = null;
if(null != blob) {
returnValue = blob.getBytes(1L, (int)blob.length());
} return returnValue == null ? "" : new String(returnValue);
}
}
MyObjectLongTypeHandle
package com.yule.querydb.typehandler; import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes; import java.io.StringReader;
import java.sql.*; /**
* 自定义处理 JdbcType.LONGVARCHAR 和 java Object(String)
* 处理转 mybatis 执行返回map的sql 报错,将 oracle Long 型转为 String 类型
* @author yule
* @date 2018/10/9 19:18
*/
@MappedTypes({Object.class, String.class})
@MappedJdbcTypes(value = {JdbcType.LONGVARCHAR})
public class MyObjectLongTypeHandle extends BaseTypeHandler<Object> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
String parameterStr = (String) parameter;
StringReader reader = new StringReader(parameterStr);
ps.setCharacterStream(i, reader, parameterStr.length());
} @Override
public Object getNullableResult(ResultSet rs, String columnName) throws SQLException {
String str = rs.getString(columnName);
return str != null ? str : "";
} @Override
public Object getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
String str = rs.getString(columnIndex);
return str != null ? str : "";
} @Override
public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
String str = cs.getString(columnIndex);
return str != null ? str : "";
}
}
解决:oracle+myBatis ResultMap 类型为 map 时,表字段类型有 Long/Blob/Clob 时报错的更多相关文章
- 解决:oracle+myBatis ResultMap 类型为 map 时返回结果中存在 timestamp 时使用 jackson 转 json 报错
前言:最近在做一个通用查询单表的组件,所以 sql 的写法就是 select *,然后 resultType="map" ,然后使用 jackson @ResponseBody 返 ...
- 解决Oracle 11g在用EXP导出时,空表不能导出
实践结论可行,看"2.解决办法" 一.问题原因: 11G中有个新特性,当表无数据时,不分配segment,以节省空间 1.insert一行,再rollback就产生 ...
- 【转】解决Oracle 11g在用EXP导出时,空表不能导出
一.问题原因: 11G中有个新特性,当表无数据时,不分配segment,以节省空间 .insert一行,再rollback就产生segment了. 该方法是在在空表中插入数据,再删除,则产生segme ...
- oracle查看某表字段类型
来源:https://www.cnblogs.com/ufindme/p/5033843.html 今天遇到一个问题:要求在可重复执行的SQL脚本添加一段SQL代码:修改当前的数据类型.因为SQL代码 ...
- 通过jdbc获取数据库中的表结构 主键 各个表字段类型及应用生成实体类
http://www.cnblogs.com/lbangel/p/3487796.html 1.JDBC中通过MetaData来获取具体的表的相关信息.可以查询数据库中的有哪些表,表有哪些字段,字段的 ...
- SQLSERVER创建该存储过程时不会出错,但是执行存储过程时报错
创建该存储过程时,不会出错,但是执行存储过程时,会报出下面这样的错误 这是因为在存储过程创建时,它先做语法检查,如果通过了语法检查,它会尝试解析它包含的对象名,如果存在也会解析该对象引用的对象是否存在 ...
- MySQL建表字段类型
1.数据库:在MySQL中,要存储数据,必须从数据库开始,因此首先要创建数据库,但由于学校的MySQL服务器对学生数据帐号有限止,学生不得创建数据库,故每个学生的帐号中已事先由信息中心为大家建立了一个 ...
- SqlBulkCopy 批量导入数据 转换表字段类型
在使用SqlBulkCopy导入数据时,要有一个跟数据库里面同样的DataTable 要赋值表名 要求每个列跟数据库中列同名,并且列的类型要赋值跟数据库中列的类型对应的NET类型 要求数据库中为Nul ...
- 使用SQL语句查询表及表字段类型说明
今天突然遇到有人要数据库表及表字段说明,数据库表太多又不能一个个表去找,就想想SQL是否能直接查询出来. 经过查询资料,加上一些自己的一些调整写了一个sql语句,在此记录一下,以方便日后查找使用. S ...
随机推荐
- AJPFX技术分析入门
AJPFX:技术分析入门 技术分析就是指通过考察历史数据来预测未来价格走向.外汇市场是非常讲技术分析的,而且分析师的基本功就是技术分析,但是,没有对基本面的准确把握,技术分析就会含糊.但是技术分析究其 ...
- Flask系列09--Flask中WTForms插件,及自定义验证器
一.概述 django中的forms组件非常的方便,在flask中有WTForms的组件实现的也是类似的功能, 安装这个插件 二.简单使用 文档地址https://wtforms.readthedoc ...
- " XSS易容术---bypass之编码混淆篇+辅助脚本编写"
一.前言本文原创作者:vk,本文属i春秋原创奖励计划,未经许可禁止转载!很多人对于XSS的了解不深.一提起来就是:“哦,弹窗的”.”哦,偷cookie的.”骚年,你根本不知道什么是力量.虽然我也不知道 ...
- JS生成某个范围的随机数【四种情况详解】
JS没有现成的函数,能够直接生成指定范围的随机数. 但是它有个函数:Math.random() 这个函数可以生成 [0,1) 的一个随机数. 利用它,我们就可以生成指定范围内的随机数. 而涉及范围的 ...
- python学习笔记10-文件操作
能调用方法的一定是对象.文件本身也是一个对象.有很多自己内置的方法 #操作文件第一件事 建立文件对象 open函数 # 参数一:文件路径 绝对路径和相对路径都可以 # 参数二:模式选择 ‘r’ 读模式 ...
- Unity C# .Net List 优化点
Unity C# .Net List 优化点 已知长度 则初始化指定长度 调用多次Remove会导致内存浪费 调用TrimExcess释放多余内存 List代码实现原理 使用数组保存泛型数据 代码 L ...
- Redis学习系列六ZSet(有序列表)及Redis数据结构的过期
一.简介 ZSet可以说是Redis中最有趣的数据结构了,因为他兼具了Hash集合和Set的双重特性,也是用的最多的,保证了value值的唯一性的同时,,同时又保证了高性能,最主要的是还可以给每个Va ...
- 使用vue开发微信公众号下SPA站点的填坑之旅
原文发表于本人博客,点击进入使用vue开发微信公众号下SPA站点的填坑之旅 本文为我创业过程中,开发项目的填坑之旅.作为一个技术宅男,我的项目是做一个微信公众号,前后端全部自己搞定,不浪费国家一分钱^ ...
- [Java初探外篇]__关于时间复杂度与空间复杂度
前言 我们在前面的排序算法的学习中了解到了,排序算法的分类,效率的比较所使用到的判断标准,就包括时间复杂度和空间复杂度,当时因为这两个定义还是比较难以理解的,所以决定单独开一篇文章,记录一下学习的过程 ...
- JAVA+SELENIUM+MAVEN+TESTNG框架(二)新建项目
1.新建maven项目 2.下载selenium的jar包,放入maven依赖库中 3.新增testng依赖库,build path->add libirary->testng 4.查看自 ...