惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

I
Intezer
V
Vulnerabilities – Threatpost
Google Online Security Blog
Google Online Security Blog
T
The Exploit Database - CXSecurity.com
C
CXSECURITY Database RSS Feed - CXSecurity.com
AWS News Blog
AWS News Blog
G
GRAHAM CLULEY
P
Privacy & Cybersecurity Law Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
C
Cybersecurity and Infrastructure Security Agency CISA
N
News | PayPal Newsroom
T
Tenable Blog
Spread Privacy
Spread Privacy
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
S
Secure Thoughts
P
Privacy International News Feed
IT之家
IT之家
Project Zero
Project Zero
T
The Blog of Author Tim Ferriss
Engineering at Meta
Engineering at Meta
大猫的无限游戏
大猫的无限游戏
博客园_首页
GbyAI
GbyAI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
量子位
雷峰网
雷峰网
Apple Machine Learning Research
Apple Machine Learning Research
Hacker News: Ask HN
Hacker News: Ask HN
Google DeepMind News
Google DeepMind News
MongoDB | Blog
MongoDB | Blog
N
Netflix TechBlog - Medium
Martin Fowler
Martin Fowler
NISL@THU
NISL@THU
I
InfoQ
D
DataBreaches.Net
有赞技术团队
有赞技术团队
K
Kaspersky official blog
Security Latest
Security Latest
The Register - Security
The Register - Security
Hugging Face - Blog
Hugging Face - Blog
S
Security @ Cisco Blogs
P
Proofpoint News Feed
M
MIT News - Artificial intelligence
H
Hackread – Cybersecurity News, Data Breaches, AI and More
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
AI
AI
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
P
Proofpoint News Feed
Security Archives - TechRepublic
Security Archives - TechRepublic
N
News and Events Feed by Topic

博客园 - 飞翔

杂记 VI使用技巧 浮躁,太浮躁了 有空看看的一些技术文章 工作流概述 JavaMail 应用 - 飞翔 - 博客园 权限系统概要 --转 看的的有意思的帖子收集 动态编译JAVA程序 Log4j基本使用方法 dom4j 读取xml文件时遇到的怪问题(org.dom4j.DocumentException: no protocol) 多线程 Thread 学习杂记 Oracle插入大量文字 Struts menu的使用(动态数据) 网页 的一些信息 - 飞翔 - 博客园 Struts Validator验证器使用指南 错误汇总 谈IFRAME标签的使用 appfuse 杂记 - 飞翔 - 博客园
spring+hibernate 处理oracle clob (编辑中)
飞翔 · 2005-10-11 · via 博客园 - 飞翔

这几天由于项目需要,处理oracle Clob类型的数据,由于使用的是hibernate,网络上找的文章有太多是讲的hibernate1.x时代的了,通常都是一个强制转化为oracle.sql.CLOB /BLOB,结果当然是不行,因为hibernate2,3封装了一层,返回的实际上是hibernate.SerializableClob...  ,还看了一些hibernate UserType的使用,但总有局限性,比如版本要求,服务器要求。。。  
        现总结对比如下几种操作方法 :
大的范围来讲有两种驱动:oci,thin方式,oci本身支持>4k字节的传输,处理相对比较方便,但是要求连接数据库的一端必须安装oracle客户端环境(配置本地NET服务名
url: jdbc:oracle:oci8:@oracle )

如果想传输大于4K字节的数据,请使用OCI驱动,用HIBERNATE如果不获得ORACLE的CLOB实现,无法传输超过4K字节的数据;

方法一。
Hibernate 映射文件:

            name="clob_content"
            type="java.sql.Clob"
            update="true"
            insert="true"
            column="content"
            not-null="false"/>
JAVABEAN:   private java.sql.Clob clob_content;
                          

DaoImp:

public void saveItem(Item item) {
 
 String str = item.getContent();
   
  item.setClob_content(Hibernate.createClob(str));//这里构造了该clob,并设置到object中去
  getHibernateTemplate().saveOrUpdate(item);
  getHibernateTemplate().flush();
 }

