閱讀185 返回首頁    go 阿裏雲 go 技術社區[雲棲]


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"
 "https://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<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 />
  </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 java.sql.Blob;

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 {
  try{
   session.close();
  }catch(HibernateException e){
   e.printStackTrace();
  }
 }
 
 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;
  try{
  tx=session.beginTransaction();
  session.saveOrUpdate(user);
  tx.commit();
  }catch(HibernateException e){
   if(tx!=null)
    tx.rollback();
   e.printStackTrace();
  }finally{
   in.close();
  }
 }
 public void testLoad()throws Exception{
  try{
   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);
   }
   in.close();
   out.close();
  }catch(HibernateException e){
   e.printStackTrace();
  }
 }

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

FileInputStream in=new FileInputStream("C://test.gif");
  Blob photo=Hibernate.createBlob(in);
我們這裏是從磁盤中讀取圖片,實際應用中你可以利用上傳組件得到圖片的2進製數據流,並利用Hibernate.createBlob方法來構造相應的Blob對象.而取圖片則使用

InputStream in=photo.getBinaryStream();

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

package com.easyjf.asp.action;

import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Blob;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import com.denny)blue.hibernate.User;


public class Test extends HttpServlet {

 /**
  * Destruction of the servlet. <br>
  */
 private Session session;
 public void destroy() {
  try{
   session.close();
  }catch(HibernateException e){
   e.printStackTrace();
  }
 }

 /**
  * Initialization of the servlet. <br>
  *
  * @throws ServletException if an error occure
  */
 public void init() throws ServletException {
  try{
   Configuration config=new Configuration().configure();
   SessionFactory sf=config.buildSessionFactory();
   session=sf.openSession();
  }catch(HibernateException e){
   e.printStackTrace();
  }
 }
    public void doGet(HttpServletRequest request,HttpServletResponse response)
    {
     try{
   User user=(User)session.load(User.class, new Integer(1));
   Blob photo=user.getPhoto();
   InputStream in=photo.getBinaryStream();
   OutputStream out=response.getOutputStream();
   byte [] buf=new byte[1024];
   int len;
   while((len=in.read(buf))!=-1){
    out.write(buf, 0, len);
   }
   in.close();
   out.close();
  }catch(Exception e){
   e.printStackTrace();
  }
    }

}

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

<img src="/servlet/Test"/>

 

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

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

文章轉自莊周夢蝶  ,原文發布時間5.17

最後更新:2017-05-17 10:01:21

  上一篇:go  我們分析了幾千人的麵相,竟發現……
  下一篇:go  獨家 | 第十屆中國R會議(北京)