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

資訊專欄INFORMATION COLUMN

Hibernate【緩存】知識(shí)要點(diǎn)

AlphaWallet / 1405人閱讀

摘要:對(duì)象狀態(tài)中對(duì)象的狀態(tài)臨時(shí)瞬時(shí)狀態(tài)持久化狀態(tài)游離狀態(tài)學(xué)習(xí)的對(duì)象狀態(tài)是為了更清晰地知道的設(shè)計(jì)思想,以及是一級(jí)緩存的基礎(chǔ)當(dāng)然啦,也就一點(diǎn)點(diǎn)知識(shí)臨時(shí)瞬時(shí)狀態(tài)當(dāng)我們直接出來的對(duì)象就是臨時(shí)瞬時(shí)狀態(tài)的該對(duì)象還沒有被持久化沒有保存在數(shù)據(jù)庫中不受的管理持久化

對(duì)象狀態(tài)

Hibernate中對(duì)象的狀態(tài):

臨時(shí)/瞬時(shí)狀態(tài)

持久化狀態(tài)

游離狀態(tài)

學(xué)習(xí)Hibernate的對(duì)象狀態(tài)是為了更清晰地知道Hibernate的設(shè)計(jì)思想,以及是一級(jí)緩存的基礎(chǔ)...當(dāng)然啦,也就一點(diǎn)點(diǎn)知識(shí)

臨時(shí)/瞬時(shí)狀態(tài)

當(dāng)我們直接new出來的對(duì)象就是臨時(shí)/瞬時(shí)狀態(tài)的..

該對(duì)象還沒有被持久化【沒有保存在數(shù)據(jù)庫中】

不受Session的管理

持久化狀態(tài)

當(dāng)保存在數(shù)據(jù)庫中的對(duì)象就是持久化狀態(tài)了

當(dāng)調(diào)用session的save/saveOrUpdate/get/load/list等方法的時(shí)候,對(duì)象就是持久化狀態(tài)

在數(shù)據(jù)庫有對(duì)應(yīng)的數(shù)據(jù)

受Session的管理

當(dāng)對(duì)對(duì)象屬性進(jìn)行更改的時(shí)候,會(huì)反映到數(shù)據(jù)庫中!

我們來測(cè)試一下:當(dāng)對(duì)對(duì)象屬性進(jìn)行更改的時(shí)候,會(huì)反映到數(shù)據(jù)庫中!

        session.save(idCard);
        idCard.setIdCardName("我是測(cè)試持久化對(duì)象");

游離狀態(tài)

當(dāng)Session關(guān)閉了以后,持久化的對(duì)象就變成了游離狀態(tài)了...

不處于session的管理

數(shù)據(jù)庫中有對(duì)應(yīng)的記錄

一級(jí)緩存

Hibernate有一級(jí)緩存和二級(jí)緩存之分,這里主要講解一級(jí)緩存

什么是一級(jí)緩存?

Hibenate中一級(jí)緩存,也叫做session的緩存,它可以在session范圍內(nèi)減少數(shù)據(jù)庫的訪問次數(shù)! 只在session范圍有效! Session關(guān)閉,一級(jí)緩存失效!

只要是持久化對(duì)象狀態(tài)的,都受Session管理,也就是說,都會(huì)在Session緩存中!

Session的緩存由hibernate維護(hù),用戶不能操作緩存內(nèi)容; 如果想操作緩存內(nèi)容,必須通過hibernate提供的evit/clear方法操作

為什么要是使用緩存?

減少對(duì)數(shù)據(jù)庫的訪問次數(shù)!從而提升hibernate的執(zhí)行效率!

測(cè)試

我們來看一下Hibernate是怎么減少對(duì)數(shù)據(jù)庫訪問的次數(shù)的。

現(xiàn)在我的User表有這么一條記錄:

        //把數(shù)據(jù)放進(jìn)cache
        User user = (User) session.get(User.class, 1);

        //發(fā)現(xiàn)要修改的字段和cache一樣,不執(zhí)行
        user.setUserName("你好2");

取數(shù)據(jù)也是一樣的

        User user = null;
        user = (User) session.get(User.class, 1);
        user = (User) session.get(User.class, 1);

