`

JDBC操作LOB字段详解

 
阅读更多

在Oracle中,lob类型主要是指:CLOB和BLOB,这两个类型都是用来存储大量数据而设计的。

 

Blob:是指二进制大对象也就是英文Binary Large Object的所写,是用来存储大量二进制数据。

 

Clob:是指大字符对象也就是英文Character Large Object的所写,用来存储大量文本数据。

 

一:操作CLOB

 

(1)数据库表结构如下:

 

 

     create table CLOB_TEST

     (

        ID      VARCHAR2(5) not null,

        CONTENT CLOB    

    )

 

(2)插入CLOB

 

方法一:第一步插入一个空值,第二步锁住此行,更新clob字段

 

public static void insertClob(Connection conn,String data) throws Exception{
  
  
//这句话如没有,9i的驱动下会报 java.sql.SQLException: ORA-01002: 读取违反顺序 的异常。
  conn.setAutoCommit(false);

  //插入一个空CLOB
  String insertSql = "insert into clob_test(id,content) values('1',empty_clob())";
  //查询插入的空CLOB
  String selectSql = "select content from clob_test where id = '1' for update";
  PreparedStatement  stmt = conn.prepareStatement(insertSql);
  stmt.executeUpdate();
  stmt.close();
  // lock this line
  PreparedStatement pstmt = conn.prepareStatement(selectSql);
  ResultSet rs = pstmt.executeQuery();
  if(rs.next()){
   oracle.sql.CLOB clob = (oracle.sql.CLOB)rs.getClob(1);
   //为CLOB写信息
   BufferedWriter out = new BufferedWriter(clob.getCharacterOutputStream()); 
   BufferedReader in = new BufferedReader(new FileReader(data)); 
   int c; 
   while ((c=in.read())!=-1) { 
     out.write(c); 
   } 
   in.close(); 
   out.close(); 
  }
  conn.commit();
  pstmt.close();
 }

 

注:此方法在jdk1.4、jdk50、jdk6.0和Oracle9i、Oracle10g、Oracle11g驱动下测试通过!

 

方法二:通过setString方法

 

public static void insertClob(Connection conn,String data) throws Exception{
  
  String insertSql = "insert into clob_test(id,content) values('1',?)";
  PreparedStatement  stmt = conn.prepareStatement(insertSql);
  stmt.setString(1, data);
  stmt.executeUpdate();
  stmt.close();
  conn.close();

 


 }

 

 

注:由于在Oracle9i的驱动下,setString 有2000字符长度的限制,故这个方法只适合Oracle10g以上的驱动(Oracle11g驱动+JDK6.0也测试通过)。

 

方法三:通过setClob方法

 

public static void insertClob(Connection conn,String filePath) throws Exception{
  String insertSql = "insert into clob_test(id,content) values('1',?)";
  PreparedStatement  stmt = conn.prepareStatement(insertSql);
  stmt.setClob(1, new FileReader(filePath));
  stmt.executeUpdate();
  stmt.close();
  conn.commit();
 }

 

注:由于setClob(int parameterIndex, Reader reader)这个方法是JDBC4.0规范刚加的内容,是以流的方式为CLOB赋值的。并且Oracle9i驱动、Oracle10g驱动、JDK1.4、JDK1.5是基于JDBC3.0规范的,只有Oracle11g驱动+JDK6.0才是基于JDBC4.0规范的,所以目前这个方法只适合Oracle11g驱动(ojdbc6.jar)+JDK6.0!

 

(3)读取CLOB

 

方法一:

 

public static String readClob(Connection conn) throws Exception{
  PreparedStatement  stmt = conn.prepareStatement("select * from clob_test where id = '1'");
  ResultSet rs = stmt.executeQuery();
  String str="";
  StringBuffer sb = new StringBuffer("");
  while(rs.next()){
   Clob clob = rs.getClob("content");
   Reader is = clob.getCharacterStream(); 
      BufferedReader br = new BufferedReader(is); 
      str = br.readLine(); 
      while (str != null)
      { 
       sb.append(str);
       str = br.readLine(); 
      } 
  }
  return sb.toString();
 }

 

方法二:

public static String readClob(Connection conn) throws Exception{
  PreparedStatement  stmt = conn.prepareStatement("select * from clob_test where id = '1'");
  ResultSet rs = stmt.executeQuery();
  String str="";
  while(rs.next()){
   str = rs.getString("content");
  }
  return str;
 }

 

注:由于在Oracle9i的驱动下,rs.getString 返回为null,所以此方法只适合Oracle10g及其以上驱动。

 

二:操作BLOB

 

(1)数据库表结构如下:

 

 

     create table BLOB_TEST

     (

        ID      VARCHAR2(5) not null,

        CONTENT BLOB

    )

 

(2)插入BLOB

 

 方法一:第一步插入一个空值,第二步锁住此行,更新blob字段

 

public static void writeBlob(Connection con,String filePath) throws Exception{
  FileInputStream fis = null;
  PreparedStatement psm = null;
  File file = new File(filePath);
  psm = con.prepareStatement("insert into blob_test(id,content) values('2',empty_blob())");
  psm.executeUpdate();
  psm = con.prepareStatement("select content from blob_test where id ='2' for update");
  ResultSet rs = psm.executeQuery();
  if(rs.next()){
   oracle.sql.BLOB blob = (oracle.sql.BLOB)rs.getBlob(1);
   FileInputStream fin = new FileInputStream(file);
   OutputStream out = blob.getBinaryOutputStream();
   int count = -1, total = 0; 
   byte[] data = new byte[blob.getBufferSize()];
   while ((count = fin.read(data)) != -1)
   { 
    out.write(data, 0, count); 
   } 
   out.flush();
   out.close();

  }  
 }

 

 方法二:通过setBinaryStream方法

 

public static void writeBlob(Connection con,String filePath) throws Exception{
  FileInputStream fis = null;
  PreparedStatement psm = null;
  File file = new File(filePath);
  try {
   fis = new FileInputStream(file);
   psm = con.prepareStatement("insert into blob_test(id,content) values('2',?)");
   psm.setBinaryStream(1, fis, fis.available());
   psm.executeUpdate();
 
  }finally{
   if(fis != null) fis.close();
   psm.close();
   con.close();
  }  
 }

 

 方法三:通过setBlob(int parameterIndex, InputStream inputStream)方法

 

public static void writeBlob(Connection con,String filePath) throws Exception{
  FileInputStream fis = null;
  PreparedStatement psm = null;
  File file = new File(filePath);
  try {
   fis = new FileInputStream(file);
   psm = con.prepareStatement("insert into blob_test(id,content) values('2',?)");
   psm.setBlob(1, fis);
   psm.executeUpdate();
 
  }finally{
   if(fis != null) fis.close();
   psm.close();
   con.close();
  }  
 }

 

 

注:由于setBlob(int parameterIndex, InputStream inputStream)这个方法是JDBC4.0规范刚加的内容,是以流的方式为BLOB赋值的。并且Oracle9i驱动、Oracle10g驱动、JDK1.4、JDK1.5是基于JDBC3.0规范的,只有Oracle11g驱动+JDK6.0才是基于JDBC4.0规范的,所以目前这个方法只适合Oracle11g驱动(ojdbc6.jar)+JDK6.0!

 

(3)读取BLOB

 

public static void readBlob(Connection con,String outFilePath){
  Statement sm = null;
  ResultSet rs = null;
  try {
   sm = con.createStatement();
   rs = sm.executeQuery("select * from blob_test where id = 2");
   if(rs.next()){
    Blob blob = rs.getBlob("content");
    File file = new File(outFilePath);   
             FileOutputStream sout = new FileOutputStream(file);   
    InputStream in = blob.getBinaryStream();//获取BLOB数据的输入数据流   
             //经BLOB输入数据流读取数据,并将其写入文件   
             byte[] b = new byte[256];    
             int off = 0;   
             int len = b.length;   
             for (int i = in.read(b); i != -1;) {    
                 sout.write(b);    
                 i = in.read(b);   
             }
             sout.close();
             rs.close();
             sm.close();
             con.close();
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

分享到:
评论

相关推荐

    解析使用jdbc,hibernate处理clob/blob字段的详解

    这篇文章主要讲解了如何使用`JDBC`和`Hibernate`这两种不同的方式来处理`CLOB`和`BLOB`字段。 1. **数据库中的`CLOB`与`BLOB`类型** - 在MySQL中,`CLOB`对应`TEXT`类型,`BLOB`对应`BLOB`类型。 - 在DB2或Oracle...

    Manipulating Large Objects

    ### Oracle LOB (Large Object) 数据类型详解及操作 #### 一、LOB 概述 在 Oracle 数据库中,LOB(Large Object)是一种用于存储大量非结构化数据的数据类型,例如文本、图形图像、视频和音频文件等。这种数据类型...

    hibernate课程详解

    ### Hibernate课程详解 #### 一、Hibernate概述及安装配置 - **HelloWorld示例**: - 创建Java项目`hibernate_0100_HelloWorld` - 配置`User-library-hibernate`,添加必要的JAR包 - 导入MySQL JDBC驱动 - 在...

    深入OCI教程

    - **OCILobAppend()**: 向LOB字段追加数据。 - **OCILobIsEqual()**: 检查两个LOB是否相等。 - **OCILobTrim()**: 剪裁LOB数据。 **3.2 Oracle Spatial数据处理** - **OCISpatialObjCreate()**: 创建Spatial对象。...

    db2错误码一览表

    16. **+23801005**: 期望的LOB值未找到,扩展的SQLVAR目标与实际需求不符。 17. **+23901005**: 同上一条错误码。 18. **+30401515**: 提供的值超出允许的范围。 19. **+33101520**: 尝试设置一个不能设为NULL的值。...

    oracle 错误合集

    **ORA-17054**:LOB 处理错误,可能是因为 LOB 对象操作不当。 **ORA-17055**:未知错误,可能与数据库操作有关。 **ORA-17056**:不支持的国际化 (i18n) 错误,可能是因为使用的国际化功能不受支持。 **ORA-...

    PL/SQL存储过程编程

    ### PL/SQL存储过程编程详解 #### 一、Oracle应用编辑方法概览 在Oracle数据库的应用开发中,存在多种编辑方法和技术,它们各有特点和适用场景。以下是对这些方法的概述: 1. **Pro*C/C++**: 这是一种C语言与...

    SSH+Oracle上传图片

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

    hibernate annotation学习文档

    ### Hibernate Annotation 学习知识点详解 #### 一、概述 Hibernate 是一款开源的对象关系映射 (ORM) 巨具,它极大地简化了 Java 应用程序与数据库之间的交互过程。Hibernate 支持多种注解(Annotation),使得...

Global site tag (gtag.js) - Google Analytics