成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Hibernate 緩存機制

rickchen / 2131人閱讀

摘要:通過查詢實例調用上面的方法這里就算方法體里面執(zhí)行三個查詢操作,也只會執(zhí)行一條查詢,因為使用的同一個對象,這就有使用到的一級緩存。方法會使用二級緩存,而方法在一級緩存沒有找到的情況下會直接查詢數(shù)據(jù)庫,不會去二級緩存中查找。

一、什么是緩存

緩存是內存中少部分數(shù)據(jù)的復制品,所以CPU到緩存中尋找數(shù)據(jù)時,也會出現(xiàn)找不到的情況(因為這些數(shù)據(jù)沒有從內存復制到緩存中去),這時CPU還是會到內存中去找數(shù)據(jù),這樣系統(tǒng)的速率就慢下來了,不過CPU會把這些數(shù)據(jù)復制到緩存中去,以便下一次不要再到內存中去取。

二、Hibernate的一級緩存

(1)使用
Hibernate的一級緩存是默認開啟的,當獲取到一個Session對象,并執(zhí)行save、update、saveOrUpdate、get方法時就會用到Hibernate一級緩存,當然也可以調用清除的放方法,Session為清除緩存提供了clear(清除所有的一級緩存)、evict(清除實例對象緩存)、refresh(重新查詢數(shù)據(jù)并刷新緩存)。

例子:

//泛型查詢實例
public E find(S s) {
    //使用Spring 獲取一個Session對象
    Session session = getSession();
    //執(zhí)行查詢操作
    E bean = (E)session.get(entityClass, (Serializable) s);
    //清除實例對象緩存
    session.evict(bean);
    //返回查詢的對象
    return bean;
}

(2)狀態(tài)

Hibernate緩存狀態(tài)分為瞬時狀態(tài)、持久狀態(tài)、脫管狀態(tài)。

瞬時狀態(tài): 創(chuàng)建一個POJO,還未將對象數(shù)據(jù)保存到數(shù)據(jù)庫時,Session中也沒有當前POJO實例。

例子:

//創(chuàng)建一個POJO實例
Account account = new Account();
//給實例添加數(shù)據(jù)
account.setPhone("12345678931");
//這時實例并沒有保存

持久狀態(tài): POJO對象被添加到Session緩存中,數(shù)據(jù)庫也要有對應的數(shù)據(jù)。

例子:

public Integer saveStatus(Account entity) {
    //獲取Session對象
    Session session = getSession();
    //執(zhí)行保存方法
    Integer id = (Integer)session.save(entity);
    //修改被持久化的POJO對象
    entity.setState(4);
    //返回對象ID
    return id;
}

在上面的例子中,當保存事務還未提交,這時數(shù)據(jù)已經(jīng)被持久化。這里會執(zhí)行兩條SQL,一條添加SQL,一條修改SQL(并沒有調用修改方法為什么會執(zhí)行修改SQL呢?因為Hibernate被持久化的POJO對象在被重新賦值時會觸發(fā)更新操作。)

脫管狀態(tài): 在緩存中已經(jīng)被持久化的POJO對象,接著POJO對象執(zhí)行了evict方法,這時POJO對象會從緩存中托管,但數(shù)據(jù)庫中是有對應的數(shù)據(jù)。

例子:

public Integer saveStatus(Account entity) {
    //獲取Session對象
    Session session = getSession();
    //執(zhí)行保存方法
    Integer id = (Integer)session.save(entity);
    //脫管當前POJO對象
    session.evict(entity);
    //修改被持久化的POJO對象
    entity.setState(4);
    //返回對象ID
    return id;
}

調用evict方法將POJO對象傳入,清除實例的持久化,修改POJO實例將不會在觸發(fā)更新操作。

(3)緩存綁定

Hibernate的一級緩存是綁定Session的,當獲取到一個Session對象,在執(zhí)行Sessinon里面的方法都能使用Hibernate默認提供的一級緩存,執(zhí)行完成Session對象消亡即緩存數(shù)據(jù)也跟著消亡(一級緩存的數(shù)據(jù)是放在棧中)。

例子:

