hibernate如何保存blob数据

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hibernate如何保存blob数据相关的知识,希望对你有一定的参考价值。

首先你得搞清楚一点BLOB是二进制大对象,是ORACLE的数据类型,它对应到java中有两种方式:

byte[] 和java.sql.Blob(先搞清楚这重点哦)

我给你直接复制重点代码,希望可以帮到你

1 数据库中定义成BLOB类型,这个你自己定义吧(表名叫 bigobject),~~~~~不过给你截个图吧


2  综上,把oracle数据库中的BLOB映射到java中有两种情况的,即java.sql.Blob和byte[],下面先说byte[]的映射

++++++++++++++++++++++++Bigobject.hbm.xml映射文件+++++++++++++++++++++++

<hibernate-mapping>

    <class name="entity.Bigobject" table="BIGOBJECT" >

        <id name="id" type="java.lang.Integer">

            <column name="ID" precision="6" scale="0" />

            <generator class="native" />

        </id>

        <property name="tclob" type="java.lang.String">

            <column name="TCLOB" />

        </property>

        <property name="tblob" type="byte[]">    //!!!!!注意,这里是byte[]

            <column name="TBLOB" />

        </property>

    </class>

</hibernate-mapping>

++++++++++++++++++++以下是bigobject实体类(用hibernate映射的)+++++++++++


public class Bigobject  implements java.io.Serializable

    // Fields    


     private Integer id;

     private String tclob;

     private byte[] tblob;    //!!!!!注意,这里是byte[]



    // Constructors


    /** default constructor */

    public Bigobject()

   


    

    /** full constructor */

    public Bigobject(String tclob, byte[] tblob)

        this.tclob = tclob;

        this.tblob = tblob;

   


   

    // Property accessors


    public Integer getId()

        return this.id;

   

    

    public void setId(Integer id)

        this.id = id;

   


    public String getTclob()

        return this.tclob;

   

    

    public void setTclob(String tclob)

        this.tclob = tclob;

   


    public byte[] getTblob()

        return this.tblob;

   

    

    public void setTblob(byte[] tblob)

        this.tblob = tblob;

   

========================控制台测试代码(读取图片到数据库,

再从数据库读取图片到特定路径下)=======================================

/**

 * 按大对象数据类型BLOB的byte[]类型

 *                CLOB的java.lang.String 

 * 映射   并插入数据

 * @author Administrator

 *

 */

public class Test

     Session session=null;

     Transaction tx=null;


         /**

         * 持久化数据,读取本地图片到数据库

         */

         public void get1()

         try

                 session=HibernateSessionFactory.getSession();

                 //前提是文件必须放在src路径下,读取的是当前项目的根目录

                // InputStream input=this.getClass().getResourceAsStream("/file.txt");

                 //加载任意路径下的图片、大文件、视屏等(括号里的参数图片是绝对路径)

                 InputStream input=new FileInputStream("G:/在线拍卖/page/images/gou1.jpg");

                 tx=session.beginTransaction();

                 byte[] byteArray=new byte[input.available()];

                 input.read(byteArray);

                 input.close();

                

                 Bigobject b=new Bigobject();

                 b.setId(1);

                 b.setTblob(byteArray);

                 b.setTclob("一条狗");

                

                 session.save(b);

                 tx.commit();

           catch (HibernateException e)

            // TODO Auto-generated catch block

           e.printStackTrace();

           catch (IOException e)

          // TODO Auto-generated catch block

           e.printStackTrace();

             

        

        

         /**

         * 从数据库bigObject表中按主键读取一条数据

         * @throws IOException 

         */

         public void get2() throws IOException

         session=HibernateSessionFactory.getSession();

         Bigobject b=(Bigobject)session.get(Bigobject.class, 1);

         System.out.println("文本内容是:"+b.getTclob());

        

         //吧字节数组数据通过字节流,输出到当前工程根目录下2.jpg中

         if(b.getTblob()!=null)

         FileOutputStream out=new FileOutputStream("dog1.jpg");

         out.write(b.getTblob());

         out.close();

        

        

        

         public static void main(String[] args) throws IOException

             test6 t=new test6();

             t.get1();

             t.get2();

