使用Hibernate向MySQL数据库中存取文件
文件上传是一个系统中的常见功能。可以把文件内容存储在磁盘中,在数据库中存储路径,或者把文件内容直接存储到数据库中。第二中方法的关键在于数据库中存储文件内容的字段用什么数据类型,以及怎么把向数据库存取二进制文件。本文探讨的正是这一内容。
1、在myeclipse中新建项目,在项目中导入Hibernate的包
2、建立Hibernate工具类:HibernateUtils.java,代码如下:
1 package cn.edu.cqu; 2 import org.hibernate.Session; 3 import org.hibernate.SessionFactory; 4 import org.hibernate.cfg.Configuration; 5 public class HibernateUtils { 6 private static SessionFactory factory; 7 static{ 8 Configuration cfg=new Configuration().configure(); 9 factory=cfg.buildSessionFactory(); 10 } 11 public static Session getSession(){ 12 factory.getCurrentSession(); 13 return factory.openSession(); 14 } 15 public static void closeSession(Session session){ 16 if(session!=null){ 17 if(session.isOpen()){ 18 session.close(); 19 } 20 } 21 } 22 public static SessionFactory getFactory() { 23 return factory; 24 } 25 public static void setFactory(SessionFactory factory) { 26 HibernateUtils.factory = factory; 27 } 28 }
3、新建实体类File.java,代码如下:
1 package cn.edu.cqu; 2 import java.sql.Blob; 3 /** 4 * 5 * @author Administrator 6 * @hibernate.class table="t_file" 7 */ 8 public class File { 9 /** 10 * @hibernate.id 11 * generator-class="native" 12 */ 13 private int id; 14 /** 15 * @hibernate.property 16 */ 17 private String filename; 18 /** 19 * @hibernate.property 20 */ 21 private Blob filecontent; 22 public int getId() { 23 return id; 24 } 25 public void setId(int id) { 26 this.id = id; 27 } 28 public String getFilename() { 29 return filename; 30 } 31 public void setFilename(String filename) { 32 this.filename = filename; 33 } 34 public Blob getFilecontent() { 35 return filecontent; 36 } 37 public void setFilecontent(Blob filecontent) { 38 this.filecontent = filecontent; 39 } 40 }
4、使用xdoclet生成Hibernate映射文件和配置文件,其中build.xml的内容如下:
1 <?xml version="1.0" encoding="GBK"?> 2 <project name="upload构建脚本" default="生成Hibernate配置文件" basedir="."> 3 <property name="src.dir" value="${basedir}/src"/> 4 <property name="xdoclet.home" value="D:/Program Files/xdoclet-plugins-1.0.3"/> 5 <!-- Build classpath --> 6 <path id="xdoclet.task.classpath"> 7 <fileset dir="${xdoclet.home}/lib"> 8 <include name="**/*.jar"/> 9 </fileset> 10 <fileset dir="${xdoclet.home}/plugins"> 11 <include name="**/*.jar"/> 12 </fileset> 13 </path> 14 <taskdef 15 name="xdoclet" 16 classname="org.xdoclet.ant.XDocletTask" 17 classpathref="xdoclet.task.classpath" 18 /> 19 <target name="生成Hibernate配置文件"> 20 <xdoclet> 21 <fileset dir="${src.dir}/cn/edu/cqu"> 22 <include name="**/*.java"/> 23 </fileset> 24 <component 25 classname="org.xdoclet.plugin.hibernate.HibernateConfigPlugin" 26 destdir="${src.dir}" 27 version="3.0" 28 hbm2ddlauto="update" 29 jdbcurl="jdbc:mysql://127.0.0.1/test" 30 jdbcdriver="com.mysql.jdbc.Driver" 31 jdbcusername="root" 32 jdbcpassword="root" 33 dialect="org.hibernate.dialect.MySQLDialect" 34 showsql="true" 35 /> 36 </xdoclet> 37 </target> 38 <target name="生成hibernate映射文件"> 39 <xdoclet> 40 <fileset dir="${src.dir}/cn/edu/cqu"> 41 <include name="**/*.java"/> 42 </fileset> 43 <component 44 classname="org.xdoclet.plugin.hibernate.HibernateMappingPlugin" 45 version="3.0" 46 destdir="${src.dir}" 47 /> 48 </xdoclet> 49 </target> 50 </project>
要注意一个问题,因为这里是单独使用Hibernate,因此要在Hibernate的配置文件中加上这样一句配置:
<property name="current_session_context_class">thread</property>
为Hibernate指定一个策略
生成映射文件和配置文件以后,加载Hibernate,即可在mysql数据库中建立一个与File类相对应的数据表t_file
5、创建类SaveFile,该类的作用是将指定的磁盘文件存储到数据库中,代码如下:
1 package cn.edu.cqu; 2 import java.io.FileInputStream; 3 import java.io.FileNotFoundException; 4 import java.io.FileOutputStream; 5 import java.io.IOException; 6 import java.sql.Blob; 7 import org.hibernate.Hibernate; 8 import org.hibernate.Session; 9 import org.hibernate.Transaction; 10 //新建file对象并保存到数据库 11 public class SaveFile { 12 public static void main(String[] args){ 13 FileInputStream fis=null; 14 byte[] content=null; 15 Transaction transaction=null; 16 Session session=null; 17 try { 18 //将磁盘文件读入到输入流 19 fis=new FileInputStream("C:/Documents and Settings/Administrator/桌面/test.txt"); 20 //将输入流中的内容存储到字节数组中 21 content=new byte[fis.available()]; 22 fis.read(content); 23 24 25 File file=new File(); 26 27 file.setFilename("测试文件存储到数据库"); 28 //将字节数组转化为blob类型的对象 29 Blob blobContent=Hibernate.createBlob(content); 30 file.setFilecontent(blobContent); 31 32 //获得session 33 session=HibernateUtils.getSession(); 34 //开启事务 35 transaction=session.beginTransaction(); 36 //保存file对象 37 session.save(file); 38 //提交事务 39 transaction.commit(); 40 } catch (FileNotFoundException e) { 41 System.out.println("文件未找到"); 42 } catch(IOException e){ 43 System.out.println("文件读写错误"); 44 } catch(Exception e){ 45 e.printStackTrace(); 46 //事务回滚 47 transaction.rollback(); 48 } finally{ 49 HibernateUtils.closeSession(session); 50 } 51 } 52 }
6、新建类LoadFile,该类的作用是将数据库中的文件内容读取出来,输出到指定的磁盘文件中
1 package cn.edu.cqu; 2 import java.io.FileOutputStream; 3 import java.io.FileNotFoundException; 4 import java.io.InputStream; 5 import java.io.OutputStream; 6 import java.sql.Blob; 7 import org.hibernate.Session; 8 import org.hibernate.Transaction; 9 //从数据库中加载file对象,并将文件内容写到磁盘文件中 10 public class LoadFile { 11 public static void main(String[] args) { 12 FileOutputStream fos=null; 13 Transaction transaction=null; 14 Session session=null; 15 Blob blobContent=null; 16 byte[] content=null; 17 try{ 18 //获得session 19 session=HibernateUtils.getSession(); 20 //开启事务 21 transaction=session.beginTransaction(); 22 //从数据库中加载file对象,刚才插入数据库中的记录编号为6 23 File file=(File)session.load(File.class, 6); 24 //提交事务 25 transaction.commit(); 26 blobContent=file.getFilecontent(); 27 28 //获得blob对象的输入流,这里的输入流是指从blob对象输入到程序(程序中定义的字节数组) 29 InputStream is=blobContent.getBinaryStream(); 30 content=new byte[is.available()]; 31 is.read(content); 32 33 //建立文件输出流,用来将内容从程序输出到磁盘文件 34 fos=new FileOutputStream("C:/Documents and Settings/Administrator/桌面/t.txt"); 35 fos.write(content); 36 37 }catch(FileNotFoundException e){ 38 System.out.println("找不到指定文件"); 39 }catch(Exception e){ 40 e.printStackTrace(); 41 }finally{ 42 HibernateUtils.closeSession(session); 43 } 44 } 45 }
这样,运行SaveFile.java,可以存储磁盘文件到数据库,运行LoadFile.java,可以读取数据库中的文件内容到磁盘。