乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Java大對象類型的Hibernate映射

       feimishiwo 2014-04-29
        
      Java中,java.lang.String可用于表示長字符串(長度超過255),字節(jié)數(shù)組byte[]可以用于存放圖片戶或文件二進(jìn)制數(shù)據(jù)。此外,在JDBC API中還提供了java.sql.CLOBjava.sql.BLOB類型,他們分別表示標(biāo)準(zhǔn)SQL中的CLOB(字符大對象)和BLOB(二進(jìn)制大對象)類型。表2.4列出了Java大對象,Hibernate映射類型以及標(biāo)準(zhǔn)SQL的對應(yīng)關(guān)系。
      2.4
       
       
       
       
      映射類型
      Java類型
      標(biāo)準(zhǔn)SQL類型
      binary
      byte[]
      VARBINARY(或者BLOB)
      text
      java.lang.String
      CLOB
      serilizable
      實現(xiàn)java.io.Serializable的任何一個Java
      VARBINARY(或者BLOB)
      clob
      java.sql.CLOB
      CLOB
      blob
      java.sql.BLOB
      BLOB
      注意:不允許用表2.4中列出的數(shù)據(jù)類型來定義持久化類的OID
      2)、BLOB,CLOB數(shù)據(jù)的處理(以Oracle數(shù)據(jù)庫為例):
       假設(shè)我們有如下表
       
      T_User 
      id     number   <pk>
      name varchar2(50)
      age    number
      image    BLOB
      resume   CLOB          
       對應(yīng)的映射文件如下:
      <hibernate-mapping>
       <class name=”com.neusoft.hibernate.db.entity.TUser” table=”T_User”>
      <id name=”id” column=”id” type=”java.lang.Integer”>
       <generator class=”native”/>
      </id>
      <property name=”name” type=”java.lang.String” column=”name”/>
      <property name=”age” type=”java.lang.Integer” column=”age”/>
      <property name=”image” type=”java.sql.Blob” column=”image”/>
      <property name=”resume” type=”java.sql.Clob” column=”resume”/>
       </class>
      </hibernate-mapping>
      實體類如下:
      public class Tuser implements Serializable{
       private Integer id;
       private String name;
       private Integer age;
       private Blob image;
       private Clob resume;
       …getter/setter…..
      }
      BLOBCLOB這種大對象一般都是采用流機(jī)制作為數(shù)據(jù)讀取方式,所以這種讀取方式在Oracle這種自視為數(shù)據(jù)庫中貴族的數(shù)據(jù)庫中對這種操作就會有諸多的限制,有時候會叫人覺得不太友好(這是典型的店大欺客)
      限制一:Oracle JDBC不允許流操作以批量方式執(zhí)行,如果發(fā)生這種錯誤一般會拋出
      ERROR JDBCExceptionReport:streams type cannot be used in batching.出現(xiàn)這種情況一般都需要將hibernate.cfg.xml中的hibernate.jdbc.batch_size設(shè)定為0即可消除,但是這就會影響其他的更新,插入,刪除操作的性能,因此必須在一個數(shù)據(jù)庫事務(wù)中對Clob,Blob進(jìn)行操作,也只有在一個數(shù)據(jù)庫事務(wù)中Clob,Blob對象才會有效。
      限制二:Oalce Blob/Clob具有獨(dú)特的訪問方式,這種類型字段擁有一個游標(biāo)(cursor),JDBC必須通過游標(biāo)對Blob/Clob進(jìn)行操作,在Blob/Clob創(chuàng)建之前我門無法獲得其游標(biāo)句炳,這就意味著必須首先創(chuàng)建一個空Blob/Clob字段,在叢空Blob/Clob獲取游標(biāo),然后寫入我們期望的數(shù)據(jù)。
       
      首先看一下采用傳統(tǒng)JDBC進(jìn)行操作的代碼:
      //….獲取Connection連接
      conn.setAtuoCommit(false);
      //插入Blob/Clob空值字段
      PrepareStatement prestmt=conn.prepareStatement(“insert into T_USER(name,age,id,image,resume) values(?,?,?,?,?)”);
      prestmt.setString(1,”zx”);
      prestmt.setInt(2,26);
      prestmt.setInt(3,5);
      //通過oracle.sql.BLOB/CLOB.empty_lob()方法構(gòu)造空Blob/Clob對象
      prestmt.setBlob(4,oracle.sql.BLOB.empty_lob());
      prestmt.setClob(5,oracle.sql.CLOB.empty_lob());
      prestmt.executeUpdate();
      prestmt.close();
      //再次從數(shù)據(jù)庫中獲得Blob/Clob句炳
      prestmt=conn.prepareStatement(“select image,resume from T_USER where id=? for update ”);
      prestmt.setInt(1,5);
      ResultSet rset=prestmt.executeQuery();
      rset.next();
      oracle.sql.BLOB imgBlob=(oracle.sql.BLOB)rset.getBlob();
      oracle.sql.CLOB resClob=(oracle.sql.CLOB)rset.getClob();
      //將二進(jìn)制數(shù)據(jù)寫入Blob
      FlieInputStream fin=new FileInputStream(“c://image.jpg”);
      OutputStream out=imgBlob.getBinaryOutputStream();
      byte[] buf=new byte[fin.available()];
      int len;
      while((len=fin.read(buf))!=-1){
       out.write(buf,0,len);
      }
      fin.close();
      out.close();
      //將字符串寫入Clob
      resClob.putString(1,”This is my clob”);
      //將更新寫回數(shù)據(jù)庫
      prestmt=conn.prepareStatement(“update T_USER set image=?,resume=? where id=? ”);
      prestmt.setBlob(1,imgBlob);
      prestmt.setClob(2,resClob);
      prestmt.setInt(3,5);
      prestmt.executeUpdate();
      prestmt.close();
      conn.commit();
      conn.close();
       
       
      以上是傳統(tǒng)的采用JDBC方式處理,注意他將連接的自動提交屬性設(shè)置為false然后將所有的操作并入一個事務(wù)中,然后進(jìn)行提交,這是處理OracleBlob/Clob字段的一般機(jī)制,所以Hibernate的處理就應(yīng)該模仿JDBC的處理方式,因為從某種角度來講Hibernate是對JDBC的封裝因為它的底層訪問機(jī)制仍然是基于JDBC的。
       
      Hibernate的處理:
      TUser user=new TUser();
      user.setAge(new Integer(26));
      user.setName(“zx”);
      //創(chuàng)建空Blob/Clob對象
      user.setImage(Hibernate.createBlob(new byte[1]));
      user.setResume(Hibernate.createClob(“ “));//注意這里的參數(shù)是一個空格
      Transaction tx=session.beginTransaction();
      session.save(user);
      //調(diào)用flush方法,強(qiáng)制Hibernate立即執(zhí)行insert sql
      session.flush();
      //通過refresh方法,強(qiáng)制Hibernate執(zhí)行select for update
      session.refresh(user,LockMode.UPGRADE);
      //Blob寫入實際內(nèi)容
      oracle.sql.BLOB blob=(oracle.sql.BLOB)user.getImger();
      OutputStream out=blob.getBinaryOutputStream();
      FileInputStream fin=new FileInputStream(“c://image.jpg”);
      byte[] buf=new byte[fin.available()];
      int len;
      while((len=fin.read())!=-1){
       out.write(buf,0,len);
      }
      fin.close();
      out.close();
      //Clob中寫入數(shù)據(jù)
      oracle.sql.CLOB clob=user.getResume();
      java.io.Writer writer=clob.getCharacterOutputStream();
      writer.write(“This is my resume!”);
      writer.close();
      session.saveOrUpdate(user);
      session.commit();
      tx.commit();
       
      在實際應(yīng)用中,對于Clob字段可以簡單的將其映射為String類型,不過在Oracle Thin DriverClob字段支持上有欠缺,當(dāng)Clob內(nèi)容超過4000字節(jié)時將無法讀取,而Oracle OCI Driver(需要在本地安裝客戶端組件)則可以完成大容量Clob字段操作。
       
      對于上面的代碼相信作為成熟的工程師來說都聞到一些bad smell,如果Blob/Clob字段普遍存在的話,那么我們的持久層邏輯可能遍布這種復(fù)雜的邏輯,不過不要著急在我即將講解的客戶自定義類中我們將會看到一個解決方案,通過自定義類型我們可以對數(shù)據(jù)類型的通用性進(jìn)行抽象,對于Blob/Clob字段我們可以定義一種類型并以這種類型作為Blob/Clob字段的映射類型。(好了等到下一篇再說吧?。?/span>

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多