自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

使用Hibernate SQLquery實現(xiàn)動態(tài)表

開發(fā) 后端
本文向您介紹使用Hibernate SQLquery實現(xiàn)動態(tài)表的思路和實現(xiàn)方法,通過Hibernate SQLquery可以很好的解決問題,并且可以重新用于Hibernate hbm機制。

在實際的項目應(yīng)用中,有時會設(shè)計出這樣的一種數(shù)據(jù)表,每個時間段產(chǎn)生一個新表,例如是按年或月或日。相同類型的表中,所有的字段結(jié)構(gòu)都是一樣的。而 Hibernate 提供的類與表的映射,是只能映射到一個具體表的,在程序的運行過程中,很難去動態(tài)修改一個 hbm 對應(yīng)的表名。我在網(wǎng)上也有看到一實現(xiàn),但是很復(fù)雜,并且不符合我的要求。

因此我就想到直接用 jdbc 去操作數(shù)據(jù)庫,這樣的做法是繞過 Hibernate 了。方法是從 Hibernate 的 session 中,直接取得數(shù)據(jù)庫 connection ,然后就直接 jdbc 了。

后來在升級了 proxool 到 9.0RC3 后,發(fā)現(xiàn)居然出現(xiàn)了數(shù)據(jù)庫連接無法釋放的問題。為了解決這個問題,我查閱了 Hibernate doc。我發(fā)現(xiàn)原來用Hibernate SQLQuery 可以更好的解決,并且可以重新用于 Hibernate hbm 機制。以下舉例說明。

例如我有一個 pojo 是 ReadInfo,用來記錄閱讀信息的。由于數(shù)據(jù)量寵大,所以我的思路是按月劃分,每個月一張表。所以只是表名不同,而字段是完全相同的。

ReadInfo.java 是這樣的,其中 userId, year, month, day 是聯(lián)合主鍵:

private Integer userId;

private Integer year;

private Integer month;

private Integer day;

private Integer point ;

那么相應(yīng)的 ReadInfo.hbm.xml 的片段是

  1. < class name"ReadInfo" table"tblReadInfo " mutable = "false" >   
  2.         < composite-id>   
  3.             < key-property name"userId" column"userId" type"integer" / >   
  4.             < key-property name"year" column"year" type"integer" / >   
  5.             < key-property name"month" column"month" type"integer" / >   
  6.             < key-property name"day" column"day" type"integer" / >   
  7.         < / composite-id>   
  8.         < property name"point" column"point" type"integer" / >   
  9.     < / class>  

上面的xml,注意 2 個細節(jié)

1. pojo 所映射的 table tblReadInfo 實際上是不存在的。實際的表是 tblRead200710 之類的;

2. mutable 要設(shè)置為 false,即是說,關(guān)閉 Hibernate 對這個 pojo 的任何持久化操作,以避免 Hibernate 把數(shù)據(jù)寫到 tblReadInfo 中(這個表是不存在的嘛)。因此,所有的持久化操作,都是需要自己通過Hibernate SQLQuery 來處理。

現(xiàn)在可以看一下 ado 中的操作了,先看一個 select 操作

  1. public ReadInfo selectReadInfo( Integer userId, Integer year,   
  2.             Integer month, Integer day) throws HibernateException  
  3.     {   
  4.          ReadInfo readInfo = null ;   
  5.  
  6.          Session session = getSession ( ) ;   
  7.         Transaction tx = session. beginTransaction( ) ;   
  8.  
  9.         try   
  10.         {   
  11.             String sql = "select * from tblRead"   
  12.                 + Misc. formatMoon( year, month)   
  13.                 + " where userId=? and day=?" ;   
  14.  
  15.              SQLQuery query = session. createSQLQuery( sql ) ;   
  16.             query . addEntity( ReadInfo. class ) ;   
  17.  
  18.             query . setLong ( 0, userId) ;   
  19.             query . setInteger( 1, day) ;   
  20.  
  21.              readInfo = ( ReadInfo) query . uniqueResult( ) ;   
  22.  
  23.              tx. commit ( ) ;   
  24.         }   
  25.         catch ( HibernateException e)   
  26.         {   
  27.             log . error ( "catch exception:" , e) ;   
  28.  
  29.             if ( tx ! = null )   
  30.             {   
  31.                  tx. rollback ( ) ;   
  32.             }   
  33.  
  34.             throw e;   
  35.         }   
  36.         return readInfo;   
  37.     }  