===================hibernate.cfg.xml的代码页给你贴一下吧,不过这都是自动生成的,你自己动手生成吧,一下是我自己的,想用的话得改参数的=======================

<?xml version='1.0' encoding='UTF-8'?>

<!DOCTYPE hibernate-configuration PUBLIC

          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"

          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">


<!-- Generated by MyEclipse Hibernate Tools.                   -->

<hibernate-configuration>


<session-factory>

<property name="dialect">

org.hibernate.dialect.Oracle9Dialect

</property>

<property name="connection.url">

jdbc:oracle:thin:@localhost:1521:accp7                 //!!!数据库名称

</property>

<property name="connection.username">scott</property>//!!!!!用户名

<property name="connection.password">accp</property>//!!!!!!密码

<property name="connection.driver_class">

oracle.jdbc.OracleDriver

</property>

<property name="myeclipse.connection.profile">scott</property>//!!!!!数据库实例名

<mapping resource="entity/Bigobject.hbm.xml" /> 

</session-factory>


</hibernate-configuration>


3 上面介绍了BLOB的byte[]存储,下面介绍另一种方式java.lang.Blob方式,还是直接粘贴代码

++++++++++++++++++++数据库还是上面图片上的,保持不变++++++++++++++++++++++

====================Bigobject.hbm.xml映射文件======================

<hibernate-mapping>

    <class name="bean.Bigobject" table="BIGOBJECT">

        <id name="id" type="java.lang.Integer">

            <column name="ID" precision="6" scale="0" />

            <generator class="native" />

        </id>

        <property name="tclob" type="java.sql.Clob">//这里用的是Clob的另一种方式,有疑问再问

            <column name="TCLOB" />

        </property>

        <property name="tblob" type="java.sql.Blob">//!!!!!注意,这里是java.sql.Blob

            <column name="TBLOB" />

        </property>

    </class>

</hibernate-mapping>


========================以下是bigobject实体类=======================

import java.sql.Blob;

import java.sql.Clob;


/**

 * Bigobject entity. @author MyEclipse Persistence Tools

 */


public class Bigobject implements java.io.Serializable


// Fields


             private Integer id;

             private Clob tclob;

             private Blob tblob;

            

             // Constructors

            

             /** default constructor */

             public Bigobject()

            

            

             /** full constructor */

             public Bigobject(Clob tclob, Blob tblob)

             this.tclob = tclob;

             this.tblob = tblob;

            

            

             // Property accessors

            

             public Integer getId()

             return this.id;

            

            

             public void setId(Integer id)

             this.id = id;

            

            

             public Clob getTclob()

             return this.tclob;

            

            

             public void setTclob(Clob tclob)

             this.tclob = tclob;

            

            

             public Blob getTblob()

             return this.tblob;

            

            

             public void setTblob(Blob tblob)

             this.tblob = tblob;

                


==========================对应的控制台测试代码===========================


/**

 * 讲字符串大对象声明为java.sql.Clob类型,二进制大对象声明为java.sql.Blob类型

 * @author Administrator

 *

 */