緩存相關(guān)的方法

和緩存有關(guān)常用的方法有三個(gè):

session.flush(); 讓一級(jí)緩存與數(shù)據(jù)庫同步

session.evict(arg0); 清空一級(jí)緩存中指定的對(duì)象

session.clear(); 清空一級(jí)緩存中緩存的所有對(duì)象

clear

        User user = null;
        user = (User) session.get(User.class, 1);

        //清除緩存,那么下面獲取的時(shí)候,就不能從緩存里面拿了
        session.clear();
        user = (User) session.get(User.class, 1);

flush

在有緩存的情況下,修改同一條記錄的數(shù)據(jù),以最后的為準(zhǔn)...因此只有一條update

        User user = null;
        user = (User) session.get(User.class, 1);

        user.setUserName("我是第一");
        user = (User) session.get(User.class, 1);
        user.setUserName("我是第二");

我讓強(qiáng)制讓它和數(shù)據(jù)庫同步的話,就有兩條update了

        User user = null;
        user = (User) session.get(User.class, 1);

        user.setUserName("我是第一");
         session.flush();
        user = (User) session.get(User.class, 1);
        user.setUserName("我是第二");

一般地,我們?cè)?strong>批處理的時(shí)候會(huì)用,因?yàn)?strong>緩存也是有大小的,如果1000條數(shù)據(jù)插入進(jìn)去都要緩存,那么Hibernate可能就崩了...

每隔一定記錄數(shù),先與數(shù)據(jù)庫同步 flush()

再清空緩存 clear()

值得注意的是:不同的Session是不會(huì)共享緩存的!

Iterator與list

我們使用HQL查詢?nèi)繑?shù)據(jù)的時(shí)候,可以使用list()得到所有的數(shù)據(jù),也可以使用iterator()得到一個(gè)迭代器,再遍歷迭代器...那它們有什么區(qū)別呢?

。。。。當(dāng)時(shí)看視頻的時(shí)候說是下圖:

但是我在測(cè)試的時(shí)候:List也可以獲取緩存的數(shù)據(jù)

當(dāng)然啦,Iterator也是可以獲取緩存的數(shù)據(jù)

因此,在獲取數(shù)據(jù)的時(shí)候還是使用list()方便!

懶加載

懶加載就是當(dāng)使用數(shù)據(jù)的時(shí)候才去獲取數(shù)據(jù)、執(zhí)行對(duì)應(yīng)的SQL語句...當(dāng)還沒用到數(shù)據(jù)的時(shí)候,就不加載對(duì)應(yīng)的數(shù)據(jù)!

主要目的就是為了提高Hibernate的性能,提高執(zhí)行效率!

get: 及時(shí)加載,只要調(diào)用get方法立刻向數(shù)據(jù)庫查詢

load:默認(rèn)使用懶加載,當(dāng)用到數(shù)據(jù)的時(shí)候才向數(shù)據(jù)庫查詢。

懶加載再次體驗(yàn)
        User user = (User) session.load(User.class, 1);

        System.out.println("________");
        System.out.println(user);

我們可以在對(duì)應(yīng)的配置文件用通常lazy屬性來設(shè)置

關(guān)閉懶加載:

    

lazy有三個(gè)屬性:

true 使用懶加載

false 關(guān)閉懶加載

extra (在集合數(shù)據(jù)懶加載時(shí)候提升效率)【只有在set、list等集合標(biāo)簽中使用】

在真正使用數(shù)據(jù)的時(shí)候才向數(shù)據(jù)庫發(fā)送查詢的sql;

如果調(diào)用集合的size()/isEmpty()方法,只是統(tǒng)計(jì),不真正查詢數(shù)據(jù)!

懶加載異常

當(dāng)Session關(guān)閉后,就不能使用懶加載了,否則會(huì)報(bào)出異常

Exception in thread "main" org.hibernate.LazyInitializationException: could not initialize proxy - no Session

報(bào)出了這個(gè)異常,我們有4種方法解決:

方式1: 先使用一下數(shù)據(jù)

dept.getDeptName();

方式2:強(qiáng)迫代理對(duì)象初始化

