一般網站在處理用戶上傳圖片時通常采用兩種策略:一是直接把圖片存入數據庫中的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"
"http://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 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 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 id="test" src="/servlet/Test"/>
簡單的例子,希望對初學者有幫助.
posted on 2006-10-28 10:09
無聲 閱讀(3706)
評論(5) 編輯 收藏 所屬分類:
職場生活