熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Oracle >> 正文

JDBC+Hibernate將Blob數據寫入Oracle

2022-06-13   來源: Oracle 

  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把oraclejdbcjar這個二進制文慈胧菘獗韏avatest的content字段(這是一個blob型字段)

  import javasql*;
import javaio*;
import oraclesql*;
public class WriteBlob {

  public static void main(String[] args) {

  try {
  DriverManagerregisterDriver(new oraclejdbcdriverOracleDriver());
  Connection conn = DriverManagergetConnection(jdbc:oracle:thin:@localhost::orclfankaifankai);
  connsetAutoCommit(false);

  BLOB blob = null;

  PreparedStatement pstmt = connprepareStatement(insert into javatest(namecontent) values(?empty_blob()));
  pstmtsetString(fankai);
  pstmtexecuteUpdate();
  pstmtclose();

  pstmt = connprepareStatement(select content from javatest where name= ? for update);
  pstmtsetString(fankai);
  ResultSet rset = pstmtexecuteQuery();
  if (rsetnext()) blob = (BLOB) rsetgetBlob();

  String fileName = oraclejdbcjar;
  File f = new File(fileName);
  FileInputStream fin = new FileInputStream(f);
  Systemoutprintln(file size = + finavailable());

  pstmt = connprepareStatement(update javatest set content=? where name=?);

  OutputStream out = blobgetBinaryOutputStream();

  int count = total = ;
  byte[] data = new byte[(int)finavailable()];
  finread(data);
  outwrite(data);
  /*
  byte[] data = new byte[blobgetBufferSize()]; 另一種實現方法節省內存
  while ((count = finread(data)) != ) {
   total += count;
   outwrite(data count);
  }
  */

  finclose();
  outclose();

  pstmtsetBlob(blob);
  pstmtsetString(fankai);

  pstmtexecuteUpdate();
  pstmtclose();

  mit();
  connclose();
 } catch (SQLException e) {
   Systemerrprintln(egetMessage());
  eprintStackTrace();
 } catch (IOException e) {
  Systemerrprintln(egetMessage());
 }
}

  }

  仔細看上例分三步

  插入空blob

  into javatest(namecontent) values(?empty_blob());

  獲得blob的cursor

  select content from javatest where name= ? for update;

  注意!!!必須加for update這將鎖定該行直至該行被修改完畢保證不產生並發沖突

  update javatest set content=? where name=

  用cursor往數據庫寫數據

  這裡面還有一點要提醒大家

  JDK帶的JDBC規范是不完善的只有讀Blob的接口而沒有寫Blob的接口JDK帶的JDBC加入了寫Blob的接口你可以使用JDBC的接口也可以直接使用Oracle的JDBC的API我在上例中使用了Oracle的JDBC的API

  另外要注意的是

  javasqlBlob

  oraclesqlBLOB

  注意看blob的大小寫是不一樣的寫程序的時候不要搞混了

  下面看看用Hibernate怎麼寫原理是一樣的也要分三步但是代碼簡單很多

  這是Cat對象定義

  package comfankai;

  import javasqlBlob;

  public class Cat {
 private String id;
 private String name;
 private char sex;
 private float weight;
 private Blob image;
 public Cat() { }

  public String getId() { return id; }
 public void setId(String id) { thisid = id; }

  public String getName() { return name; }
 public void setName(String name) { thisname = name; }

  public char getSex() { return sex; }
 public void setSex(char sex) { thissex = sex; }

  public float getWeight() { return weight; }
 public void setWeight(float weight) { thisweight = weight; }

  public Blob getImage() { return image; }
 public void setImage(Blob image) { thisimage = image;}
}
 

  這是Cathbmxml

  <?xml version=?>
<!DOCTYPE hibernatemapping SYSTEM

  <hibernatemapping>
<class name=comfankaiCat table=cat
<!jcscache usage=readonly/
<id name=id unsavedvalue=null
<generator class=uuidhex/>
</id>
<property name=name length= notnull=true/>
<property name=sex length= notnull=true/>
<property name=weight />
<property name=image />
</class>
</hibernatemapping>

  下面是完整的用Hibernate寫入Blob的例子相比JDBC已經簡單輕松多了也不用寫那些Oracle特殊的sql了

  package comfankai;

  import javasqlBlob;
import netsfhibernate*;
import oraclesql*;
import javaio*;

  public class TestCatHibernate {
 public static void testBlob() {
  Session s = null;
  byte[] buffer = new byte[];
  buffer[] = ;
  try {
   SessionFactory sf = HibernateSessionFactorygetSessionFactory();
   s = sfopenSession();
   Transaction tx = sbeginTransaction();
   Cat c = new Cat();
   csetName(Robbin);
   csetImage(HibernatecreateBlob(buffer));
   ssave(c);
   sflush();
   srefresh(c LockModeUPGRADE);
   BLOB blob = (BLOB) cgetImage();
   OutputStream out = blobgetBinaryOutputStream();
   String fileName = oraclejdbcjar;
   File f = new File(fileName);
   FileInputStream fin = new FileInputStream(f);
   int count = total = ;
   byte[] data = new byte[(int)finavailable()];
   finread(data);
   outwrite(data);
   finclose();
   outclose();
   sflush();
   mit();

  } catch (Exception e) {
   Systemoutprintln(egetMessage());
  } finally {
   if (s != null)
   try {
    sclose();
   } catch (Exception e) {}
  }
 }
}


From:http://tw.wingwit.com/Article/program/Oracle/201311/17139.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.