Hibernate.initialize(dept);

方式3:關(guān)閉懶加載

設(shè)置lazy=false;

方式4: 在使用數(shù)據(jù)之后,再關(guān)閉session!

Hibernate二級(jí)緩存

前面我們已經(jīng)講解過了一級(jí)緩存,一級(jí)緩存也就是Session緩存,只在Session的范圍內(nèi)有效...作用時(shí)間就在Session的作用域中,范圍比較小

Hibernate為我們提供了二級(jí)緩存功能:二級(jí)緩存是基于應(yīng)用程序的緩存,所有的Session都可以使用

Hibernate提供的二級(jí)緩存有默認(rèn)的實(shí)現(xiàn),且是一種可插配的緩存框架!如果用戶想用二級(jí)緩存,只需要在hibernate.cfg.xml中配置即可; 不想用,直接移除,不影響代碼。

如果用戶覺得hibernate提供的框架框架不好用,自己可以換其他的緩存框架或自己實(shí)現(xiàn)緩存框架都可以。

Hibernate二級(jí)緩存:存儲(chǔ)的是常用的類

配置二級(jí)緩存

既然二級(jí)緩存是Hibernate自帶的,那么我們可以在hibernate.properties文件中找到對(duì)應(yīng)的信息..

hibernate.cache.use_second_level_cache false【二級(jí)緩存默認(rèn)不開啟,需要手動(dòng)開啟】

hibernate.cache.use_query_cache true 【開啟查詢緩存】

choose a cache implementation 【二級(jí)緩存框架的實(shí)現(xiàn)】

hibernate.cache.provider_class org.hibernate.cache.EhCacheProvider

hibernate.cache.provider_class org.hibernate.cache.EmptyCacheProvider

hibernate.cache.provider_class org.hibernate.cache.HashtableCacheProvider 默認(rèn)實(shí)現(xiàn)

hibernate.cache.provider_class org.hibernate.cache.TreeCacheProvider

hibernate.cache.provider_class org.hibernate.cache.OSCacheProvider

hibernate.cache.provider_class org.hibernate.cache.SwarmCacheProvider

通過配置文件我們可以發(fā)現(xiàn),二級(jí)緩存默認(rèn)是不開啟的,需要我們手動(dòng)開啟,以下步驟:

1)開啟二級(jí)緩存

2)指定緩存框架

3)指定哪些類加入二級(jí)緩存

開啟二級(jí)緩存

在hibernate.cfg.xml文件中開啟二級(jí)緩存

        
        true
指定緩存框架

指定Hibernate自帶的二級(jí)緩存框架就好了

        
        org.hibernate.cache.HashtableCacheProvider
指定哪些類加入二級(jí)緩存
        
        
        

測(cè)試:

我們知道一級(jí)緩存是Session的緩存,那么我們?cè)?strong>測(cè)試二級(jí)緩存的時(shí)候使用兩個(gè)Session來測(cè)試就好了。如果第二個(gè)Session拿到的是緩存數(shù)據(jù),那么就證明二級(jí)緩存是有用的。

package zhongfucheng.aa;

import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;

public class App5 {
    public static void main(String[] args) {


        //獲取加載配置管理類
        Configuration configuration = new Configuration();
        //加載類對(duì)應(yīng)的映射文件!
        configuration.configure().addClass(Animal.class);
        //創(chuàng)建Session工廠對(duì)象
        SessionFactory factory = configuration.buildSessionFactory();
        //得到Session對(duì)象
        Session session1 = factory.openSession();
        //使用Hibernate操作數(shù)據(jù)庫,都要開啟事務(wù),得到事務(wù)對(duì)象
        Transaction transaction = session1.getTransaction();
        //開啟事務(wù)
        transaction.begin();
        Monkey monkey = (Monkey) session1.get(Monkey.class,"40283f815be67f42015be67f43240001" );
        System.out.println(monkey.getName());
        System.out.println("-----------------------");



        Session session2 = factory.openSession();
        Transaction transaction2 = session2.getTransaction();
        transaction2.begin();
        Monkey monkey2 = (Monkey) session1.get(Monkey.class, "40283f815be67f42015be67f43240001");
        System.out.println(monkey2.getName());


        //提交事務(wù)
        transaction.commit();
        transaction2.commit();

        //關(guān)閉Session
        session1.close();
        session2.close();


    }
}

