ORACLE 里的CLOB应用

来源:互联网 发布:为什么程序员工资40万 编辑:程序博客网 时间:2024/05/18 03:58
 

public void NewsLocation(DataSource ds, Collection coll) throws SQLException {
        Connection conn = ds.getConnection();
        conn.setAutoCommit(false);
        try{
           Statement state = conn.createStatement();
           String cont ="";
           String strSql ="select id,title,content from news where id = '3';
           ResultSet rs = state.executeQuery(strSql);
           while (rs.next()) {
                oracle.sql.CLOB clob = (oracle.sql.CLOB)ret.getClob("CONTENT");
                if(clob!=null){
                    Reader isClob = clob.getCharacterStream();
                    BufferedReader bfClob = new BufferedReader(isClob);
                    String strClob = bfClob.readLine();//调试到这行之后异常出错。
                    while (strClob!=null ) {
                      cont += strClob;
                      strClob = bfClob.readLine();
                    }
                    isClob.close();
                    bfClob.close();
                }
                rd.setContent(cont);
                coll.add(rd);
            }
            conn.commit();
            rs.close();
            state.close();
        }catch(Exception e){
            e.printStackTrace();
            conn.rollback();
            conn.close();
        }
        conn.setAutoCommit(true);
        conn.close();
    }
出错:

 

 

 

 

/////////////////////////////////////////////////////////////////

1.       CLOB字段的插入

clob类型的数据直接insert可能会因为字符过长而出错,所以要用对象形式插入.

示例:

首先,创建一个含CLOB字段的表:

create table test (id INTEGER, content clob);

 

然后插入空值

String strSql = “INSERT INTO TEST(id,content) values(‘0001’,?) ”;

con.setAutoCommit(false);  //conn为Connection对象

//创建并实例化一个CLOB对象

CLOB clob = new CLOB((OracleConnection)con);

   clob = oracle.sql.CLOB.createTemporary((OracleConnection)con,true,1);

//对CLOB对象赋值

   clob.putString(1,formateSingleQuotes(Content));

   OracleConnection OCon = (OracleConnection)con;

   OraclePreparedStatement pstmt = (OraclePreparedStatement)OCon.prepareCall(strSql);

   pstmt.setCLOB(1,clob);

   int i  = pstmt.executeUpdate();

   pstmt.close();

   OCon.commit();

   OCon = null;

con = null;      

Boolean flag = true;

if(i <=0)

 {

      flag = false;

 }

 

if (flag == true)

 {

       out.print( "<script>alert('成功保存!'); </script>");

}

 else

 {

       out.print( "<script>alert('保存数据时出错,请检查你输入的数据格式是否符合要求');self.history.back ();</script>");

 }

 

注意:

一定不要忘记引入包:import oracle.sql.*,oracle.jdbc.driver.*

 

2.       CLOB类型的修改

 

对CLOB字段的修改除了sql语句外其他和插入相同

String strSql = “UPDATE TEST set content=? Where Id=’0001’ ”;

con.setAutoCommit(false);  //conn为Connection对象

//创建并实例化一个CLOB对象

CLOB clob = new CLOB((OracleConnection)con);

   clob = oracle.sql.CLOB.createTemporary((OracleConnection)con,true,1);

//对CLOB对象赋值

   clob.putString(1,formateSingleQuotes(Content));

   OracleConnection OCon = (OracleConnection)con;

   OraclePreparedStatement pstmt = (OraclePreparedStatement)OCon.prepareCall(strSql);

   pstmt.setCLOB(1,clob);

   int i  = pstmt.executeUpdate();

   pstmt.close();

   OCon.commit();

   OCon = null;

con = null;      

Boolean flag = true;

if(i <=0)

 {

      flag = false;

 }

 

if (flag == true)

 {

       out.print( "<script>alert('成功保存!'); </script>");

}

 else

 {

       out.print( "<script>alert('保存数据时出错,请检查你输入的数据格式是否符合要求');self.history.back ();</script>");

 }


CLOB修改
String strSql = “UPDATE TEST set content=? Where Id=’0001’ ”;

con.setAutoCommit(false);  //conn为Connection对象

//创建并实例化一个CLOB对象