//通過id查詢POJO實例
public E find(S s) {
    Session session = getSession();
    E bean = (E)session.get(entityClass, (Serializable) s);
    return bean;
}
//調用三次上面的方法
accountService.find(1);
accountService.find(1);
accountService.find(1);

這里會執(zhí)行三條查詢SQL,這是因為里面獲取的Session對象是線程安全的,彼此并沒有任何關聯(lián)(這也是為什么Spring不能用到Hibernate的一級緩存,其實不是Spring的問題)。

//通過id查詢POJO實例
public E find(S s) {
    Session session = getSession();
    E bean  = (E)session.get(entityClass, (Serializable) s);
    E bean1 = (E)session.get(entityClass, (Serializable) s);
    E bean2 = (E)session.get(entityClass, (Serializable) s);
    return bean;
}
//調用上面的方法
accountService.find(1);

這里就算方法體里面執(zhí)行三個查詢操作,也只會執(zhí)行一條查詢SQL,因為使用的同一個Session對象,這就有使用到Hibernate的一級緩存。

二、Hibernate的二級緩存
(1)使用

Hibernate的二級緩存是默認關閉的(二級緩存的數(shù)據(jù)是放在堆中),如果需要開啟二級緩存則需要額外的配置。

(2)配置

第一步:POJO對象設置

@Entity//POJO注解
@Table(name = "account")//對應的數(shù)據(jù)庫表名稱
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)//二級緩存配置,讀寫模式
public class Account {
    ...
}

第二步:配置Hibernate session工廠


    
    
        
            update
            org.hibernate.dialect.MySQLDialect
            true
            true
            true
            true
            org.hibernate.cache.ehcache.EhCacheRegionFactory
            classpath:applicationContext-ehcache.xml
        
    
    
        
            com.test.entity
        
    

第三步:創(chuàng)建二級緩存配置文件



    
    //maxElementsInMemory--緩存對象的最大數(shù)目
    //eternal--對象是否永不過期,設置為true,過期時間則無效
    //timeToldleSeconds--對象空閑多長時間未被使用就失效
    //timeToLiveSeconds--對象被緩存的時間
    //overflowToDisk--內存溢出時是否刷盤,如果為true則需要配置一個刷盤路徑
    //diskExpiryThreadIntervalSeconds--磁盤失效線程運行時間間隔

三、選擇正確的方法

(1) Hibernatne查詢分為兩類:一類是得到單個對象,另一類是得到結果集。

單個對象:

get()方法和load()方法的區(qū)別在于對二級緩存的使用上。load()方法會使用二級緩存,而get()方法在一級緩存沒有找到的情況下會直接查詢數(shù)據(jù)庫,不會去二級緩存中查找。在使用中,對使用了二級緩存的對象進行查詢時最好使用load()方法,以充分利用二級緩存來提高檢索的效率。

結果集對象:

list方法介紹

list()方法在執(zhí)行時,是直接運行查詢結果所需要的查詢語句,而iterator()方法則是先執(zhí)行得到對象ID的查詢,然后再根據(jù)每個ID值去取得所要查詢的對象。因此,對于list()方式的查詢通常只會執(zhí)行一個SQL語句,而對于iterator()方法的查詢則可能需要執(zhí)行N+1條SQL語句(N為結果集中的記錄數(shù))。

list()方法只能使用二級緩存中的查詢緩存,而無法使用二級緩存對單個對象的緩存(但是會把查詢出的對象放入二級緩存中)。所以,除非重復執(zhí)行相同的查詢操作,否則無法利用緩存的機制來提高查詢的效率。

list()方法會一次獲得所有的結果集對象,而且它會依據(jù)查詢的結果初始化所有的結果集對象。這在結果集非常大的時候必然會占據(jù)非常多的內存,甚至會造成內存溢出情況的發(fā)生。

iterator方法介紹

iterator()方法只是可能執(zhí)行N+1條數(shù)據(jù),具體執(zhí)行SQL語句的數(shù)量取決于緩存的情況以及對結果集的訪問情況。

iterator()方法則可以充分利用二級緩存,在根據(jù)ID檢索對象的時候會首先到緩存中查找,只有在找不到的情況下才會執(zhí)行相應的查詢語句。所以,緩存中對象的存在與否會影響到SQL語句的執(zhí)行數(shù)量。

