- 浏览: 7948823 次
- 性别:
- 来自: 广州
文章分类
- 全部博客 (2425)
- 软件工程 (75)
- JAVA相关 (662)
- ajax/web相关 (351)
- 数据库相关/oracle (218)
- PHP (147)
- UNIX/LINUX/FREEBSD/solaris (118)
- 音乐探讨 (1)
- 闲话 (11)
- 网络安全等 (21)
- .NET (153)
- ROR和GOG (10)
- [网站分类]4.其他技术区 (181)
- 算法等 (7)
- [随笔分类]SOA (8)
- 收藏区 (71)
- 金融证券 (4)
- [网站分类]5.企业信息化 (3)
- c&c++学习 (1)
- 读书区 (11)
- 其它 (10)
- 收藏夹 (1)
- 设计模式 (1)
- FLEX (14)
- Android (98)
- 软件工程心理学系列 (4)
- HTML5 (6)
- C/C++ (0)
- 数据结构 (0)
- 书评 (3)
- python (17)
- NOSQL (10)
- MYSQL (85)
- java之各类测试 (18)
- nodejs (1)
- JAVA (1)
- neo4j (3)
- VUE (4)
- docker相关 (1)
最新评论
-
xiaobadi:
jacky~~~~~~~~~
推荐两个不错的mybatis GUI生成工具 -
masuweng:
(转)JAVA获得机器码的实现 -
albert0707:
有些扩展名为null
java 7中可以判断文件的contenttype了 -
albert0707:
非常感谢!!!!!!!!!
java 7中可以判断文件的contenttype了 -
zhangle:
https://zhuban.me竹板共享 - 高效便捷的文档 ...
一个不错的网络白板工具
http://blog.csdn.net/renfufei/article/details/44887371
众所周知,Oracle有很多坑, 所以才有了去IOE。
在使用Druid做数据库连接池后,其实偶尔也会碰到小坑,这就是使用开源项目所必须去填平的。【如果使用不开源的产品,那就不是坑,而是陷阱了,你都不知道怎么去填坑】
用Druid连接池,通过JDBC往Oracle数据库的Clob字段插入数据,或者更新数据时,一个问题出现了。
类似于这样:
Caused by: java.lang.ClassCastException: com.alibaba.druid.proxy.jdbc.ClobProxyImpl cannot be cast to oracle.sql.CLOB
at oracle.jdbc.driver.OraclePreparedStatement.setClob(OraclePreparedStatement.java:7919)
at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_setClob(FilterChainImpl.java:2978)
at com.alibaba.druid.filter.FilterAdapter.preparedStatement_setClob(FilterAdapter.java:1178)
at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_setClob(FilterChainImpl.java:2975)
at com.alibaba.druid.filter.FilterAdapter.preparedStatement_setClob(FilterAdapter.java:1178)
at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_setClob(FilterChainImpl.java:2975)
at com.alibaba.druid.proxy.jdbc.PreparedStatementProxyImpl.setClob(PreparedStatementProxyImpl.java:255)
at com.alibaba.druid.pool.DruidPooledPreparedStatement.setClob(DruidPooledPreparedStatement.java:588)
... 63 more
然后, 参考网上的文章,切换成 StringReader 以后又出现了字符串过长的问题,只好断点调试找BUG了,然后发现了一个方法:
ClobProxyImpl#getRawClob()
1
那么问题来了,也解决了。 代码贴出来如下所示:
package com.cncounter.util.solution.processor;
import java.sql.Clob;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class ClobProcessor {
public static final String JDBC_TYPE_CLOB = "clob";
public boolean processSolutionType(PreparedStatement statement, int order,
String jdbcType, Object paramValue) {
boolean result = false;
if(null == statement || order < 1){
return result;
}
//
String value = "";
if(null != paramValue){
value = paramValue.toString();
}
//
try {
if(JDBC_TYPE_CLOB.trim().equalsIgnoreCase(jdbcType)){
//
Clob clob = null;
if(paramValue instanceof Clob){
clob = (Clob)paramValue;
} else {
clob = statement.getConnection().createClob();
// 从 1 开始
clob.setString(1, value);
}
// 阿里巴巴的坑
if(clob instanceof com.alibaba.druid.proxy.jdbc.ClobProxyImpl){
com.alibaba.druid.proxy.jdbc.ClobProxyImpl impl = (com.alibaba.druid.proxy.jdbc.ClobProxyImpl)clob;
clob = impl.getRawClob(); // 获取原生的这个 Clob
}
statement.setClob(order, clob);
//
// 请注意, StringReader有坑,字段超过5万或者多少之后,就报错了. 所以注释了
// MyBatis的Clob类型也是这个BUG,如果不使用Clob,直接默认String,则Mybatis不报错
//StringReader reader = new StringReader(value);
//Reader reader = clob.getCharacterStream();
// 设置输出流
//statement.setCharacterStream(order, reader, value.length());
} else {
statement.setString(order, value);
}
result = true;
} catch (SQLException e) {
throw new RuntimeException("设置["+jdbcType+"]类型出错!", e);
}
//
return result;
}
}
分析了下原因,大概Druid是因为Clob有什么需要处理的,就增加了一个代理类: com.alibaba.druid.proxy.jdbc.ClobProxyImpl ; Blob就没有。
然后呢,Oracle也比较粗暴,setClob() 里面直接强转为 oracle.sql.CLOB。于是问题就出现了。
另外值得一提的是MyBatis的Clob类型有BUG,在上面的代码注释之中也提醒了,属于是 StringReader 的坑,反正谁用谁知道。 我们的处理策略是, 在 xml 之中不指定 jdbcType,由MyBatis自己判断,当成String处理就不报错,然后也就不管了。
众所周知,Oracle有很多坑, 所以才有了去IOE。
在使用Druid做数据库连接池后,其实偶尔也会碰到小坑,这就是使用开源项目所必须去填平的。【如果使用不开源的产品,那就不是坑,而是陷阱了,你都不知道怎么去填坑】
用Druid连接池,通过JDBC往Oracle数据库的Clob字段插入数据,或者更新数据时,一个问题出现了。
类似于这样:
Caused by: java.lang.ClassCastException: com.alibaba.druid.proxy.jdbc.ClobProxyImpl cannot be cast to oracle.sql.CLOB
at oracle.jdbc.driver.OraclePreparedStatement.setClob(OraclePreparedStatement.java:7919)
at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_setClob(FilterChainImpl.java:2978)
at com.alibaba.druid.filter.FilterAdapter.preparedStatement_setClob(FilterAdapter.java:1178)
at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_setClob(FilterChainImpl.java:2975)
at com.alibaba.druid.filter.FilterAdapter.preparedStatement_setClob(FilterAdapter.java:1178)
at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_setClob(FilterChainImpl.java:2975)
at com.alibaba.druid.proxy.jdbc.PreparedStatementProxyImpl.setClob(PreparedStatementProxyImpl.java:255)
at com.alibaba.druid.pool.DruidPooledPreparedStatement.setClob(DruidPooledPreparedStatement.java:588)
... 63 more
然后, 参考网上的文章,切换成 StringReader 以后又出现了字符串过长的问题,只好断点调试找BUG了,然后发现了一个方法:
ClobProxyImpl#getRawClob()
1
那么问题来了,也解决了。 代码贴出来如下所示:
package com.cncounter.util.solution.processor;
import java.sql.Clob;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class ClobProcessor {
public static final String JDBC_TYPE_CLOB = "clob";
public boolean processSolutionType(PreparedStatement statement, int order,
String jdbcType, Object paramValue) {
boolean result = false;
if(null == statement || order < 1){
return result;
}
//
String value = "";
if(null != paramValue){
value = paramValue.toString();
}
//
try {
if(JDBC_TYPE_CLOB.trim().equalsIgnoreCase(jdbcType)){
//
Clob clob = null;
if(paramValue instanceof Clob){
clob = (Clob)paramValue;
} else {
clob = statement.getConnection().createClob();
// 从 1 开始
clob.setString(1, value);
}
// 阿里巴巴的坑
if(clob instanceof com.alibaba.druid.proxy.jdbc.ClobProxyImpl){
com.alibaba.druid.proxy.jdbc.ClobProxyImpl impl = (com.alibaba.druid.proxy.jdbc.ClobProxyImpl)clob;
clob = impl.getRawClob(); // 获取原生的这个 Clob
}
statement.setClob(order, clob);
//
// 请注意, StringReader有坑,字段超过5万或者多少之后,就报错了. 所以注释了
// MyBatis的Clob类型也是这个BUG,如果不使用Clob,直接默认String,则Mybatis不报错
//StringReader reader = new StringReader(value);
//Reader reader = clob.getCharacterStream();
// 设置输出流
//statement.setCharacterStream(order, reader, value.length());
} else {
statement.setString(order, value);
}
result = true;
} catch (SQLException e) {
throw new RuntimeException("设置["+jdbcType+"]类型出错!", e);
}
//
return result;
}
}
分析了下原因,大概Druid是因为Clob有什么需要处理的,就增加了一个代理类: com.alibaba.druid.proxy.jdbc.ClobProxyImpl ; Blob就没有。
然后呢,Oracle也比较粗暴,setClob() 里面直接强转为 oracle.sql.CLOB。于是问题就出现了。
另外值得一提的是MyBatis的Clob类型有BUG,在上面的代码注释之中也提醒了,属于是 StringReader 的坑,反正谁用谁知道。 我们的处理策略是, 在 xml 之中不指定 jdbcType,由MyBatis自己判断,当成String处理就不报错,然后也就不管了。
发表评论
-
复习:强迫线程顺序执行方式
2019-01-03 23:42 1587方法1: 三个线程,t1,t2,t3,如果一定要按顺序执行, ... -
(转)不错的前后端处理异常的方法
2019-01-02 23:16 2021前言 在 Web 开发中, 我们经常会需要处理各种异常, 这是 ... -
info q的极客时间大咖说等资料下载
2018-08-15 08:40 3474info q的极客时间大咖说等资料下载,还有不少思维导图 链 ... -
CXF 客户端超时时间设置(非Spring配置方式)
2018-07-03 22:38 2238import org.apache.cxf.endpoint. ... -
(转)synchronized关键字画像:正确打开方式
2018-06-14 09:25 492https://mp.weixin.qq.com/s/b3Sx ... -
CountDownLatch的例子
2018-06-13 14:10 694public class StatsDemo { ... -
两道面试题,带你解析Java类加载机制
2018-06-12 16:29 617https://mp.weixin.qq.com/s/YTa0 ... -
Spring中获取request的几种方法,及其线程安全性分析
2018-06-11 09:03 672https://mp.weixin.qq.com/s/KeFJ ... -
内部类小结
2018-06-06 10:25 439https://mp.weixin.qq.com/s/hErv ... -
JVM虚拟机小结1
2018-06-04 20:43 5451 jps -l //列出详细的类名和进程ID 2)jps ... -
windows下自带命令行工具查看CPU资源情况等
2018-06-04 12:53 3108微软提供了不少命令行 ... -
(收藏)深入分析Java的序列化与反序列化
2018-05-30 15:21 620https://mp.weixin.qq.com/s/T2Bn ... -
apache common包中的序列化工具
2018-05-30 09:10 1846什么是序列化 我们的 ... -
JAVA8 JVM的变化: 元空间(Metaspace)
2018-05-24 22:30 969本文将会分享至今为至我收集的关于永久代(Permanent G ... -
(转)服务器性能指标(一)——负载(Load)分析及问题排查
2018-05-21 21:03 1368原创: Hollis Hollis 负载 ... -
(转)对象复用
2018-05-20 15:27 866public class Student { priv ... -
mapreduce中入门中要注意的几点
2018-05-06 08:59 675在 mapreduce中,比如有如下的词: I love b ... -
HDFS的基本操作
2018-05-02 21:47 942-mkdir 在HDFS创建目录 ... -
一个不错的开源工具类,专门用来解析日志头部的,好用
2018-05-02 20:00 774一个不错的开源工具类,专门用来解析日志头部的,好用。 http ... -
介绍个不错的RESTFUL MOCK的工具wiremock
2018-04-27 21:02 1909介绍个不错的RESTFUL MOCK的工具wiremock,地 ...
相关推荐
总的来说,这个项目展示了如何利用SpringBoot的灵活性和强大功能,结合Oracle和MySQL的特点,以及Druid的数据连接池优势,实现大规模数据的双数据库同步,同时通过流处理策略有效地避免了内存溢出的问题。...
本篇将详细讲解如何在Spring Boot项目中结合Mybatis和Druid实现多数据源配置,以支持Oracle和MySQL两种数据库,并进行数据库的分离调试。 首先,我们要理解Spring Boot的自动配置机制。Spring Boot通过扫描`@...
SpringMVC+Druid+Oracle配置-附件资源
总结起来,通过SpringBoot、Mybatis-Plus和Druid,我们可以方便地实现双数据源配置,使得应用能同时处理MySQL和Oracle数据库的数据。在实际开发中,要根据业务场景灵活切换数据源,确保数据操作的正确性和效率。同时...
参考这个https://mrbird.cc/Spring-Boot-MyBatis Druid.html做的 配置多个数据源同时访问mysql和oracle数据库 互相交换数据 个人学习用 仅供参考 欢迎指教
在MySQL支持上,Druid1.1.22能够很好地兼容各种MySQL版本,包括事务、存储过程、触发器等功能。它还支持MySQL的JDBC驱动自动切换,当主库发生故障时,可以无缝切换到备库,确保服务的高可用性。 对于Oracle数据库,...
使用ssl的tcp_ip连接oracle数据库
可以帮助你了解,以及配置实现DruidDataSource数据源的配置
4. 支持多种数据库:除了MySQL,Druid还支持Oracle、SQL Server、PostgreSQL等多种主流数据库。 三、Druid源码分析 1. ConnectionWrapper:Druid对JDBC的Connection接口进行了封装,实现了连接池的特性,如连接的...
当我们需要在一个系统中同时处理来自多个不同数据库的数据时,如MySQL和Oracle,就需要实现多数据源的支持。本项目正是以此为目标,结合Spring Boot和Druid,构建了一个能够同时操作两种不同类型数据库的示例。 ...
9. 支持多种数据库:Druid不仅支持MySQL,还支持Oracle、PostgreSQL、SQL Server等多种主流数据库,具有很好的兼容性和适应性。 通过阅读Druid-1.2.8的源码,我们可以了解其设计思想和实现原理,如线程安全的实现、...
【druid&ojdbc jar包】是两个在Java开发中常用的库文件,分别用于数据库连接管理和Oracle数据库的连接。这两个jar包在Java应用程序尤其是企业级应用中扮演着至关重要的角色。 1. Druid(德鲁伊): Druid是阿里巴巴...
本示例主要介绍如何使用Druid 1.0.1版本作为数据库连接池来连接Oracle数据库,并进行基本的数据库操作,如建表、初始化数据和查询数据。 Druid是一个开源的数据库连接池组件,由阿里巴巴开发并维护,以其高性能、...
当一个请求需要数据库连接时,Druid会从连接池中分配一个已经建立好的连接,而不是每次都创建新的连接。这大大降低了数据库的负载,并减少了应用的响应时间。此外,Druid还具备连接池的健康检查和自动回收机制,确保...
4. **数据源扩展性**: Druid支持多种数据库,包括MySQL、Oracle、SQL Server等,并且容易扩展支持其他数据库。此外,它还支持读写分离、主备切换等高级特性,适应高可用和高并发的系统需求。 5. **日志与警告**: ...
以上是关于"druid-1.2.8.jar"的基本介绍和主要特性,作为一款优秀的数据库连接池,Druid在性能、稳定性和扩展性上都有出色的表现,深受广大Java开发者喜爱。在日常开发和运维中,合理配置和使用Druid能够有效提升...
5. **兼容性**:Druid支持多种主流的数据库,如MySQL、Oracle、SQL Server、PostgreSQL等,标签中的"jdbc mysql java"表明Druid与Java JDBC API兼容,并特别针对MySQL进行了优化。 在实际应用中,Druid通常作为...
Druid是阿里巴巴开源的一个高效、强大的数据库连接池组件,它的全称是Dynamic Routing Data Source,即动态路由数据源。在Java Web开发中,数据库连接池扮演着至关重要的角色,它负责管理数据库连接,提高数据库操作...