上面的代碼,關(guān)鍵是以下幾點:

1. 通過函數(shù)參數(shù)的 year, month 來確定要操作的表名,我自己寫了一個 Misc.formatMoon(year, month) 來生成 "yyyyMM" 格式的字串;

2. 使用了 SQLQuery ,再通過 query.addEntity(ReadInfo.class); 建立與 ReadInfo 的映射關(guān)系;

3. query.setXxx() 與 PreparedStatement 的類似,不過索引是從 0 開始;

4. 其它的就跟一般的 Query 操作類似的了。

再看一個 insert 操作

  1. public void insertReadInfo( ReadInfo readInfo) throws HibernateException  
  2.     {   
  3.          Session session = getSession ( ) ;   
  4.         Transaction tx = session. beginTransaction( ) ;   
  5.  
  6.         try   
  7.         {   
  8.             String sql = "insert into tblRead"   
  9.                 + Misc. formatMoon( readInfo. getYear ( ) , readInfo. getMonth ( ) )   
  10.                 + " (userId, year, month, day, point) values (?, ?, ?, ?, ?)" ;   
  11.  
  12.              SQLQuery query = session. createSQLQuery( sql ) ;   
  13.  
  14.             query . setLong ( 0, readInfo. getUserId( ) ) ;   
  15.             query . setInteger( 1, readInfo. getYear ( ) ) ;   
  16.             query . setInteger( 2, readInfo. getMonth ( ) ) ;   
  17.             query . setInteger( 3, readInfo. getDay ( ) ) ;   
  18.             query . setInteger( 4, readInfo. getPoint ( ) ) ;   
  19.  
  20.             query . executeUpdate ( ) ;   
  21.  
  22.              tx. commit ( ) ;   
  23.         }   
  24.         catch ( HibernateException e)   
  25.         {   
  26.             log . error ( "catch exception:" , e) ;   
  27.  
  28.             if ( tx ! = null )   
  29.             {   
  30.                  tx. rollback ( ) ;   
  31.             }   
  32.  
  33.             throw e;   
  34.         }   
  35.     }  

同理,update, delete 等操作也是這樣通過Hibernate SQLquery來實現(xiàn)的。

這種Hibernate SQLquery處理方式的麻煩的地方是需要手工寫 SQL,因此要盡量寫通用的標(biāo)準(zhǔn)SQL,不然在數(shù)據(jù)庫兼容方面會有問題。當(dāng)然,有時是會出現(xiàn)無法兼容的情況,那么可以考慮把 SQL寫到配置文件中,根據(jù)不同的數(shù)據(jù)庫,裝載相應(yīng)的配置文件。

 

【編輯推薦】

  1. Hibernate更新出錯的解決
  2. 深入淺出Hibernate學(xué)習(xí)筆記 Criteria Query
  3. 正確理解Hibernate Inverse
  4. 對Hibernate緩存機制的分析
  5. Hibernate HQL查詢解析
責(zé)任編輯:佚名 來源: CSDN
相關(guān)推薦

2011-04-07 14:04:28

SQL動態(tài)交叉表

2009-06-26 10:12:00

Hibernate自動

2009-09-25 10:38:42

Hibernate動態(tài)

2010-11-12 13:27:13

動態(tài)sql

2018-06-04 16:20:56

Linux動態(tài)路由Quagga

2009-09-23 10:14:10

Hibernate使用

2009-09-28 13:43:28

使用Hibernate

2009-09-25 13:55:05

Hibernate使用

2009-09-29 16:48:42

Hibernate J

2009-09-21 17:23:49

Hibernate使用

2009-09-23 10:28:49

使用Hibernate

2009-06-30 16:52:30

DetchedCrit

2009-09-14 19:20:22

LINQ TO SQL

2009-06-02 17:27:28

Hibernate框架ORM

2009-06-25 16:49:24

Hibernate

2009-09-25 11:14:16

Hibernate批量

2009-06-29 09:00:42

Hibernate的Q

2009-09-22 13:41:10

直接使用Hiberna

2011-03-24 11:37:41

Hibernate

2012-02-08 11:01:53

HibernateJava
點贊
收藏

51CTO技術(shù)棧公眾號