Hibernate
與
SQL Server BLOB
BLOB
數據在
SQL Server
數據庫中主要由
IMAGE
類型體現,最大容量為
2GB
。其存儲方式不同于普通的數據類型,對于普通類型的數據系統直接在用戶定義的字段上存儲數據值,而對于
IMAGE
類型數據,系統開辟新的存儲頁面來存放這些數據,表中
IMAGE
類型數據字段存放的僅是一個
16
字節的指針,該指針指向存放該條記錄的
IMAGE
數據的頁面。如果
你對
Hibernate
還不熟息,請看
這里
。
新建名為
“BLOB_TEST”
的表,字段分別是
INT
類型的
“ID”
和
IMAGE
類型的
“MYBLOB”
。從文件系統讀取
“sample.jpg”
并轉換成字節數組再放進
BlobTest
對象實例。
寫入程序如下:
import java.io.*;
import net.sf.hibernate.*;
import bo.*;
public class Tester {
?public void DoTest() {
???//begin BlobTest
???//begin Hibernate Session
?
import net.sf.hibernate.cfg.*;
??InputStream in = null;
??BlobTest blobTest = null;
??Configuration cfg = null;
??SessionFactory sessions = null;
??Session session = null;
??Transaction tx = null;
??try {
???//begin InputStream
???in = new FileInputStream("d:/sample.jpg");
???byte[] b = new byte[in.available()];
???in.read(b);
???in.close();
???blobTest = new BlobTest();
???blobTest.setMyblob(b);
???cfg = new Configuration().configure();
???sessions = cfg.buildSessionFactory();
???session = sessions.openSession();
???tx = session.beginTransaction();
???session.save(blobTest);
???tx.commit();
??} catch (Exception e) {
???e.printStackTrace();
??} finally {
???try {
????session.close();
???} catch (Exception e1) {
????e1.printStackTrace();
???}
??}
?}
}
取出
程序如下:
import java.io.*;
import net.sf.hibernate.*;
import bo.*;
public class Tester {
?public void DoTest() {
???//begin BlobTest
???//begin OutputStream
?
import net.sf.hibernate.cfg.*;
??OutputStream out = null;
??BlobTest blobTest = null;
??Configuration cfg = null;
??SessionFactory sessions = null;
??Session session = null;
??try {
???//begin Hibernate Session
???cfg = new Configuration().configure();
???sessions = cfg.buildSessionFactory();
???session = sessions.openSession();
???blobTest = new BlobTest();
???blobTest = (BlobTest) session.load(BlobTest.class, new Integer(23));
???out = new FileOutputStream("d:/sample.jpg");
???out.write(blobTest.getMyblob());
???out.flush();
???out.close();
??} catch (Exception e) {
???e.printStackTrace();
??} finally {
???try {
????session.close();
???} catch (Exception e1) {
????e1.printStackTrace();
???}
??}
?}
}
Hibernate
與
MySQL BLOB
??? MySQL
中的
BLOB
數據由四種類型體現,分別是
TINYBLOB
其容量為
256
字節、
BLOB
其容量為
64KB
、
MEDIUMBLOB
其容量為
16MB
、
LONGBLOB
其容量為
4GB
。
新建名為
“BLOB_TEST”
的表,字段分別是
INTEGER
類型的
“ID”
和
MEDIUMBLOB
類型的
“MYBLOB”
。從文件系統讀取
“sample.jpg”
并轉換成字節數組再放進
BlobTest
對象實例。
寫入、
取出
程序和上面的
SQL Server
一樣。
Hibernate
與
Oracle BLOB
???
為了不使用
“for update”
鎖住數據庫,遂打算讓
Oracle LONG RAW
類型保存大對象,最大容量
2GB
。經過測試后發現,直接寫
JDBC
代碼可以保存,但
Hibernate
只能保存
4K
大小內容,換成
Hibernate 3.0 beta3
也未能成功。偶然的機會在郵件列表上發現這是
JDBC Driver
的問題,換成
Oracle
10g
的驅動后問題解決。
新建名為
“BLOB_TEST”
的表,字段分別是
NUMBER
類型的
“ID”
和
LONG RAW
類型的
“MYBLOB”
。從文件系統讀取
“sample.jpg”
并轉換成字節數組再放進
BlobTest
對象實例。
寫入、
取出
程序和
SQL Server
一樣。
如果你一定要用
Oracle
BLOB
類型,接著往下看:
??? Hibernate
處理
Oracle
BLOB
類型較特殊
,
從文件系統讀取
“sample.jpg”
放進
BlobTest
對象實例的是
java.sql.Blob
類型,而不是字節數組。
import java.io.*;
import net.sf.hibernate.*;
import bo.*;
public class Tester {
?public void DoTest() {
?
import net.sf.hibernate.cfg.*;
import oracle.sql.*;
??BLOB blob = null;
??InputStream in = null;
??OutputStream out = null;
??BlobTest blobTest = null;
??Configuration cfg = null;
??SessionFactory sessions = null;
??Session session = null;
??Transaction tx = null;
??try {
???//begin InputStream
???in = new FileInputStream("d:/sample.jpg");
???byte[] b = new byte[in.available()];
???in.read(b);
???in.close();
???
???//begin BlobTest
???blobTest = new BlobTest();
???blobTest.setMyblob(BLOB.empty_lob());
???
???//begin Hibernate Session
???cfg = new Configuration().configure();
???sessions = cfg.buildSessionFactory();
???session = sessions.openSession();
???tx = session.beginTransaction();
???session.save(blobTest);
???session.flush();
???session.refresh(blobTest, LockMode.UPGRADE);
???blob = (BLOB) blobTest.getMyblob();
???out = blob.getBinaryOutputStream();
???out.write(b);
???out.close();
???session.flush();
???tx.commit();
??} catch (Exception e) {
???e.printStackTrace();
??} finally {
???try {
????session.close();
???} catch (Exception e1) {
????e1.printStackTrace();
???}
??}
?}
}
取出
程序和其他兩種數據庫操作幾乎一樣。
iBATIS SQL Maps
與
SQL Server BLOB
???
建表過程和
Hibernate
操作
SQL Server
一樣,如果
你對
iBATIS SQL Maps
還不熟息,請看
這里
。
映射文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap
<sqlMap>
??? <insert id="insertBlob" parameterClass="bo.BlobTest">
??? <resultMap id="get-blob-result" class="bo.BlobTest">
??? <select id="getBlob" resultMap="get-blob-result" parameterClass="bo.BlobTest">
?
??? PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN"
??? "
http://www.ibatis.com/dtd/sql-map-2.dtd
">
????? <![CDATA[
??????? insert into blob_test (myblob) values (#myblob#)
????? ]]>
????? <selectKey resultClass="java.lang.Integer" keyProperty="id">
??????? <![CDATA[
????????? SELECT @@IDENTITY AS ID
??????? ]]>
????? </selectKey>
??? </insert>
????? <result property="id" column="id"/>
????? <result property="myblob" column="myblob"/>
??? </resultMap>
????? <![CDATA[
??????? select * from blob_test where id=#id#
????? ]]>
??? </select>
???????
</sqlMap>
寫入程序如下:
import java.io.*;
import com.ibatis.sqlmap.client.*;
import bo.*;
public class Tester {
?public void DoTest() {
???//begin BlobTest
???//begin SqlMapClient
?
import com.ibatis.common.resources.*;
??byte[] b=null;
??Reader reader = null;
??InputStream in = null;
??BlobTest blobTest = null;
??SqlMapClient sqlMap = null;
??String resource = "SqlMapConfig.xml";
??try {
???//begin InputStream
???in = new FileInputStream("d:/sample.jpg");
???b = new byte[in.available()];
???in.read(b);
???in.close();
???blobTest = new BlobTest();
???blobTest.setMyblob(b);
???reader = Resources.getResourceAsReader(resource);
???sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
???sqlMap.startTransaction();
???sqlMap.insert("insertBlob", blobTest);
???sqlMap.commitTransaction();
??} catch (Exception e) {
???e.printStackTrace();
??} finally {
???try {
????sqlMap.endTransaction();
???} catch (Exception e1) {
????e1.printStackTrace();
???}
??}
?}
}
取出
程序如下:
import java.io.*; import com.ibatis.sqlmap.client.*; import bo.*; public class Tester { ?public void DoTest() { ???//begin SqlMapClient ???//begin OutputStream
import com.ibatis.common.resources.*;
??Reader reader = null;
??OutputStream out = null;
??BlobTest blobTest = null;
??SqlMapClient sqlMap = null;
??String resource = "SqlMapConfig.xml";
??try {
???//begin BlobTest
???blobTest = new BlobTest();
???blobTest.setId(new Integer(21));
???reader = Resources.getResourceAsReader(resource);
???sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
???blobTest = (BlobTest) sqlMap.queryForObject("getBlob", blobTest);
???out = new FileOutputStream("d:/sample.jpg");
???out.write(blobTest.getMyblob());
???out.close();
??} catch (Exception e) {
???e.printStackTrace();
??} finally {
???try {
????sqlMap.endTransaction();
???} catch (Exception e1) {
????e1.printStackTrace();
???}
??}
?}
}
iBATIS SQL Maps
與
MySQL BLOB
??? 這個主題很簡單,需要注意映射文件 insert 元素主鍵生成方式, 寫入、 取出 程序和上面的 SQL Server 一樣 :
?
??? <insert id="insertBlob" parameterClass="bo.BlobTest">
????? <![CDATA[
??????? insert into blob_test (myblob) values (#myblob#)
????? ]]>
????? <selectKey resultClass="java.lang.Integer" keyProperty="id">
??? <![CDATA[
????????? select last_insert_id();
??? ]]>
????? </selectKey>
? </insert>
iBATIS SQL Maps
與
Oracle BLOB
???
使用
Oracle LONG RAW
類型,
注意映射文件
insert
元素主鍵生成方式,
寫入、
取出
程序和上面的
SQL Server
一樣
:
?
??? <insert id="insertBlob" parameterClass="bo.BlobTest">
????? <selectKey resultClass="int" keyProperty="id">
??????? <![CDATA[
????????? select hibernate_sequence.nextval from dual
??????? ]]>
????? </selectKey>
????? <![CDATA[
??????? insert into blob_test (id,myblob) values (#id#,#myblob#)
????? ]]>
??? </insert>
如果你一定要用
Oracle
BLOB
類型,接著往下看:
???
在
iBATIS 2.0.9
以前,處理
Oracle BLOB
類型相當麻煩,要自己實現
TypeHandlerCallback
接口。
iBATIS 2.0.9
的出現使一切都簡單了,寫入、
取出
程序和上面的
SQL Server
一樣。
http://java.ccidnet.com/art/297/20051117/374459_1.html