public class test7

             Session session=null;

             Transaction tx=null;

            

             public void get1()

             try

             session=HibernateSessionFactory.getSession();

             //前提是文件必须放在src路径下

             InputStream input=this.getClass().getResourceAsStream("/upload.txt");

             //加载任意路径下的图片、大文件、视屏等

            // InputStream input=new FileInputStream("F:/1.jpg");

             tx=session.beginTransaction();

             byte[] byteArray=new byte[input.available()];

             input.read(byteArray);

             input.close();

            

             Bigobject b=new Bigobject();

            //依据二进制数据创建一个Blob对象                   !!!!!重点 务必看清楚

             b.setTblob(Hibernate.createBlob(byteArray));

            //依据字符串数据创建一个Clob对象                    !!!!!重点 务必看清楚

             b.setTclob(Hibernate.createClob("上传图片"));

            

             session.save(b);

             tx.commit();

             catch (HibernateException e)

             // TODO Auto-generated catch block

             e.printStackTrace();

             catch (IOException e)

             // TODO Auto-generated catch block

             e.printStackTrace();

            

            

             public void get2()

             session=HibernateSessionFactory.getSession();

             Bigobject obj=(Bigobject)session.get(Bigobject.class, 131);

             //把Clob对象通过字符流读入到内存,并输出

            

             try

             if(obj.getTclob()!=null)

             Reader read=obj.getTclob().getCharacterStream();

             char[] chArray=new char[1];

             StringBuilder sb=new StringBuilder();

             while(read.read(chArray)!=-1)

             sb.append(new String(chArray));

            

             System.out.println(sb.toString().trim());

            

             catch (SQLException e)

             // TODO Auto-generated catch block

             e.printStackTrace();

             catch (IOException e)

             // TODO Auto-generated catch block

             e.printStackTrace();

            

             //把Blob对象通过字节流读输出,并保存到当前工程根目录下,取名为upload.txt

             try

             if(obj.getTblob()!=null)

             InputStream in=obj.getTblob().getBinaryStream();

             FileOutputStream fos=new FileOutputStream("upload.txt");

             int b=-1;

             while((b=in.read())!=-1)

             fos.write(b);

            

             fos.close();

             in.close();

            

             catch (FileNotFoundException e)

             // TODO Auto-generated catch block

             e.printStackTrace();

             catch (SQLException e)

             // TODO Auto-generated catch block

             e.printStackTrace();

             catch (IOException e)

             // TODO Auto-generated catch block

             e.printStackTrace();

            

            

            

             public static void main(String[] args)

                 test7 t=new test7();

                 t.get1();

                 t.get2();

            

++++++++++++++++++++hibernate.cfg.xml同上++++++++++++++++++++++++++++



===================================================================

综上,Blob与Clob(字符串大对象)的写入读出的两种方法都有了(Clob的两种方法你自己捎带看看),都是完整代码,粘贴即可用,整理了两个多小时,希望对你有帮助!

参考技术A   1、插入空blob

  into javatest(name,content) values(?,empty_blob());

  2、获得blob的cursor

  select content from javatest where name= ? for update;

  注意!!!必须加for update,这将锁定该行,直至该行被修改完毕,保证不产生并发冲突。

  3、update javatest set content=? where name=

  用cursor往数据库写数据

  这里面还有一点要提醒大家:

  JDK1.3带的JDBC2.0规范是不完善的,只有读Blob的接口,而没有写Blob的接口,JDK1.4带的JDBC3.0加入了写Blob的接口。你可以使用JDBC3.0的接口,也可以直接使用Oracle的JDBC的API,我在上例中使用了Oracle的JDBC的API。

  另外要注意的是:

  java.sql.Blob

  oracle.sql.BLOB

  注意看blob的大小写,是不一样的。写程序的时候不要搞混了。

  下面看看用Hibernate怎么写,原理是一样的,也要分三步,但是代码简单很多

  这是Cat对象定义

  package com.fankai;

  import java.sql.Blob;

  public class Cat
  private String id;
  private String name;
  private char sex;
  private float weight;
  private Blob image;
  public Cat()

  public String getId() return id;
  public void setId(String id) this.id = id;

  public String getName() return name;
  public void setName(String name) this.name = name;

  public char getSex() return sex;
  public void setSex(char sex) this.sex = sex;

  public float getWeight() return weight;
  public void setWeight(float weight) this.weight = weight;

  public Blob getImage() return image;
  public void setImage(Blob image) this.image = image;
  

  这是Cat.hbm.xml

  <?xml version="1.0"?>
  <!DOCTYPE hibernate-mapping SYSTEM "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

  <hibernate-mapping>
  <class name="com.fankai.Cat" table="cat">
  <!--jcs-cache usage="read-only"/-->
  <id name="id" unsaved-value="null">
  <generator class="uuid.hex"/>
  </id>
  <property name="name" length="16" not-null="true"/>
  <property name="sex" length="1" not-null="true"/>
  <property name="weight" />
  <property name="image" />
  </class>
  </hibernate-mapping>