CLOB clob = new CLOB((OracleConnection)con);

   clob = oracle.sql.CLOB.createTemporary((OracleConnection)con,true,1);

//对CLOB对象赋值

   clob.putString(1,formateSingleQuotes(Content));

   OracleConnection OCon = (OracleConnection)con;

   OraclePreparedStatement pstmt = (OraclePreparedStatement)OCon.prepareCall(strSql);

   pstmt.setCLOB(1,clob);

   int i  = pstmt.executeUpdate();

   pstmt.close();

   OCon.commit();

   OCon = null;

con = null;      

Boolean flag = true;

if(i <=0)

 {

      flag = false;

 }

 

if (flag == true)

 {

 

///////////////////////////////////////////////////////////////////////////////////////

 

 

 

 

 

 

 

 


1.       CLOB字段的插入

clob类型的数据直接insert可能会因为字符过长而出错,所以要用对象形式插入.

示例:

首先,创建一个含CLOB字段的表:

create table test (id INTEGER, content clob);

 

然后插入空值

String strSql = “INSERT INTO TEST(id,content) values(‘0001’,?) ”;

con.setAutoCommit(false);  //conn为Connection对象

//创建并实例化一个CLOB对象

CLOB clob = new CLOB((OracleConnection)con);

   clob = oracle.sql.CLOB.createTemporary((OracleConnection)con,true,1);

//对CLOB对象赋值

   clob.putString(1,formateSingleQuotes(Content));

   OracleConnection OCon = (OracleConnection)con;

   OraclePreparedStatement pstmt = (OraclePreparedStatement)OCon.prepareCall(strSql);

   pstmt.setCLOB(1,clob);

   int i  = pstmt.executeUpdate();

   pstmt.close();

   OCon.commit();

   OCon = null;

con = null;      

Boolean flag = true;

if(i <=0)

 {

      flag = false;

 }

 

if (flag == true)

 {

       out.print( "<script>alert('成功保存!'); </script>");

}

 else

 {

       out.print( "<script>alert('保存数据时出错,请检查你输入的数据格式是否符合要求');self.history.back ();</script>");

 }

 

注意:

一定不要忘记引入包:import oracle.sql.*,oracle.jdbc.driver.*

 

2.       CLOB类型的修改

 

对CLOB字段的修改除了sql语句外其他和插入相同

String strSql = “UPDATE TEST set content=? Where Id=’0001’ ”;

con.setAutoCommit(false);  //conn为Connection对象

//创建并实例化一个CLOB对象

CLOB clob = new CLOB((OracleConnection)con);

   clob = oracle.sql.CLOB.createTemporary((OracleConnection)con,true,1);

//对CLOB对象赋值

   clob.putString(1,formateSingleQuotes(Content));

   OracleConnection OCon = (OracleConnection)con;

   OraclePreparedStatement pstmt = (OraclePreparedStatement)OCon.prepareCall(strSql);

   pstmt.setCLOB(1,clob);

   int i  = pstmt.executeUpdate();

   pstmt.close();

   OCon.commit();

   OCon = null;

con = null;      

Boolean flag = true;

if(i <=0)

 {

      flag = false;

 }

 

if (flag == true)

 {

       out.print( "<script>alert('成功保存!'); </script>");

}

 else

 {

       out.print( "<script>alert('保存数据时出错,请检查你输入的数据格式是否符合要求');self.history.back ();</script>");

 }

 
////////////////////////////////////////////////////

使用Oracle来存储长文本始终没Mysql来的方便,Mysql不用特殊配置直接使用java.lang.String来存储Text 字段内容即可。这里可以看出Mysql的优势了吧。^-^
很久之前在网上找了些,加上自己摸索的,应该算是很简单的了。
来个总结备案。

步骤:
1。使用Clob类型来存储长文本。

2。在你的Spring的applicationContext-hibernate.xml里配置以下两个bean.

<bean id="nativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.SimpleNativeJdbcExtractor"/>

<bean id="oracleLobHandle" class="org.springframework.jdbc.support.lob.OracleLobHandler" Lazy-init="true">
 <property name="nativeJdbcExtractor">
   <ref local="nativeJdbcExtractor"/>
 </property>
</bean>

3。在有clob类型sessionFactory(org.springframework.com.hibernate.LocalSessionFractoryBean)中加入
<property name="lobHandler"><ref bean="oracleLobHandle"/></property>

4。在*.hbm文件里使用长文本的字段加上对应的Java类型。
 <property name="content" type="org.springframework.orm.hibernate3.support.ClobStringType" column="TRACK_CONTENT" length="100000"/>

5。上边的这个content,即JavaBean的对应的属性类型为String,不是ClobStringType。

如果只配置到这里的话,启动应用的时候会报缺少事务支持的错误,忘了具体报什么错了。

6。所以要给save,remove方法加上事务支持。

    <bean id="txProxyTemplate" abstract="true"
        class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="transactionManager"><ref bean="transactionManager"/></property>
        <property name="transactionAttributes">
            <props>
                <prop key="save*">PROPAGATION_REQUIRED</prop>
                <prop key="remove*">PROPAGATION_REQUIRED</prop>
                <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
            </props>
        </property>
    </bean>
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory"><ref bean="sessionFactory"/></property>
    </bean>
 <bean id="cnProjectTrackManager" parent="txProxyTemplate">
        <property name="target">
            <bean class="com.helloworld.cn.manager.project.bl.impl.ProjectTrackManagerImpl">
                <property name="projectTrackDAO"><ref bean="cnProjectTrackDAO"/></property>
            </bean>
        </property>
    </bean>

7。结束。
下边是配置所需的3个文件。
applicationContext.xml


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
    "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
   
    <bean id="txProxyTemplate" abstract="true"
        class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="transactionManager"><ref bean="transactionManager"/></property>
        <property name="transactionAttributes">
            <props>
                <prop key="save*">PROPAGATION_REQUIRED</prop>
                <prop key="remove*">PROPAGATION_REQUIRED</prop>
                <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
            </props>
        </property>
    </bean>
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory"><ref bean="sessionFactory"/></property>
    </bean>
    <bean id="cnProjectTrackManager" parent="txProxyTemplate">
        <property name="target">
            <bean class="com.helloworld.cn.manager.project.bl.impl.ProjectTrackManagerImpl">
                <property name="projectTrackDAO"><ref bean="cnProjectTrackDAO"/></property>
            </bean>
        </property>
    </bean>
   
    <!--  bean id="jtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
        <property name="sessionFactory"><ref bean="sessionFactory"/></property>
    </bean-->
     <!--bean id="cnProjectTrackManager" class="com.helloworld.cn.manager.project.bl.impl.ProjectTrackManagerImpl">
        <property name="projectTrackDAO"><ref bean="cnProjectTrackDAO"/></property>
     </bean-->
</beans>

applicationContext-hibernate.xml


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
    "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
    <!-- bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean" -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource"><ref bean="dataSource"/></property>
        <property name="mappingResources">
            <list>
                <value>/hbm.ProjectTrack.xml</value>                       
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <!-- prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop-->
                <prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop >
                <!-- prop key="hibernate.dialect">net.sf.hibernate.dialect.MySQLDialect</prop -->               
                <!-- prop key="hibernate.hbm2ddl.auto">update</prop -->
                 <prop key="hibernate.show_sql">true</prop>
                 <!-- prop key="hibernate.jdbc.batch_size">0</prop-->
                <prop key="hibernate.use_outer_join">true</prop>               
                <!-- prop key="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</prop -->                
            </props>
        </property>
        <property name="lobHandler"><ref bean="oracleLobHandle"/></property>
    </bean>
   
    <bean id="oracleLobHandle" class="org.springframework.jdbc.support.lob.OracleLobHandler" lazy-init="true">
      <property name="nativeJdbcExtractor">
        <ref local="nativeJdbcExtractor"/>
      </property>
    </bean>
    <bean id="nativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.SimpleNativeJdbcExtractor"/>
    <bean id="cnProjectTrackDAO" class="com.helloworld.cn.manager.project.dao.hibernate.ProjectTrackDAOHibernate">
        <property name="sessionFactory"><ref bean="sessionFactory"/></property>
    </bean>
</beans>

hbm.ProjectTrack.xml


<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="com.vitamin.cn.manager.project.entity.ProjectTrack" dynamic-update="false"
        dynamic-insert="false" table="VITAMIN_CN_PROJECT_TRACK" lazy="false">
        <id name="id" column="TRACK_ID" type="java.lang.Long" unsaved-value="null">
            <!-- generator for mysql
            <generator class="native">
            </generator>
            -->
            <!-- generator for oracle -->
            <generator class="sequence">
              <param name="sequence">SEQ_CN_PROJECT_TRACK</param>
            </generator>
        </id>
        <many-to-one name="project" column="PROJECT_ID"/>
        <property name="date" type="java.util.Date"  column="TRACK_DATE" />
        <property name="editor" type="java.lang.String"  column="TRACK_EDITOR" />
        <property name="content" type="org.springframework.orm.hibernate3.support.ClobStringType" column="TRACK_CONTENT" length="100000"/>
        <property name="name" type="java.lang.String"  column="TRACK_NAME" />
    </class>

</hibernate-mapping>

有关oracle字段类型的相关信息可以查阅oracle技术网。下面摘抄一些有关blob.clob等类型的说明。又便于大家的了解。
字段类型:blob,clob,nclob
说明:三种大型对象(LOB),用来保存较大的图形文件或带格式的文本文件,如Miceosoft Word文档,以及音频、视频等非文本文件,最大长度是4GB。LOB有几种类型,取决于你使用的字节的类型,Oracle 8i实实在在地将这些数据存储在数据库内部保存。可以执行读取、存储、写入等特殊操作。

我们所操作的clobtest_table中属性是(字符型id,CLOB型picstr),目前我们假设一个大的字符对象str已经包含了我们需要存入picstr字段的数据。而且connection对象conn已经建立。以下的例子程序也因为不想占用太多的空间,所以对抛出异常没有写。大家参考一下api doc。就可以知道该抛出什么异常了,此处仅仅告诉大家如何去写。

代码:


(1)对数据库clob型执行插入操作
*************************************************

java.sql.PreparedStatement pstmt = null;
ResultSet rs = null;
String query = "";

conn.setAutoCommit(false);
query = "insert into clobtest_table(id,picstr) values(?,empty_clob())";
java.sql.PreparedStatement pstmt = conn.prepareStatement(query);
pstmt.setString(1,"001");
pstmt.executeUpdate();
pstmt = null
query = "select picstr from clobtest_table where id = '001' for update";
pstmt = con.prepareStatement(query)
rs= pstmt.executeQuery();

oracle.sql.CLOB clobtt = null;
if(rs.next()){
clobtt = (oracle.sql.CLOB)rs.getClob(1);
}
Writer wr = clobtt.getCharacterOutputStream();
wr.write(strtmp);
wr.flush();
wr.close();
rs.close();
con.commit();

 

(2)通过sql/plus查询是否已经成功插入数据库
*************************************************

PL/SQL的包DBMS_LOB来处理LOB数据。察看刚才的插入是否成功。使用DBMS_LOB包的getlength这个procedure来检测是否已经将str存入到picstr字段中了。如:

SQL> select dbms_lob.getlength(picstr) from clobtest_table;


(3)对数据库clob型执行读取操作
*************************************************

读取相对插入就很简单了。基本步骤和一半的取数据库数据没有太大的差别。
String description = ""
query = "select picstr from clobtest_table where id = '001'";
pstmt = con.prepareStatement(query);
ResultSet result = pstmt.executeQuery();
if(result.next()){
oracle.jdbc.driver.OracleResultSet ors =
(oracle.jdbc.driver.OracleResultSet)result;
oracle.sql.CLOB clobtmp = (oracle.sql.CLOB) ors.getClob(1);

if(clobtmp==null || clobtmp.length()==0){
System.out.println("======CLOB对象为空 ");
description = "";
}else{
description=clobtmp.getSubString((long)1,(int)clobtmp.length());
System.out.println("======字符串形式 "+description);
}
}

 

//////////////////////////


 一、   CLOB对象的存取  
  1、往数据库中插入一个新的CLOB对象  
  public   static   void   clobInsert(String   infile)   throws   Exception  
  {  
  /*   设定不自动提交   */  
  boolean   defaultCommit   =   conn.getAutoCommit();  
  conn.setAutoCommit(false);  
  try   {  
  /*   插入一个空的CLOB对象   */  
  stmt.executeUpdate("INSERT   INTO   TEST_CLOB   VALUES   ('111',   EMPTY_CLOB())");  
  /*   查询此CLOB对象并锁定   */  
  ResultSet   rs   =   stmt.executeQuery("SELECT   CLOBCOL   FROM   TEST_CLOB   WHERE   ID='111'   FOR   UPDATE");  
  while   (rs.next())   {  
  /*   取出此CLOB对象   */  
  oracle.sql.CLOB   clob   =   (oracle.sql.CLOB)rs.getClob("CLOBCOL");  
  /*   向CLOB对象中写入数据   */  
  BufferedWriter   out   =   new   BufferedWriter(clob.getCharacterOutputStream());  
  BufferedReader   in   =   new   BufferedReader(new   FileReader(infile));  
  int   c;  
  while   ((c=in.read())!=-1)   {  
  out.write(c);  
  }  
  in.close();  
  out.close();  
  }  
  /*   正式提交   */  
  conn.commit();  
  }   catch   (Exception   ex)   {  
  /*   出错回滚   */  
  conn.rollback();  
  throw   ex;  
  }  
  /*   恢复原提交状态   */  
  conn.setAutoCommit(defaultCommit

 

///////////////////////////////////////////////////////
有关oracle字段类型的相关信息可以查阅oracle技术网。下面摘抄一些有关blob.clob等类型的说明。又便于大家的了解。
字段类型:blob,clob,nclob
说明:三种大型对象(LOB),用来保存较大的图形文件或带格式的文本文件,如Miceosoft Word文档,以及音频、视频等非文本文件,最大长度是4GB。LOB有几种类型,取决于你使用的字节的类型,Oracle 8i实实在在地将这些数据存储在数据库内部保存。可以执行读取、存储、写入等特殊操作。

我们所操作的clobtest_table中属性是(字符型id,CLOB型picstr),目前我们假设一个大的字符对象str已经包含了我们需要存入picstr字段的数据。而且connection对象conn已经建立。以下的例子程序也因为不想占用太多的空间,所以对抛出异常没有写。大家参考一下api doc。就可以知道该抛出什么异常了,此处仅仅告诉大家如何去写。

代码:
 
 
(1)对数据库clob型执行插入操作
*************************************************
 
java.sql.PreparedStatement pstmt = null;
ResultSet rs = null;
String query = "";
 
conn.setAutoCommit(false);
       query = "insert into clobtest_table(id,picstr) values(?,empty_clob())";
java.sql.PreparedStatement pstmt = conn.prepareStatement(query);
pstmt.setString(1,"001");
pstmt.executeUpdate();
pstmt = null
       query = "select picstr from clobtest_table where id = '001' for update";
pstmt = con.prepareStatement(query)
rs= pstmt.executeQuery();
 
oracle.sql.CLOB clobtt = null;
if(rs.next()){
    clobtt = (oracle.sql.CLOB)rs.getClob(1);
}
Writer wr = clobtt.getCharacterOutputStream();
wr.write(strtmp);
wr.flush();
wr.close();
rs.close();
con.commit();
 
 
 
(2)通过sql/plus查询是否已经成功插入数据库
*************************************************
 
PL/SQL的包DBMS_LOB来处理LOB数据。察看刚才的插入是否成功。使用DBMS_LOB包的getlength这个procedure来检测是否已经将str存入到picstr字段中了。如:
 
SQL> select dbms_lob.getlength(picstr) from clobtest_table;
 
 
(3)对数据库clob型执行读取操作
*************************************************
 
读取相对插入就很简单了。基本步骤和一半的取数据库数据没有太大的差别。
String description = ""
      query = "select picstr from clobtest_table where id = '001'";
pstmt = con.prepareStatement(query);
ResultSet result = pstmt.executeQuery();
if(result.next()){
    oracle.jdbc.driver.OracleResultSet ors = 
              (oracle.jdbc.driver.OracleResultSet)result;
    oracle.sql.CLOB clobtmp = (oracle.sql.CLOB) ors.getClob(1);
 
    if(clobtmp==null || clobtmp.length()==0){
        System.out.println("======CLOB对象为空 ");
        description = "";
    }else{
        description=clobtmp.getSubString((long)1,(int)clobtmp.length());
        System.out.println("======字符串形式 "+description);
    }
}