public Item getItem(Long itemId) {
  Item item = (Item) getHibernateTemplate().get(Item.class, itemId);
if(item!=null){
   java.sql.Clob clob = item.getClob_content();
   Strint tempStr = clob.getSubString(1, (int) clob.length());
   item.setContent(tempStr);
  }
  return item;
 }

方法二:使用hibernate的用户类型 (参考:http://www.hibernate.org/76.html)
  (1)Hibernate 映射文件:

            name="clob_content"
            type="StringClobType"
            column="content"  
         />   
 (2)javabean:     private String clob_content;

 (3)
/* StringClobType类源码*/
import java.io.IOException;
import java.io.Reader;
import java.io.Serializable;
import java.io.StringReader;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.sql.Clob;

import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.usertype.*;

public class StringClobType implements UserType {
 public int[] sqlTypes() {
  return new int[] { Types.CLOB };
 }

 public Class returnedClass() {
  return String.class;
 }

 public boolean equals(Object x, Object y) {
  return (x == y) || (x != null && y != null && (x.equals(y)));
 }

 public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
  Reader reader = rs.getCharacterStream(names[0]);
  if (reader == null)
   return null;

  StringBuffer sb = new StringBuffer();
  try {
   char[] charbuf = new char[4096];
   for (int i = reader.read(charbuf); i > 0; i = reader.read(charbuf)) {
    sb.append(charbuf, 0, i);
   }
  } catch (IOException e) {
   throw new SQLException(e.getMessage());
  }
  return sb.toString();
 }

 public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
  if (value != null) {
   StringReader r = new StringReader((String) value);
   st.setCharacterStream(index, r, ((String) value).length());
  } else {
   st.setNull(index, sqlTypes()[0]);
  }
 }

 public Object deepCopy(Object value) {
  if (value == null)
   return null;
  return new String((String) value);
 }

 public boolean isMutable() {
  return false;
 }

 /*
  * @see org.hibernate.usertype.UserType#hashCode(java.lang.Object)
  */
 public int hashCode(Object arg0) throws HibernateException {
  // TODO 自动生成方法存根
  return 0;
 }

 /*
  * @see org.hibernate.usertype.UserType#disassemble(java.lang.Object)
  */
 public Serializable disassemble(Object arg0) throws HibernateException {
  // TODO 自动生成方法存根
  return null;
 }

 /*
  * @see org.hibernate.usertype.UserType#assemble(java.io.Serializable, java.lang.Object)
  */
 public Object assemble(Serializable arg0, Object arg1) throws HibernateException {
  // TODO 自动生成方法存根
  return null;
 }

 /*
  * @see org.hibernate.usertype.UserType#replace(java.lang.Object, java.lang.Object, java.lang.Object)
  */
 public Object replace(Object arg0, Object arg1, Object arg2) throws HibernateException {
  // TODO 自动生成方法存根
  return null;
 }
}

DaoImp:
与其他字段一样的处理,get/set就可以了

/* End: StringClobType类源码*/

注意:以上两种方法,在采用oracle thin方式连接的情况下 经我测试都不能传输超过4K字节
采用oci连接方式(jdbc:oracle:oci8:@orclsid) 则可以,但必须设置 hibernate的propertie
0 (注意此设置有可能导致旧的代码有批量更新的问题,我的解决办法是其他代码采用一个新的数据源)

/* 
oracle10g JDBC驱动可以处理clob 类型,直接采用String 就好了,但采用hiberbate ,我不知道如何设置他的 特性:SetBigStringTryClob  为  true http://www.javaworld.com.tw/jute/post/view?bid=11&id=80295&sty=1&tpg=1&age=0 
(楼主说可以,但我测试没有成功) 

//oracle 官方说明及例子
http://www.oracle.com/technology/sample_code/tech/java/codesnippet/jdbc/lob/LobToSP.html

http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/htdocs/jdbc_10201.html

http://www.oracle.com/technology/sample_code/tech/java/codesnippet/jdbc/clob10g/handlingclobsinoraclejdbc10g.html
*/