解決Hibernate SQL Query Cache的一個可靠性問題_第1頁
解決Hibernate SQL Query Cache的一個可靠性問題_第2頁
解決Hibernate SQL Query Cache的一個可靠性問題_第3頁
解決Hibernate SQL Query Cache的一個可靠性問題_第4頁
解決Hibernate SQL Query Cache的一個可靠性問題_第5頁
全文預(yù)覽已結(jié)束

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、解決Hibernate SQL Query Cache的一個可靠性問題(附源碼) 上篇 帖子 Hibernate查詢緩存的一個可靠性問題 Java代碼 1. private final Set querySpaces = new HashSet();    private final Set querySpaces = new HashSet();     通過源碼分析,發(fā)現(xiàn) querySpaces  主要用來進(jìn)行Cache更新檢查,querySpaces 

2、; 存放的是基本VOClass 對應(yīng)的 tableName, 例如: SYS_PERM,SYS_USER . Hibernate 在執(zhí)行查詢時,會檢查這個集合中的所有 tableName, 如果該任意一個 tableName 對應(yīng) VOClass 二級緩存 有增,刪,改的更新操作,即 UpdateTimestampsCache 不是最新的 ,那么該 Query 的 cache 就失效,就會重新去數(shù)據(jù)庫中查詢 ID 集合。     SQLCustomQuery 在構(gòu)造函數(shù)中即進(jìn)行 sql 的解析和querySpaces的判斷,其中中有這樣一段代碼: Java代碼 1

3、.   public SQLCustomQuery(.) throws HibernateException    2.     SQLQueryReturnProcessor processor = new SQLQueryReturnProcessor(queryReturns, scalarQueryReturns, factory);   3.    proc

4、cess();   4.      .   5.     SQLLoadable entityPersisters = (SQLLoadable) processor.getPersisters().toArray( new SQLLoadable0 );   6.      .   7.

5、   for (int i = 0; i < entityPersisters.length; i+)    8.       SQLLoadable persister = entityPersistersi;   9.    /alias2Persister.put( aliasesi, 

6、persister );   10.   /TODO:Does not consider any other tables referenced in the query       11. ArrayHelper.addAll( querySpaces, persister.getQuerySpaces() );   12.  

7、0;  .   13.       14. .   public SQLCustomQuery(.) throws HibernateException SQLQueryReturnProcessor processor = new SQLQueryReturnProcessor(queryReturns, scalarQueryReturns, factory); cess(); . SQLLoadable entityPersisters = (SQLLo

8、adable) processor.getPersisters().toArray( new SQLLoadable0 ); . for (int i = 0; i < entityPersisters.length; i+) SQLLoadable persister = entityPersistersi; /alias2Persister.put( aliasesi, persister ); /TODO:Does not consider any other tables referenced in the query ArrayHelper.addAll( querySpace

9、s, persister.getQuerySpaces() ); . .       /TODO: Does not consider any other tables referenced in the query     ArrayHelper.addAll( querySpaces, persister.getQuerySpaces() );     其中紅色部分是將 persister 的querySpaces 賦給 sqlQuery 的 querySpaces, 但是 per

10、sister 代表返回結(jié)果集類型對應(yīng)的表,測試用例中是權(quán)限表 SYS_PERM; 因此漏了關(guān)聯(lián)表 (Reference Table),這就是問題所在。 我們看到作者 author Gavin King, Max Andersen 也打了 TODO 注釋: /TODO: Does not consider any other tables referenced in the queryJava代碼 1. /*  2.  * analyze reference table of a specified sql

11、 query  3.  * author Raymond He, Guangzhou China  4.  * Oct 8, 2008  5.  *  6.  */  7. public class SQLQueryReferencesAnalyzer       8.   private stat

12、ic Pattern p = Ppile( "w3," );      9.   private static Map sqlquery2ReferenceTableMapping  = new HashMap();   10.   private static Map tableName2EntityNam

13、eMapping = new HashMap(100);   11.         12.   private static final Log log = LogFactory.getLog( SQLQueryReferencesAnalyzer.class );   13.        &#