得到的是緩存數(shù)據(jù)!

緩存策略

我們?cè)诎袮nimal類放進(jìn)二級(jí)緩存的時(shí)候,用法為只讀

也就是說,只能讀取,不能寫入,我們來看看寫入會(huì)怎么樣:

  monkey2.setName("小猴子");

拋出了異常....

usage的屬性有4種:

放入二級(jí)緩存的對(duì)象,只讀;

非嚴(yán)格的讀寫

讀寫; 放入二級(jí)緩存的對(duì)象可以讀、寫;

(基于事務(wù)的策略)

集合緩存

如果我們?cè)跀?shù)據(jù)庫查詢的數(shù)據(jù)是集合...Hibernate默認(rèn)是沒有為集合數(shù)據(jù)設(shè)置二級(jí)緩存的...因此還是需要去讀寫數(shù)據(jù)庫的信息

接下來,我們就看看把集合設(shè)置為二級(jí)緩存是什么做的:

在hibernate.cgf.xml中配置對(duì)象中的集合為二級(jí)緩存

        
        

測(cè)試代碼:

    public void testCache() {
        Session session1 = sf.openSession();
        session1.beginTransaction();
        // a. 查詢一次
        Dept dept = (Dept) session1.get(Dept.class, 10);
        dept.getEmps().size();// 集合
        session1.getTransaction().commit();
        session1.close();
        
        System.out.println("------");
        
        // 第二個(gè)session
        Session session2 = sf.openSession();
        session2.beginTransaction();
        // a. 查詢一次
        dept = (Dept) session2.get(Dept.class, 10);  // 二級(jí)緩存配置好; 這里不查詢數(shù)據(jù)庫
        dept.getEmps().size();
        
        session2.getTransaction().commit();
        session2.close();
    }
查詢緩存

list()和iterator()會(huì)把數(shù)據(jù)放在一級(jí)緩存,但一級(jí)緩存只在Session的作用域中有效...如果想要跨Session來使用,就要設(shè)置查詢緩存

我們?cè)谂渲梦募羞€看到了查詢緩存這么一條配置..

    #hibernate.cache.use_query_cache true      【開啟查詢緩存】

也就是說,默認(rèn)的查詢數(shù)據(jù)是不放在二級(jí)緩存中的,如果我們想要把查詢出來的數(shù)據(jù)放到二級(jí)緩存,就需要在配置文件中開啟

        
        true

在使用程序查詢的時(shí)候,也要調(diào)用setCacheable()方法,設(shè)置為查詢緩存。

    @Test
    public void listCache() {
        Session session1 = sf.openSession();
        session1.beginTransaction();
        // HQL查詢  【setCacheable  指定從二級(jí)緩存找,或者是放入二級(jí)緩存】
        Query q = session1.createQuery("from Dept").setCacheable(true);
        System.out.println(q.list());
        session1.getTransaction().commit();
        session1.close();
        
        
        Session session2 = sf.openSession();
        session2.beginTransaction();
        q = session2.createQuery("from Dept").setCacheable(true);
        System.out.println(q.list());  // 不查詢數(shù)據(jù)庫: 需要開啟查詢緩存
        session2.getTransaction().commit();
        session2.close();
    }
如果文章有錯(cuò)的地方歡迎指正,大家互相交流。習(xí)慣在微信看技術(shù)文章,想要獲取更多的Java資源的同學(xué),可以關(guān)注微信公眾號(hào):Java3y

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/68715.html

