麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁(yè) > 數(shù)據(jù)庫(kù) > 文庫(kù) > 正文

利用Hibernate儲(chǔ)存大對(duì)象到達(dá)夢(mèng)數(shù)據(jù)庫(kù)

2024-09-07 22:12:19
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

  使用達(dá)夢(mèng)數(shù)據(jù)庫(kù)的大字段前不得不說(shuō)一下數(shù)據(jù)庫(kù)大字段的性能問(wèn)題:在數(shù)據(jù)庫(kù)中,經(jīng)常需要用到大字段類型,如Oracle中l(wèi)ong、blob、clob,SQLServer中的text、image,MySql中的text、longtext、clob、blob以及達(dá)夢(mèng)數(shù)據(jù)庫(kù)中的clob、blob類型。存儲(chǔ)的信息大概主要是兩類,一類是長(zhǎng)文本,如大段的文字,普通的varchar最長(zhǎng)只能存儲(chǔ)4K的數(shù)據(jù),已經(jīng)不能滿足要求;另一類是存儲(chǔ)二進(jìn)制信息,如上傳的文件等。不過(guò)通常情況下,大字段不意味著保存很大的文件,例如很長(zhǎng)的文章,圖標(biāo),小圖片等等。數(shù)據(jù)過(guò)大保存在數(shù)據(jù)庫(kù)有諸多的問(wèn)題:

  1.速度慢:影響一張表的查詢速度的,除了行數(shù),還包括表所占的物理空間的大小。此表在數(shù)據(jù)量較小時(shí),在查詢方面感覺不到明顯的差異。但是如果某個(gè)字段所存儲(chǔ)的數(shù)據(jù)都是大段文本或較大的文件時(shí),會(huì)導(dǎo)致表的物理空間迅速變大,該字段所占用的空間有可能達(dá)到整表所占空間的90%以上。在此基礎(chǔ)上,如果行數(shù)再增加到數(shù)十萬(wàn)、上百萬(wàn)級(jí)時(shí),整個(gè)表所占的空間將達(dá)到一個(gè)驚人的數(shù)字,查詢的速度亦會(huì)受到非常大的影響。

  2.操作不方便:必須把數(shù)據(jù)庫(kù)打開一個(gè)流,構(gòu)造一個(gè)Buffer,然后再輸出一個(gè)ServletOutputStream。占用數(shù)據(jù)庫(kù)連接,加重?cái)?shù)據(jù)庫(kù)訪問(wèn)負(fù)載不說(shuō),如果用戶突然中斷下載,還需要處理數(shù)據(jù)庫(kù)關(guān)閉動(dòng)作,容易造成性能問(wèn)題。如果把整個(gè)數(shù)據(jù)讀入內(nèi)存再輸出,則內(nèi)存占用非常可觀。如果是硬盤文件,只要返回一個(gè)URL 就可以了。即使你不希望用戶直接訪問(wèn)到文件,你也可以構(gòu)造一個(gè)IOStream來(lái)輸出文件,既不會(huì)占用數(shù)據(jù)庫(kù)資源,傳輸速度也快。

  3.性能有問(wèn)題:特別的情況是,如果并發(fā)很多用戶來(lái)下載大文件的時(shí)候,應(yīng)用服務(wù)器要占用非常多的內(nèi)存來(lái)緩存文件內(nèi)容,假設(shè)并發(fā)10個(gè)用戶,下載10MB的文件,JVM的峰值就至少需要100MB內(nèi)存來(lái)支撐,很容易造成JVM崩潰。

  所以說(shuō)數(shù)據(jù)庫(kù)大字段并不適合存儲(chǔ)過(guò)大的數(shù)據(jù),數(shù)據(jù)過(guò)大可能會(huì)影響到數(shù)據(jù)庫(kù)存儲(chǔ)的性能。

  下面言歸正傳,使用Hibernate操作達(dá)夢(mèng)數(shù)據(jù)庫(kù)中的大字段應(yīng)該有如下幾步:

  1 首先需要一張表存儲(chǔ)大字段數(shù)據(jù):包括內(nèi)容,類型;

  2 必須得到一個(gè)代表上傳文件的數(shù)據(jù)流;

  3 進(jìn)行保存操作

  好了我們先建一張表,里面包括達(dá)夢(mèng)數(shù)據(jù)庫(kù)的2個(gè)大字段類型(CLOB、BLOB)字段:

  --創(chuàng)建表
  create table TESTLOB(
   ID int primary key,
   TITLE varchar(50),
   CLOBNAME varchar(50),
   CLOBCONTENT clob,
   BLOBNAME varchar(50),
   BLOBCONTENT blob
  );
 
  在建立一個(gè)序列用于處理表的流水ID:

  --創(chuàng)建序列
  create SEQUENCE "TESTLOB"."SEQ_TESTLOB_ID"
  INCREMENT BY 1 START WITH 1 MAXVALUE 100000 MINVALUE 1
  NOCYCLE

  然后編寫關(guān)于這2個(gè)大字段的Java對(duì)象文件TestLob.java,分別定義類型為CLOB和BLOB屬性字段為String和byte[]類型,其中由于CLOB是處理大文本類型所以它對(duì)應(yīng)了Java中的String類型,BLOB是處理一些以二進(jìn)制流形勢(shì)存儲(chǔ)的沒有嚴(yán)ge定義的大文件所以讓它使用byte[]類型,然后分別定義這2個(gè)屬性的Getter和Setter方法,相關(guān)代碼如下:

  package com.dm.lobtest.vo;

  public class TestLob {
   private int id;
   private String title;        //記錄標(biāo)題
   private String clobName;     //clob文件名稱
   private String clobContent;  //clob文件
   private byte[] blobContent;  //blob文件
   private String blobName;     //blob文件名稱
  
   public byte[] getBlobContent() {
    return blobContent;
   }
   public void setBlobContent(byte[] blobContent) {
    this.blobContent = blobContent;
   }
 
   public String getClobContent() {
    return clobContent;
   }
   public void setClobContent(String clobContent) {
    this.clobContent = clobContent;
   }
   public int getId() {
    return id;
   }
   public void setId(int id) {
    this.id = id;
   }
   public String getTitle() {
    return title;
   }
   public void setTitle(String title) {
    this.title = title;
   }
   public String getBlobName() {
    return blobName;
   }
   public void setBlobName(String blobName) {
    this.blobName = blobName;
   }
   public String getClobName() {
    return clobName;
   }
   public void setClobName(String clobName) {
    this.clobName = clobName;
   }

   } 

  將對(duì)象的映射文件中主健字段元素的內(nèi)置Generator指定為sequence,并與達(dá)夢(mèng)數(shù)據(jù)庫(kù)重的內(nèi)置序列(sequence)關(guān)聯(lián),最后指定CLOB類型的屬性為"string"類型,BLOB類型的屬性為"binary"類型:

  <?xml version="1.0" encoding="GB2312"?>
  <!DOCTYPE hibernate-mapping PUBLIC
   "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  <hibernate-mapping>

   <class name="com.dm.lobtest.vo.TestLob" table="TESTLOB">
        <id name="id" column="ID" type="int">
     <generator class="sequence">
      <param name="sequence">SEQ_TESTLOB_ID</param>
     </generator>
    </id> 
    <property name="title" column="TITLE" type="string" />
    <property name="clobName" column="CLOBNAME" type="string" />
    <property name="blobName" column="BLOBNAME" type="string" />
    <property name="clobContent" column="CLOBCONTENT" type="string" />
    <property name="blobContent" column="BLOBCONTENT" type="binary" />   
  </class>

  </hibernate-mapping>
 
  完成以上這些操作后我們可以開始編寫上傳文件頁(yè)面和處理上傳文件的業(yè)務(wù)邏輯了,

  定義上傳文件頁(yè)面:

  <form name="myTestLobFrm" method="post" enctype="multipart/form-data" action="/LobTest/testlob.do?method=save">
   <table align="center">
    <tr>
     <td colspan="2">
      <b>達(dá)夢(mèng)數(shù)據(jù)庫(kù)CLOB和BLOB數(shù)據(jù)類型在Hibernate下使用的示例</b>
     </td>
    </tr>
    <tr>
     <td>標(biāo)題:</td>
     <td>
      <input type="text" name="title" size="81">
     </td>
    </tr>
    <tr>
     <td>文件內(nèi)容:</td>
     <td>
      <textarea rows="20" cols="80" name="clobTest" ></textarea>
     </td>
     </tr>
    <tr>
     <td>附件:</td>
     <td>
      <input type="file" name="blobTest" size="71">
     </td>
    </tr>
    <tr>
     <td colspan="2" align="center">
      <input type="submit" value=" 確  認(rèn) ">
     </td>
    </tr>
    <tr>
     <td colspan="2" align="center"> <font id="info" color="red"><%=message %></font></td>
    </tr>
   </table>
  </form>
 
  處理業(yè)務(wù)邏輯類:

  public class TestLobAction extends DispatchAction{

  public ActionForward save(ActionMapping mapping, ActionForm form,
        HttpServletRequest request, HttpServletResponse response) throws   Exception {
  try{
     //設(shè)置文件標(biāo)題
     String title = request.getParameter("title");
     TestLob testLob = new TestLob();
     testLob.setTitle(title);
   
     //處理blob字段
     Hashtable files = form.getMultipartRequestHandler().getFileElements();
     FormFile blobTestFile = (FormFile) files.get("blobTest");//得到文件
     String blobName = blobTestFile.getFileName();            //得到文件名
     testLob.setBlobName(blobName);                           //設(shè)置文件
     byte[] blobContent=blobTestFile.getFileData();           //得到文件內(nèi)容
     testLob.setBlobContent(blobContent);                     //設(shè)置文件內(nèi)容
   
     //處理clob字段
     String clobName = title;      //文件名就是標(biāo)題名
     String clobContent = request.getParameter("clobTest");   //得到文件
     testLob.setClobName(clobName);                           //設(shè)置文件名
     testLob.setClobContent(clobContent);                     //設(shè)置文件
   
     TestLobService testLobService = TestLobService.getInstance();
     if(testLobService.createTestLob(testLob)==0){
      request.setAttribute("message", "上傳失敗");
      return list(mapping,form,request,response);
     }
    }catch(Exception e){
     throw new BaseException();
    }
    request.setAttribute("message", "上傳成功");
    return list(mapping,form,request,response);
  }
   }
 
  因?yàn)閏lob字段對(duì)應(yīng)的是String類型,所以可以直接將表單中得到的數(shù)據(jù)設(shè)置到對(duì)象的屬性中去,而blob類型處理的是二進(jìn)制類型的文件,我們需要將得到的文件以流的形式存入到對(duì)象的屬性中,這里我使用了struts的FormFile組件來(lái)進(jìn)行文件的上傳,將得到的數(shù)據(jù)流設(shè)置到對(duì)象的屬性中。

  完成以上操作后我們就可以將設(shè)置好的對(duì)象用以下面的方法保存數(shù)據(jù)到數(shù)據(jù)庫(kù)中:

  首先定義一個(gè)Hibernate的Session管理類:HibernateUtil.java,它是使用ThreadLocal類建立的一個(gè)Session管理的輔助類。

  package com.dm.lobtest.util;

  import org.hibernate.HibernateException;
  import org.hibernate.Session;
  import org.hibernate.SessionFactory;

  public class HibernateUtil {
        private static SessionFactory sessionFactory = null;

        public static final ThreadLocal session = new ThreadLocal();

        public static Session currentSession() throws HibernateException {
                if (sessionFactory == null) {
                        if (getSystemSessionFactory() == false) {
                                throw new HibernateException(
                                                "Exception geting SessionFactory ! ");
                        }
                }
                Session s = (Session) session.get();
                // 如果該線程還不存在,打開一個(gè)新的Session
                if (s == null) {
                        s = sessionFactory.openSession();
                        session.set(s);
                }
                return s;
        }

        public static void closeSession() throws HibernateException {
                Session s = (Session) session.get();
                session.set(null);
                if (s != null)
                        s.close();
        }
  }
 
  最后利用Hibernate的運(yùn)作中心--Session接口的save()方法保存對(duì)象并提交相關(guān)的Session實(shí)例:

  public int createTestLob(TestLob testLob){
   Session session = null;
   try{
      session = HibernateUtil.currentSession();
      Transaction tr = session.beginTransaction();
      session.save(testLob);
      tr.commit();
      return 1;
   }catch(Exception e){
    e.printStackTrace();
    return 0;
   }finally {
            try {
                if (session != null) {
                    HibernateUtil.closeSession();
                }
             }catch (Exception ex) {}
         }
  }

  現(xiàn)在我們已經(jīng)利用Hibernate完成了多個(gè)不同的大數(shù)據(jù)類型存儲(chǔ)到達(dá)夢(mèng)數(shù)據(jù)庫(kù)中的全過(guò)程。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 国产妞干网 | 久久久青青草 | 国产精品视频导航 | 一二区成人影院电影网 | 久久99精品久久久久久国产越南 | 91精品国产综合久久婷婷香 | av国产在线被下药迷网站 | 亚洲二区不卡 | 精品久久久久久久久久久久久久 | 免费在线看a | china对白普通话xxxx | 视频在线亚洲 | 久草在线资源观看 | 国产精品自拍啪啪 | 91av资源在线 | 久草手机在线 | av成人在线免费观看 | 欧美精品一区二区久久久 | 一区二区免费看 | 色播视频在线播放 | 国产精品99精品 | 中文字幕免费看 | 羞羞视频免费视频欧美 | 欧美成人免费在线视频 | 97超视频在线观看 | 毛片视频免费播放 | 最新中文字幕日本 | 亚洲第一精品在线 | 日韩欧美激情视频 | 国产一区二区影视 | 黄色羞羞 | 国产成人高清在线观看 | 国产做爰 | 欧美日韩爱爱视频 | 黄色av电影在线 | 国产午夜精品理论片a级探花 | 欧美一区2区三区4区公司二百 | 91麻豆精品国产91久久久无需广告 | 国产午夜精品一区二区三区视频 | 国产午夜免费 | 色吧久久 |