天天看點

Hibernate存取圖檔示例

一般網站在處理使用者上傳圖檔時通常采用兩種政策:一是直接把圖檔存入資料庫中的blob字段;二是資料庫中隻存儲圖檔的在伺服器上的路徑資訊 ,圖檔存放在分門别類的檔案中,使用的時候從資料庫讀取路徑資訊到頁面img元素即可.在此不讨論兩種方案的優劣,我隻是寫了個hibernate的例子來實作第一種政策.例子很簡單,t_user表主要兩個字段,name和photo,其中photo字段類型為blob.在此例中資料庫我采用mysql, oracle的blob字段比較特殊,你必須自定義類型,具體的請自行搜尋,這方面的資料很多.

//user.java  

package com.denny_blue.hibernate;

import java.io.serializable;

import java.sql.blob;

public class user implements serializable{

 private integer id;

 private string name;

 private blob photo;

 /**

  * @return the id

  */

 public user(){

 }

 public integer getid() {

  return id;

  * @param id the id to set

 public void setid(integer id) {

  this.id = id;

  * @return the name

 public string getname() {

  return name;

  * @param name the name to set

 public void setname(string name) {

  this.name = name;

  * @return the photo

 public blob getphoto() {

  return photo;

  * @param photo the photo to set

 public void setphoto(blob photo) {

  this.photo = photo;

}

類user有3個屬性,id,name,photo,相應的getter和setter方法以及一個無參構造函數.應該注意的是photo的類型java.sql.blob

相應的user.hbm.xml應該如下:

<?xml version="1.0"?>

<!doctype hibernate-mapping public

 "-//hibernate/hibernate mapping dtd 3.0//en"

<hibernate-mapping

 package="com.denny_blue.hibernate">

 <class name="com.denny_blue.hibernate.user"

        table="t_user"

        dynamic-update="true"

        dynamic-insert="true"

        batch-size="3">

  <id name="id"

      column="id"

      type="java.lang.integer">

   <generator class="native"/>

  </id>

  <property name="name" column="name" type="java.lang.string" lazy="true"/>

  <property name="photo" column="photo" type="java.sql.blob"/>

 </class>

</hibernate-mapping>

對應的hibernate.cfg.xml配置檔案,不再列出,請參照hibernate文檔自行設定.

OK,做了這一步,我們寫個測試類來進行單元測試:

package com.denny_blue.test;

import java.io.fileinputstream;

import java.io.filenotfoundexception;

import java.io.fileoutputstream;

import java.io.ioexception;

import java.io.inputstream;

import org.hibernate.hibernate;

import org.hibernate.hibernateexception;

import org.hibernate.session;

import org.hibernate.sessionfactory;

import org.hibernate.transaction;

import org.hibernate.cfg.configuration;

import com.denny_blue.hibernate.user;

import junit.framework.testcase;

public class hibernatetest extends testcase {

        private session session;

 protected void setup() throws exception {

  try{

   configuration config=new configuration().configure();

   sessionfactory sf=config.buildsessionfactory();

   session=sf.opensession();

  }catch(hibernateexception e){

   e.printstacktrace();

  }

 protected void teardown() throws exception {

   session.close();

 public void testsave()throws filenotfoundexception,ioexception{

  user user=new user();

  user.setname("jordan");

  fileinputstream in=new fileinputstream("c://test.gif");

  blob photo=hibernate.createblob(in);

  user.setphoto(photo);

  transaction tx=null;

  tx=session.begintransaction();

  session.saveorupdate(user);

  tx.commit();

   if(tx!=null)

    tx.rollback();

  }finally{

   in.close();

 public void testload()throws exception{

   user user=(user)session.load(user.class, new integer(1));

   blob photo=user.getphoto();

   inputstream in=photo.getbinarystream();

   fileoutputstream out=new fileoutputstream("c://out//test2.gif");

   byte [] buf=new byte[1024];

   int len;

   while((len=in.read(buf))!=-1){

    out.write(buf, 0, len);

   }

   out.close();

我們讀取c盤目錄下的test.gif并存儲到資料庫中,然後再取出來寫入c:/out目錄,此時你可以檢視下資料表中photo顯示為blob,表示已經成功存入.值的注意的代碼片段就是:

fileinputstream in=new fileinputstream("c://test.gif");

我們這裡是從磁盤中讀取圖檔,實際應用中你可以利用上傳元件得到圖檔的2進制資料流,并利用hibernate.createblob方法來構造相應的blob對象.而取圖檔則使用

inputstream in=photo.getbinarystream();

這隻是個簡單的測試類,如果我想從資料庫中取出圖檔并現實在頁面上該如何做呢?其實也很簡單,我們先要寫一個servlet,在它的service方法中取出圖檔,并"畫"到指定頁面上.

package com.easyjf.asp.action;

import java.io.outputstream;

import javax.servlet.servletexception;

import javax.servlet.http.httpservlet;

import javax.servlet.http.httpservletrequest;

import javax.servlet.http.httpservletresponse;

import com.denny)blue.hibernate.user;

public class test extends httpservlet {

  * destruction of the servlet. <br>

 private session session;

 public void destroy() {

  * initialization of the servlet. <br>

  *

  * @throws servletexception if an error occure

 public void init() throws servletexception {

    public void doget(httpservletrequest request,httpservletresponse response)

    {

     try{

   outputstream out=response.getoutputstream();

  }catch(exception e){

    }

通過response.getoutputstream取得輸出流,其他就與上段代碼一緻.servlet寫好了,怎麼在頁面調用呢?那就更簡單啦,直接在頁面的img标簽的src屬性上調用該servlet即可,如:

<img id="test" src="/servlet/test"/>

簡單的例子,希望對初學者有幫助.

附記:如果不希望在servlet(或者action之類)中進行儲存操作,希望在dao進行此操作,那麼inputstream的關閉問題可以通過hibernate的interceptor機制解決

文章轉自莊周夢蝶  ,原文釋出時間5.17

<a></a>