hibernateのBlob,Clobフィールド


ほとんどの場合、ライブラリ・テーブルに大規模な文字列、または画像などのバイナリ・データを保存する必要があります.Hibernateは、Blob(ピクチャ)、Clob(大型文字列);
BlobとClobの違いは、Blobフィールドは単バイト記憶を採用し、画像などのバイナリデータを保存するのに適していることです.
Clobフィールドはマルチバイトストレージを採用し、大規模なテキストデータを保存するのに適している.
BlobとClobは、さまざまなデータベースで独自の実装を行っています.
例:tUser.java
 
import java.io.Serializable;
import java.sql.Blob;
import java.sql.Clob;

public class Tuser implements Serializable {
	private Integer tId;
	private String tName;
	private Blob image;
	private Clob info;
        get()/set()...
}
 
属性ファイル:Tuser.hbm.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 package="com.keith">

	<class name="Tuser" table="tUser">
		<id name="tId" column="tId">
			<generator class="native" />
		</id>
		
		<property name="tName" column="tName"/>
		<property name="image" type="java.sql.Blob"></property>
		<property name="info" type="java.sql.Clob"></property>
	</class>
</hibernate-mapping>

 
データテストを追加します.
 
                Tuser tUser = new Tuser();
		tUser.settName("keith");
		
		FileInputStream imges = new FileInputStream("C:/Users/T/Desktop/hankuko.png");
		Blob img = Hibernate.createBlob(imges);
		tUser.setImage(img);
		
		Clob info = Hibernate.createClob("this is more info");
		tUser.setInfo(info);
		
		session.save(tUser);

 
以上のコードはHibernate.クリエイティブ・Blob()とHibernate.createClob()は、対応するBlobオブジェクトとClobオブジェクトを作成します.ここで、BlobオブジェクトはFileInputStreamに基づいて構築され、Clobオブジェクトは文字列に基づいて構築されます.
次に、挿入したデータを読み込みます.
 
                Tuser tUser = (Tuser) session.load(Tuser.class, new Integer(1));
		Clob info = tUser.getInfo();
		System.out.println("user's info:"+info.getSubString(1, (int) info.length()));
		Blob image = tUser.getImage();
		InputStream is = image.getBinaryStream();
		FileOutputStream fos = new FileOutputStream("C:/Users/T/Desktop/hankuko1.png");
		byte[] buf = new byte[102400];
		int len;
		while ((len = is.read(buf))!=-1) {
			fos.write(buf,0,len);
		}
		fos.close();
		is.close();
		

 
「hibernate深入浅出中」は、各データベースがこの読み方をサポートしているわけではないことを指摘しています(この例はmysqlで操作されています)、oracleではデータベースが操作を許可していない異常が発生する可能性があります:streams type cannot be used in batching;この状況に遭遇したらhibernateでcfg.xmlに追加:
 
<property name="hibernate.jdbc.batch_size">0</property>

また、OracleではBlob/Clobに独自のアクセス方法があり、OracleのBlob/Clobフィールド自体にカーソル(cursor)があり、JDBCはカーソルを介してBlob/Clobフィールドを操作する必要があります.そうすると、空のBlob/Clobフィールドを作成し、この空のBlob/Clobフィールドからカーソルを取得し、保存したいデータを書き込む必要があります.
 
		Tuser tUser  = new Tuser();
		tUser.settName("keith");
		tUser.setImage(Hibernate.createBlob(new byte[1]));
		tUser.setInfo(Hibernate.createClob(" "));
		session.getTransaction().commit();
		
		session.flush();
		//  refresh()    Hibernate  Select for update
		session.refresh(tUser,LockMode.UPGRADE);
		
		oracle.sql.Blob blob = (oracle.sql.Blob)tUser.getImage();
		OutputStream out = blob.getBinaryOutputStreamStream();
		FileInputStream image = new FileInputStream("C:/Users/T/Desktop/hankuko1.png");
		byte[] buf = new byte[102400];
		int len;
		while ((len = image.read(buf))!=-1) {
			image.write(buf,0,len);
		}
		image.close();
		out.close();
		
		oracle.sql.Clob clob = (oracle.sql.Blob)tUser.getInfo();
		java.io.Writer writer = clob.getCharacterOutputStream();
		writer.write("this is my Info");
		writer.close();
		session.save(tUser);
		session.getTransaction().commit();

Oracleはテストされていません.