天天看点

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>