hibernate存取图片示例

news/2024/11/15 21:29:21/
一般网站在处理用户上传图片时通常采用两种策略:一是直接把图片存入数据库中的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"/>
 

http://www.ppmy.cn/news/717143.html

相关文章

MyBatis使用foreach批量插入,foreach套查询

目录跳转 需求场景我跳进去的坑解决方式方法一方法二 重点(也不是) 需求场景 我需要批量list写入数据到info_notice表格&#xff0c;写入的数据中有一个属性是来之user_info表格。我用foreach去写批量插入&#xff0c;但是在服务层我又不想根据批量写入的数据list去查询每一个…

mybatis之批量插入

通过动态SQL方式实现 通过动态SQL方式&#xff0c;Executor的类型不需要特别设置&#xff0c;用默认的SIMPLE就可以。 具体步骤如下&#xff1a; 第一步&#xff1a;定义Mapper映射文件和接口类 映射文件中定义动态SQL语句 <insert id"insertBatch" parameter…

Mybatis批量添加(foreach标签)

delete from xxx_table where id in <foreach collection"list" item"item" index"index" open"(" separator"," close")"> #{item} </foreach> > (1,2,3,4) foreach标签&#xff1a;主要应用…

通过Mybatis批量插入表数据

对于需要同时插入大量表数据的需求&#xff0c;我们可以通过下述方式实现&#xff1a; for(Commit commit: commitList){commitDao.insertCommit(commit);}但我们很快就会发现系统效率低下。插入2000条数据大概花了4mins。 在思考如何提速的过程中&#xff0c;首先想到的就是如…

MyBatis批量插入的五种方式,哪种最强?

前言 这里列举了MyBatis和MyBatis-Plus常用的五种批量插入的方式&#xff0c;进行了详细的总结归纳。 准备工作MyBatis利用For循环批量插入MyBatis的手动批量提交MyBatis以集合方式批量新增&#xff08;推荐&#xff09;MyBatis-Plus提供的SaveBatch方法MyBatis-Plus提供的In…

MyBatis 批量插入数据的 3 种方法!

作者 | 王磊 来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09; 转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone 批量插入功能是我们日常工作中比较常见的业务功能之一&#xff0c;之前我也写过一篇关于《MyBatis Plus 批量数据插入功能&#xff0c…

mybatis遍历

参考&#xff1a;foreach 实现 MyBatis 遍历集合与批量操作数据_点滴记录-CSDN博客_mybatis遍历list SELECT * FROM t_employee WHERE id IN (1, 2, 3, ...) /** 根据传入的 id 集合&#xff0c;查询出对应的员工信息&#xff0c;并使用集合保存信息 */ List<Employee> …

MyBatis 使用 foreach 批量插入

教程 单条语句插入多个值 Mapper public interface UserMapper {void batchSave(List<User> userList); }<insert id"batchSave">insert into user(name, password) values<foreach collection"list" item"user" separator&quo…