参考技术B 通过转换把大类型转换成小类型来保存 参考技术C java.sql.Blob n=Hibernate.createBlob(bytes);
你可以参考下下面这个例子,应该对你有很大帮助
http://developer.51cto.com/art/200906/130231.htm

如何将blob url数据保存在目录中

【中文标题】如何将blob url数据保存在目录中【英文标题】:How to save blob url data in a directory 【发布时间】:2017-05-02 04:24:37 【问题描述】:

我正在处理录音。现在我想直接将录制的音频保存在我们的本地。当我录制音频时,它会返回 blob URL,例如:

blob:http://example.com/7737-4454545-545445。

当我点击此 URL 时,它会播放录制的音频。现在我将该 blob URL 从 js 发送到 PHP 脚本以保存您的本地目录,但它不起作用。

我该怎么做?

【问题讨论】:

如果你不发布你的代码并告诉我们什么是不工作的(JavaScript 不发送?php 不接收?文件不保存?保存但不可读?) 【参考方案1】:

Blob URL 生命周期链接到 document,它从 BlobFile 对象创建了 Blob URLBlob URL 不能发布到服务器作为存储在 snapshot state 的 Blob 的参考。见Blob URL Store。

您可以使用fetch()Response.blob() 获取Blob 表示Blob URL,将FormData 发布到服务器。

// `blobURL` : `"blob:http://example.com/7737-4454545-545445"`
fetch(blobUrl).then(response => response.blob())
.then(blob =>  
  const fd = new FormData();
  fd.append("fileName", blob, "file.ext"); // where `.ext` matches file `MIME` type  
  return fetch("/path/to/server", method:"POST", body:fd)
)
.then(response => response.ok)
.then(res => console.log(res))
.catch(err => console.log(err));

【讨论】:

以上代码给出以下错误-TypeError: HEAD or GET Request cannot have a body. 查看更新后的帖子。在第二个参数传递的init 对象处将method 设置为"POST"。见developer.mozilla.org/en-US/docs/Web/API/… 在 PHP 脚本中我得到 $__FILES 元素。对于上传,我使用以下代码。但它只是保存名为 blob 的文件,而不是音频文件。定义('UPLOAD_DIR','上传/'); if($_FILES['fileName']) $target_path = UPLOAD_DIR . basename($_FILES['fileName']['name']); if(move_uploaded_file($_FILES['fileName']['tmp_name'], $target_path)) echo "文件".基本名称($_FILES['fileName']['name'])。 “已上传”; else echo "上传文件出错,请重试!";如何在这里获取音频文件? 尝试将包含扩展名的文件名设置为FormData.prototype.append()fd.append("fileName", blob, "audio.ogg"); // or appropriate .ext for MIME type of file 对编辑表示歉意!发错帖子了:o 请编辑回来我在国外用我的手机很抱歉!

以上是关于hibernate如何保存blob数据的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate/hsqldb 2 无法水合 Blob 列

如何将 LocalDate 作为 Date 类型持久保存到 Hibernate

如何使用 Hibernate 在 Oracle 中保留 LARGE BLOB (>100MB)

Hibernate操作Blob数据

Hibernate向数据库存入BLOB和CLOB类型的数据

Struts+Spring+Hibernate处理Lob(Blob,Clob)