首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > 其他数据库 >

施用JDBC和Hibernate来写入Blob型数据到Oracle中(1)

2012-12-19 
使用JDBC和Hibernate来写入Blob型数据到Oracle中(1)转Oracle的Blob字段比较特殊,他比long字段的性能要好很

使用JDBC和Hibernate来写入Blob型数据到Oracle中(1)


Oracle的Blob字段比较特殊,他比long字段的性能要好很多,可以用来保存例如图片之类的二进制数据。

写入Blob字段和写入其它类型字段的方式非常不同,因为Blob自身有一个cursor,你必须使用cursor对blob进行操作,因而你在写入Blob之前,必须获得cursor才能进行写入,那么如何获得Blob的cursor呢?

这需要你先插入一个empty的blob,这将创建一个blob的cursor,然后你再把这个empty的blob的cursor用select查询出来,这样通过两步操作,你就获得了blob的cursor,可以真正的写入blob数据了。

看下面的JDBC的demo,把oraclejdbc.jar这个二进制文件写入数据库表javatest的content字段(这是一个blob型字段)

代码



1.import java.sql.*;   
2.import java.io.*;   
3.import oracle.sql.*;   
4.public class WriteBlob {   
5.  
6.  public static void main(String[] args) {   
7.  
8.    try {   
9.      DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());   
10.      Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl","fankai","fankai");   
11.      conn.setAutoCommit(false);   
12.  
13.      BLOB blob = null;   
14.  
15.      PreparedStatement pstmt = conn.prepareStatement("insert into javatest(name,content) values(?,empty_blob())");   
16.      pstmt.setString(1,"fankai");   
17.      pstmt.executeUpdate();   
18.      pstmt.close();   
19.  
20.      pstmt = conn.prepareStatement("select content from javatest where name= ? for update");   
21.      pstmt.setString(1,"fankai");   
22.      ResultSet rset = pstmt.executeQuery();   
23.      if (rset.next()) blob = (BLOB) rset.getBlob(1);   
24.  
25.      String fileName = "oraclejdbc.jar";   
26.      File f = new File(fileName);   
27.      FileInputStream fin = new FileInputStream(f);   
28.      System.out.println("file size = " + fin.available());   
29.  
30.      pstmt = conn.prepareStatement("update javatest set content=? where name=?");   
31.  
32.      OutputStream out = blob.getBinaryOutputStream();   
33.  
34.      int count = -1, total = 0;   
35.      byte[] data = new byte[(int)fin.available()];   
36.      fin.read(data);   
37.      out.write(data);   
38.      /*  
39.      byte[] data = new byte[blob.getBufferSize()];  另一种实现方法,节省内存  
40.      while ((count = fin.read(data)) != -1) {  
41.        total += count;  
42.        out.write(data, 0, count);  
43.      }  
44.      */  
45.  
46.      fin.close();   
47.      out.close();   
48.  
49.      pstmt.setBlob(1,blob);   
50.      pstmt.setString(2,"fankai");   
51.  
52.      pstmt.executeUpdate();   
53.      pstmt.close();   
54.  
55.      conn.commit();   
56.      conn.close();   
57.    } catch (SQLException e) {   
58.      System.err.println(e.getMessage());   
59.      e.printStackTrace();   
60.    } catch (IOException e) {   
61.      System.err.println(e.getMessage());   
62.    }   
63.  }   
64.  
65.} 


仔细看上例,分三步:

1、插入空blob

into javatest(name,content) values(?,empty_blob());

2、获得blob的cursor

select content from javatest where for update;

注意!!!必须加for update,这将锁定该行,直至该行被修改完毕,保证不产生并发冲突。

3、update javatest set content=? where >

用cursor往数据库写数据

这里面还有一点要提醒大家:

JDK1.3带的JDBC2.0规范是不完善的,只有读Blob的接口,而没有写Blob的接口,JDK1.4带的JDBC3.0加入了写Blob的接口。你可以使用JDBC3.0的接口,也可以直接使用Oracle的JDBC的API,我在上例中使用了Oracle的JDBC的API。

另外要注意的是:

java.sql.Blob

oracle.sql.BLOB

注意看blob的大小写,是不一样的。写程序的时候不要搞混了。

下面看看用Hibernate怎么写,原理是一样的,也要分三步,但是代码简单很多

这是Cat对象定义

代码



1.package com.fankai;   
2.  
3.import java.sql.Blob;   
4.  
5.public class Cat {   
6.  private String id;   
7.  private String name;   
8.  private char sex;   
9.  private float weight;   
10.  private Blob image;   
11.  public Cat() { }   
12.  
13.  public String getId() { return id; }   
14.  public void setId(String id) { this.id = id; }   
15.  
16.  public String getName() { return name; }   
17.  public void setName(String name) { this.name = name; }   
18.  
19.  public char getSex() { return sex; }   
20.  public void setSex(char sex) { this.sex = sex; }   
21.  
22.  public float getWeight() { return weight; }   
23.  public void setWeight(float weight) { this.weight = weight; }   
24.     
25.  public Blob getImage() { return image; }   
26.  public void setImage(Blob image) { this.image = image;}   
27.} 


这是Cat.hbm.xml

代码



1.<?xml version="1.0"?>  
2.<!DOCTYPE hibernate-mapping SYSTEM "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">  
3.  
4.<hibernate-mapping>  
5.    <class name="com.fankai.Cat" table="cat">  
6.        <!--jcs-cache usage="read-only"/-->  
7.        <id name="id" unsaved-value="null">  
8.            <generator length="16" not-null="true"/>  
11.        <property name="sex" length="1" not-null="true"/>  
12.        <property name="weight" />  
13.        <property name="image" />  
14.    </class>  
15.</hibernate-mapping> 


下面是完整的用Hibernate写入Blob的例子,相比JDBC,已经简单轻松多了,也不用写那些Oracle特殊的sql了:

代码



1.package com.fankai;   
2.  
3.import java.sql.Blob;   
4.import net.sf.hibernate.*;   
5.import oracle.sql.*;   
6.import java.io.*;   
7.  
8.public class TestCatHibernate {     
9.  public static void testBlob() {   
10.    Session s = null;       
11.    byte[] buffer = new byte[1];   
12.    buffer[0] = 1;   
13.    try {   
14.      SessionFactory sf = HibernateSessionFactory.getSessionFactory();   
15.      s = sf.openSession();     
16.      Transaction tx = s.beginTransaction();   
17.      Cat c = new Cat();   
18.      c.setName("Robbin");   
19.      c.setImage(Hibernate.createBlob(buffer));   
20.      s.save(c);   
21.      s.flush();   
22.      s.refresh(c, LockMode.UPGRADE);       
23.      BLOB blob = (BLOB) c.getImage();         
24.      OutputStream out = blob.getBinaryOutputStream();      
25.      String fileName = "oraclejdbc.jar";   
26.      File f = new File(fileName);   
27.      FileInputStream fin = new FileInputStream(f);      
28.      int count = -1, total = 0;   
29.      byte[] data = new byte[(int)fin.available()];   
30.      fin.read(data);   
31.      out.write(data);         
32.      fin.close();   
33.      out.close();   
34.      s.flush();   
35.      tx.commit();   
36.      
37.    } catch (Exception e) {   
38.      System.out.println(e.getMessage());   
39.    } finally {   
40.      if (s != null)   
41.        try {   
42.          s.close();   
43.        } catch (Exception e) {}   
44.    }       
45.       
46.  }   
47.}

热点排行