iterator()方法在執(zhí)行時不會一次初始化所有的對象,而是根據(jù)對結果集的訪問情況來初始化對象。因此在訪問中可以控制緩存中對象的數(shù)量,以避免占用過多緩存,導致內存溢出情況的發(fā)生。使用iterator()方法的另外一個好處是,如果只需要結果集中的部分記錄,那么沒有被用到的結果對象根本不會被初始化。所以,對結果集的訪問情況也是調用iterator()方法時執(zhí)行數(shù)據(jù)庫SQL語句多少的一個因素。

部分信息來自網(wǎng)絡,歡迎大家指出錯誤。

文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://systransis.cn/yun/71451.html

相關文章

  • Hibernate 緩存機制

    摘要:通過查詢實例調用上面的方法這里就算方法體里面執(zhí)行三個查詢操作,也只會執(zhí)行一條查詢,因為使用的同一個對象,這就有使用到的一級緩存。方法會使用二級緩存,而方法在一級緩存沒有找到的情況下會直接查詢數(shù)據(jù)庫,不會去二級緩存中查找。 一、什么是緩存 緩存是內存中少部分數(shù)據(jù)的復制品,所以CPU到緩存中尋找數(shù)據(jù)時,也會出現(xiàn)找不到的情況(因為這些數(shù)據(jù)沒有從內存復制到緩存中去),這時CPU還是會到內存中去...

    DevTTL 評論0 收藏0
  • Hibernate最全面試題

    摘要:中怎樣實現(xiàn)類之間的關系如一對多多對多的關系中怎樣實現(xiàn)類之間的關系如一對多多對多的關系它們通過配置文件中的來實現(xiàn)類之間的關聯(lián)關系的。 Hibernate常見面試題 Hibernate工作原理及為什么要用? Hibernate工作原理及為什么要用? 讀取并解析配置文件 讀取并解析映射信息,創(chuàng)建SessionFactory 打開Sesssion 創(chuàng)建事務Transation 持久化操作 提...

    張利勇 評論0 收藏0
  • Hibernate與mybatis比較

    摘要:一級緩存又叫的緩存,是事物范圍的緩存,默認開啟二級緩存又叫的緩存,默認關閉。二級緩存存放數(shù)據(jù)一般是不經(jīng)常修改的數(shù)據(jù),不會被并發(fā)訪問的數(shù)據(jù),常量數(shù)據(jù)訪問數(shù)據(jù)順序是一級緩存二級緩存數(shù)據(jù)庫。 Hibernate與mybatis比較 1、先說底層:   a)Jdbc:全稱java數(shù)據(jù)庫連接,是java語言用來規(guī)范客戶端如何訪問數(shù)據(jù)庫的程序接口。   b) 一般步驟: i.加載驅動程序 ...

    wqj97 評論0 收藏0
  • 初識Hibernate

    摘要:使用反射機制,而不是字節(jié)碼增強程序來實現(xiàn)透明性。工具類初始化失敗為空,請檢查配置文件瞬時對象與持久化對象測試代碼當前在數(shù)據(jù)庫中沒有記錄進行關聯(lián),所以此時是瞬時對象。將持久化當前在數(shù)據(jù)庫有唯一一條記錄對應,所以此時是持久化對象。 showImg(https://segmentfault.com/img/bVbo4at?w=2313&h=642); 一、什么是Hibernate? Hibe...

    tomato 評論0 收藏0
  • 近期Java高級工程師面試總結

    摘要:面試總結最近兩周面試了幾家公司高級工程師的職位,主要有宜信網(wǎng)信金融阿里高德口袋購物。目前有部分公司已經(jīng)面試通過,兩家在等消息。今天趁熱把常見面試內容總結一下。可以用來完成統(tǒng)一命名服務狀態(tài)同步服務集群管理分布式應用配置項等管理工作。 面試總結 最近兩周面試了幾家公司Java高級工程師的職位,主要有宜信、網(wǎng)信金融、阿里高德、口袋購物。目前有部分公司已經(jīng)面試通過,兩家在等消息。今天趁熱把常見...

    raoyi 評論0 收藏0

發(fā)表評論

0條評論

rickchen

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<