相關(guān)文章

  • 納稅服務(wù)系統(tǒng)【總結(jié)】

    摘要:要是使用到日歷的話,我們想到使用這個(gè)日歷類上面僅僅是我個(gè)人總結(jié)的要點(diǎn),如果有錯(cuò)誤的地方還請(qǐng)大家給我指正。 納稅服務(wù)系統(tǒng)總結(jié) 納稅服務(wù)系統(tǒng)是我第一個(gè)做得比較大的項(xiàng)目(不同于javaWeb小項(xiàng)目),該項(xiàng)目系統(tǒng)來源于傳智Java32期,十天的視頻課程(想要視頻的同學(xué)關(guān)注我的公眾號(hào)就可以直接獲取了) 我跟著練習(xí)一步一步完成需求,才發(fā)覺原來Java是這樣用來做網(wǎng)站的,Java有那么多的類庫,頁面...

    ispring 評(píng)論0 收藏0
  • Java3y文章目錄導(dǎo)航

    摘要:前言由于寫的文章已經(jīng)是有點(diǎn)多了,為了自己和大家的檢索方便,于是我就做了這么一個(gè)博客導(dǎo)航。 前言 由于寫的文章已經(jīng)是有點(diǎn)多了,為了自己和大家的檢索方便,于是我就做了這么一個(gè)博客導(dǎo)航。 由于更新比較頻繁,因此隔一段時(shí)間才會(huì)更新目錄導(dǎo)航哦~想要獲取最新原創(chuàng)的技術(shù)文章歡迎關(guān)注我的公眾號(hào):Java3y Java3y文章目錄導(dǎo)航 Java基礎(chǔ) 泛型就這么簡單 注解就這么簡單 Druid數(shù)據(jù)庫連接池...

    KevinYan 評(píng)論0 收藏0
  • Hibernate【inverse和cascade屬性】知識(shí)要點(diǎn)

    摘要:屬性屬性表示控制權(quán)是否轉(zhuǎn)移控制權(quán)已轉(zhuǎn)移當(dāng)前一方?jīng)]有控制權(quán)控制權(quán)沒有轉(zhuǎn)移當(dāng)前一方有控制權(quán)屬性,是在維護(hù)關(guān)聯(lián)關(guān)系的時(shí)候起作用的。表的外鍵并沒有數(shù)據(jù)結(jié)論如果設(shè)置控制反轉(zhuǎn)即然后通過部門方維護(hù)關(guān)聯(lián)關(guān)系。 Inverse屬性 Inverse屬性:表示控制權(quán)是否轉(zhuǎn)移.. true:控制權(quán)已轉(zhuǎn)移【當(dāng)前一方?jīng)]有控制權(quán)】 false:控制權(quán)沒有轉(zhuǎn)移【當(dāng)前一方有控制權(quán)】 Inverse屬性,是在維護(hù)關(guān)聯(lián)...

    abson 評(píng)論0 收藏0
  • Mybatis【逆向工程,緩存,代理】知識(shí)要點(diǎn)

    摘要:一級(jí)緩存值得注意的地方默認(rèn)就是支持一級(jí)緩存的,并不需要我們配置和整合后進(jìn)行代理開發(fā),不支持一級(jí)緩存,和整合,按照的模板去生成代理對(duì)象,模板中在最后統(tǒng)一關(guān)閉??偨Y(jié)的一級(jí)緩存是級(jí)別的。 前言 本文主要講解Mybatis的以下知識(shí)點(diǎn): Mybatis緩存 一級(jí)緩存 二級(jí)緩存 與Ehcache整合 Mapper代理 使用Mapper代理就不用寫實(shí)現(xiàn)類了 逆向工程 自動(dòng)生成代碼 ...

    wanglu1209 評(píng)論0 收藏0
  • Hibernate【映射】知識(shí)要點(diǎn)

    摘要:前言前面的我們使用的是一個(gè)表的操作,但我們實(shí)際的開發(fā)中不可能只使用一個(gè)表的因此,本博文主要講解關(guān)聯(lián)映射集合映射需求分析當(dāng)用戶購買商品,用戶可能有多個(gè)地址。數(shù)據(jù)庫表我們一般如下圖一樣設(shè)計(jì)數(shù)據(jù)庫表,一般我們不會(huì)在表設(shè)計(jì)多個(gè)列來保存地址的。 前言 前面的我們使用的是一個(gè)表的操作,但我們實(shí)際的開發(fā)中不可能只使用一個(gè)表的...因此,本博文主要講解關(guān)聯(lián)映射 集合映射 需求分析:當(dāng)用戶購買商品,用戶...

    TesterHome 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<