Oracle9i 长字符串存储的经验总结
- 博客分类:
- 技术杂绘
项目从MySQL 到Oracle迁移,针对一个长字符串(中文字数大概有1000以上,不到1w)的存储,经历来太多的波折,终于搞定。
以下是我的一些经验总结
本文中的测试表设计如下:
CREATE TABLE TZB.test_table (
test_id NUMBER(20,0) NOT NULL,
short_str varchar(2000 CHAR) default NULL,
middle_string varchar(4000 CHAR) default NULL,
PRIMARY KEY ( test_id )
) ;
1:如果字符串中文长度在2000或者以下,可以直接使用varchar2(2000 char)。
(1)在使用ojdbc14.jar的情况下,
在使用Statement方式插入时,定义为2000 char的数据列,可以插入2000个中文字符,但是通过PL/SQL是看不到该行。只能插入2000个英文字符。
在使用PreparedStatement方式插入时,定义为2000 char的数据列,可以通过批处理插入字符串长度小于或等于666个中文字符。
当汉字字符串长度大于666,插入数据必须使用流式方式,且最大长度不能超过2000个中文字符。当采用流式方式插入数据时,不能使用批处理。
原因是PreparedStatement.setString(index, StringValue)方法对StringValue的char长度有限制,并且一个中文字符占3个char,故只能输入666个汉字。
插入英文字符时,至多只能插入2000个。
(2)在使用ojdbc6.jar的情况下
在使用Statement方式插入时,定义为2000 char的数据列,可以插入2000个中文字符,但是通过PL/SQL是看不到该行。只能插入2000个英文字符。
在使用PreparedStatement方式插入时,可以插入2000个中文字符或者4000个英文字符,并且可以使用批处理,对英文字符串是否采用流式处理,没有限制。
(3)批处理的方法如下:
String test_str="这是一个测试字符串......";
String sql_insert = "insert into tzb.test_table (test_id, short_str) values (?,?)";
Connection conn = null;
PreparedStatement pstmt = null;
Statement stmt=null;
try {
conn= ......; //获取链接
pstmt = conn.prepareStatement(sql_insert);
for(int i=8; i字符串......";
String sql_insert = "insert into tzb.test_table (test_id, short_str) values (?,?)";
......
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn= ......; //获取链接
pstmt = conn.prepareStatement(insert_sql);
pstmt.setLong(1, 12);
//这里的length不是字符串.length(),而是有多少个char。很多人避免计算char长度,直接写成4000。
pstmt.setCharacterStream(2, new StringReader(需要保存的字符串), length);
//pstmt.setCharacterStream(2, new StringReader(需要保存的字符串), 4000);
pstmt.execute();
pstmt.close();
} catch (Exception e) {
// 异常处理,如
e.printStackTrace();
}finally{
try{
pstmt.close();
//关闭连接。如果使用连接池,则应归还连接
conn.close();
}catch(Exception e){
// 异常处理
}
}
2、当插入的字符串长度大于2000不多余4000 char时,可以直接使用varchar2(4000 char)。
(1)使用ojdbc14.jar时,
在直接使用Statement方式插入时,test_str最大长度可达2000个中文字符,4000个英文字符。
在使用PreparedStatement方式插入时,定义为4000 char的数据列,可以通过批处理插入字符串长度小于或等于666个中文字符。
当汉字字符串长度大于666,插入数据必须使用流式方式,但不能用批处理,且最大长度不能超过2000个中文字符。
插入英文字符时,当英文字符长度超过2000,必须采用流式方式,且至多只能插入4000个。
(2)在使用ojdbc6.jar时,无论使用流式存储与否,插入的字符串汉字长度不能超过2000,但可以插入4000个英文字符。
3:如果字符串长度不是很长,一个字段又装不下,可以将一个字符串分解成几段分别存储在数据表中,读取时进行合并即可。
4:如果使用了Spring2.5+Hibernate3框架,最好使用Spring提供的透明处理Clob的方法,这样将更加容易移植程序而不用修改代码。
具体做法如下:
1).在sessionFactory中加入lobHandler的注射:
xxx.hbm.xml
.....
dataSource是数据源Bean的配置,且有一定的限制。
(1)数据库为oracle9i,驱动程序使用ojdbc14.jar,在使用dbcp连接池的情况下,会抛异常:
org.springframework.transaction.TransactionSystemE xception: Could not roll back Hibernate transaction;
Caused by: org.hibernate.TransactionException: JDBC rollback failedorg.hibernate.Transaction:JDBC rollback failed
Caused by: java.sql.SQLException: Io 异常: Connection reset by peer: socket write error
(2)数据库为oracle9i,在本段介绍的解决方案中不能使用C3P0连接池(不管使用ojdbc14.jar,或者ojdbc6.jar),否则将抛出异常:
org.springframework.dao.InvalidDataAccessApiUsageE xception: OracleLobCreator needs to work on [oracle.jdbc.OracleConnection], not on [com.mchange.v2.c3p0.impl.NewProxyConnection]
Caused by: java.lang.ClassCastException: com.mchange.v2.c3p0.impl.NewProxyConnection cannot be cast to oracle.jdbc.OracleConnection
(3)使用JNDI数据源(暂时没有用过)
2).定义这个lobHandler,值得注意的是这里有Oracle的版本区别:
因为Oracle9i处理Clob的方式和别的数据库很不一样,甚至与Oracle10g都不兼容,所以这里要用spring提供的SimpleNativeJdbcExtractor.如果使用Oracle10g的话,可以直接使用:
对应的应该使用Oracle10g对应的JDBC驱动.
3).在领域对象的hbm中对应的Clob字段应该使用这样的定义:
该字段在领域对象中直接申明成String就可以了.当对这个字段写入长数据时直接调用其set方法就可以了,Spring会自己帮你做余下的处理,让你透明的处理Clob字段.
4).DAO层或者业务逻辑层对该字段的操作必须需要在有事务管理的方法中使用
发表评论
-
win7自带的正则表达式验证工具----powershell
2012-07-06 09:45 993最近项目中要用正则表达式,忽然想起powershell可以 ... -
java正则表达式学习总结,以及和javascript正则表达式的区别
2012-07-06 09:37 746用正则表达式处理字符串功能非常强大,下面总结一下java正 ... -
Android源代码下载与编译
2012-07-06 09:30 760使用repo下载官方http://android.git. ... -
asp.net中实现证件照拍照
2012-07-05 20:45 868以下代码需要用到最新版本ImageCapOnWeb控件,天 ... -
核心Swing组件(四)
2012-07-03 13:43 630Icon接口用来将图标 ... -
mx_internal变量读取和设置
2012-07-02 10:54 655Flex中很多组件的变量都有mx_internal命名空间 ... -
遮罩的使用
2012-07-02 10:54 582有N个按钮又不想其导航栏出现烦人的滚动条。 解决方法 ... -
柱状图
2012-07-02 10:54 618Main application file: fl ... -
实战 OpenLaszlo 与 db4o
2012-07-02 10:54 641本文于去年年底完 ... -
Flex 开发框架汇总
2012-07-01 00:34 574现有成熟常用的Flex ... -
Flex DivideBox
2012-07-01 00:33 494用户操作 [留言] [发消息] [加为好友] ... -
ArcGIS API for Flex and ArcGIS Viewer for Flex 2.2 发布
2012-07-01 00:33 605主要改进如下: 1 支持ArcGIS.com Web Ma ... -
免费NET&C#开发参考资料合辑
2012-07-01 00:33 824用户操作 [留言] [发消息] [加为好友] ... -
使用AJAX的十大理由
2012-07-01 00:33 580使用AJAX的十大理由: 10。XAML, XUL, ...
相关推荐
oracle中操作字符串(带有,的字符串,从中取出“:”前面或后面的值)
oracle 9i所有版本最新下载链接 直接迅雷下载 Oracle9i Database Release 2 Enterprise/Standard/Personal Edition for Windows NT/2000/XP ...
C#连接Oracle数据库字符串 C#连接Oracle数据库字符串
Oracle 9i Client (Oracle 9i 客户端) 简化版 (不安装Oracle客户端,也可以使用PLSQL Developer 不用安装Oracle客户端也可以使用PLSQL Developer 绿色! 安全! 轻便! 可靠! 1、本软件可作为简单的Oracle9i客户端...
介绍了将多行转为字符串的三种方案,并比较了三种方案的执行效率. 1.sys_connect_by_path + start with ... connect by ... prior + 分析函数 2.自定义Function/SP 3.使用 Oracle 10g 内置函数 wmsys.wm_concat
oracle9i物理结构,oracle9i物理结构,oracle9i物理结构,oracle9i物理结构,oracle9i物理结构,oracle9i物理结构
oracle,按特定字符,截取字符串,直接出结果 oracle,按特定字符,截取字符串,直接出结果oracle,按特定字符,截取字符串,直接出结果
Oracle接收长度大于4000的字符串 Oracle接收长度大于4000的字符串
Oracle拆分字符串,字符串分割的函数,将返回一个表格,如果有需要的可以下载去看看。
select f_find('Ap@2233ll@@l@@','@') from dual 返回结果为5,代表‘@’在该字符串中出现5次。 同理 select f_find('Ap@223SWEQQQ3ll@@l@@','Q') from dual---返回3,代表Q在字符串中出现了3次, select f_find('我...
例如:字段为1,2,3,4,5 截取之后为 1 2 3 4 5
传入一个字符串和该字符串的分割字符,返回去重后的字符串,可以直接在plsql中运行,简单的函数运用,能处理oracle中。资源仅供参考
oracle通过sql实现字符串转数字oracle函数,可用于字符串的最终排序
oracle9i下载地址, 分三个IOS文件, 加压即可安装.
Oracle 数据库连接字符串大全教程,含异地或服务器数据库连接,亲测可用,实用!
Oracle9i的开发学习资料,PDF中文版,非扫描版,13章全,附带8个章节使用的SQL语句和代码。...第十一章 存储管理 深入Oracle9i核心 第十二章 数据安全 备份与恢复实战 第十三章 性能优化 通向OCP之路
• 在.NET中调用Oracle9i存储过程经验 • Windows下Oracle9i数据库文件的自 • 图解Oracle9i在Windows2000下的安 • Linux环境下oracle9i的Dataguard配 • 修改oracle9i数据库字符集的方法 • windows优化系统...
oracle拼接字符串查询语句。 普通拼接字符串和拼接某一列的所有值。
ORACLE字符串函数ORACLE字符串函数ORACLE字符串函数
在实际工作中经常遇到截取两个相同字符串之间的字符的oracle问题,以下是相关语句