14、160;14.   public List analyzeSQL(SessionFactory sessionFactory,String sql)             15.     if(sqlquery2ReferenceTableMapping.containsKey(sql)    16.    

15、0;            17.     List refTables  = (List)sqlquery2ReferenceTableMapping.get(sql);   18.     if(log.isDebugEnabled()   19.      log.debu

16、g("Got ref tables:" + refTables + "rn of SQL: " + sql);   20.      return refTables;   21.    else    22.       

17、60;     23.      if(tableName2EntityNameMapping.size() = 0)   /init it once   24.     initTableName2EntityNameMapping(sessionFactory);    25.      

18、60;   26.                 27.     List refTables = new ArrayList(3);   28.     Matcher m = p.matcher(sql);   29.  &

19、#160;             30.     while(m.find()                    31.      String word  =&#

20、160;m.group();   32.      word = word.toUpperCase();   33.     /check if the word is a table name in sessionFactory   34.         

21、 /cache table for every sessionFactory independently, for multi sessionFactory env.   35.      String key = "SF" + sessionFactory.hashCode() + "_" + w

22、ord;    36.      if(tableName2EntityNameMapping.containsKey( key )    37.        if(log.isDebugEnabled() log.debug("word is table: "+ word);   38.  &#

23、160;     refTables.add( word);   39.              40.         41.                42.  

24、0;   if(log.isDebugEnabled()   43.      log.debug("To cache sqlquery2ReferenceTableMapping, ref tables:" + refTables + "rn of SQL: " + sql);   44.  &#

25、160;    /cache it   45.       sqlquery2ReferenceTableMapping.put(sql, refTables);   46.      return refTables;   47.       48.    /* * analy

26、ze reference table of a specified sql query * author Raymond He, Guangzhou China * Oct 8, 2008 * */public class SQLQueryReferencesAnalyzer private static Pattern p = Ppile( "w3," ); private static Map sqlquery2ReferenceTableMapping = new HashMap(); private static Map tableName2EntityNameMa

27、pping = new HashMap(100); private static final Log log = LogFactory.getLog( SQLQueryReferencesAnalyzer.class ); public List analyzeSQL(SessionFactory sessionFactory,String sql) if(sqlquery2ReferenceTableMapping.containsKey(sql) List refTables = (List)sqlquery2ReferenceTableMapping.get(sql);if(log.is

28、DebugEnabled() log.debug("Got ref tables:" + refTables + "rn of SQL: " + sql); return refTables; else if(tableName2EntityNameMapping.size() = 0) /init it onceinitTableName2EntityNameMapping(sessionFactory); List refTables = new ArrayList(3); Matcher m = p.matcher(sql); while(m.fi

29、nd() String word = m.group(); word = word.toUpperCase();/check if the word is a table name in sessionFactory /cache table for every sessionFactory independently, for multi sessionFactory env. String key = "SF" + sessionFactory.hashCode() + "_" + word; if(tableName2EntityNameMappi

30、ng.containsKey( key ) if(log.isDebugEnabled() log.debug("word is table: "+ word); refTables.add( word); if(log.isDebugEnabled() log.debug("To cache sqlquery2ReferenceTableMapping, ref tables:" + refTables + "rn of SQL: " + sql); /cache it sqlquery2ReferenceTableMapping.

31、put(sql, refTables); return refTables;    2) 調(diào)用reference table分析類,將關(guān)聯(lián)表加入 querySpaces     在 SQLCustomQuery 中 完成 Gavin King  的 TODO 任務(wù)。     Java代碼 1. /2008-10-6,Raymond He fix bug here,old text: Does not consider 

32、;any other tables referenced in the query   2.    /*start: analyze ref tables and add it to querySpaces */  3.    SQLQueryReferencesAnalyzer referencesAnalyzer =

33、0;new SQLQueryReferencesAnalyzer();   4.    List refTables = referencesAnalyzer.analyzeSQL(factory, sql);   5.    for (int k = 0; k < refTables.size(); k+)    6.  

34、;   querySpaces.add(refTables.get(k);   7.       8.    /*end */  /2008-10-6,Raymond He fix bug here,old text: Does not consider any other tables referenced in the query /*start: analyze ref tables and add it to querySpac

35、es */ SQLQueryReferencesAnalyzer referencesAnalyzer = new SQLQueryReferencesAnalyzer(); List refTables = referencesAnalyzer.analyzeSQL(factory, sql); for (int k = 0; k < refTables.size(); k+) querySpaces.add(refTables.get(k); /*end */3. 驗證     還是之前那個測試用例,觀察日志: Execute No. 0 * 2008-

36、10-08 17:32:50,140 DEBUG(AbstractBatcher.java,346) - select  this.PERMCODE as  PERM1_15_0_,  this.MODULECODE as  MODULE2_15_0_,  this.PERMTYPECODE as  PERM3_15_0_,  this.PERMNAME as  PERM4_15_0_,  this.PERMDESC as  PERM5_15_0_,  this.PORTNO as&#

37、160; PORT6_15_0_ from (select  t.perm_code as permCode,        t.module_code as moduleCode,        t.perm_name as permName,        t.perm_desc as permDesc,        t.port_no as

38、 portNo,        t.perm_type_code as permTypeCode   from sys_perm t join sys_role_perm o     on t.perm_code = o.perm_code     where o.role_code = ? ) this  (No.0)result size:1 Execute No. 1 * (No.1)result size:1 2008-10-08 17:32:50

39、,187 DEBUG(AbstractBatcher.java,346) - delete from SYS_ROLE_PERM where PERM_CODE=? and ROLE_CODE=? Execute No. 2 * 2008-10-08 17:32:50,187 DEBUG(AbstractBatcher.java,346) - select  this.PERMCODE as  PERM1_15_0_,  this.MODULECODE as  MODULE2_15_0_,  this.PERMTYPECODE as  PERM

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論