<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                Hibernate二級級緩存 上篇介紹了[Hibernate](http://blog.csdn.net/lovesummerforever/article/details/20997879)[一級緩存](http://blog.csdn.net/lovesummerforever/article/details/20997879),主要是session緩存,session生命周期結束,緩存也就結束。二級緩存相對于一級緩存來說是一個范圍更廣闊一些,就比你住的地方周圍有多個小賣鋪(session緩存),和一個大型超市,原料加工廠送貨的時候送小賣鋪一份的同時,必然送一份到超市。而給第二個小賣鋪送一份的同時,也送給超市一份,這個超市就是我們的SessionFactory。hibernate二緩存的又稱為“SessionFactory的緩存”緩存的生命周期和SessionFactory(線程安全,一個數據庫對應一個,重量級)的生命周期一致,所以SessionFactory可以管理二級緩存。 下面來看session控制的二級緩存。 ### 二級緩存配置 1、需要引入第三方的jar包,hibernate的Cglib.jar。 2、在緩存的配置文件來控制緩存,我們可以拷貝hibernate已有項目中的ehcache.xml配置文件到自己的項目中。通過這個文件,我們可以對二級緩存進行設置,例如緩存的時間,緩存的代銷,緩存間隔多長時間自動被清掉,緩存超時間直接緩存到磁盤指定的位置上等設置。 3、在hibernate.cfg.xml文件中加入緩存產品提供商。 ~~~ <propertyname="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property> ~~~ 4、啟用二級緩存,設置為true,默認是true,添加上有助于我們手動關閉和開啟二級緩存。 ~~~ <propertyname="hibernate.cache.use_second_level_cache">true</property> ~~~ 5、指定哪些實體類使用二級緩存。 方法一:在對應實體的.hbm.xml文件中設置,<cacheusage="read-only"/>這樣如果我們想要知道二百個映射文件哪些使用了二級緩存,就要查看二百個文件,所以我們可以把對實體加入二級緩存的策略放到hibernate.cfg.xml進行配置。也就是方法二。 方法二:處于好管理的目的我們把哪個實體使用二級緩存的配置放到hibernate.cfg.xml文件中。例如執行把student實體加入二級緩存策略。???????<!-- ????????????????????????????????指定Student使用二級緩存 ??????????????????????????--> ~~~ <class-cacheclass="com.bjpowernode.hibernate.Student"usage="read-only"/> ~~~ 注意:緩存策略通常采用read-only和read-write 緩存原則;通常是讀大于寫的數據進行緩存。 ### 開啟二級緩存在兩個session中使用兩次load()進行查詢 代碼如下所示。 ~~~ /** * 開啟二級緩存 * * 在兩個session中發load查詢 */ public voidtestCache1() { Sessionsession = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); Studentstudent = (Student)session.load(Student.class, 1); System.out.println("student.name=" +student.getName()); session.getTransaction().commit(); }catch(Exceptione) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } try { session = HibernateUtils.getSession(); session.beginTransaction(); Studentstudent = (Student)session.load(Student.class, 1); //不會發出查詢語句,因為配置二級緩存,session可以共享二級緩存中的數據 //二級緩存是進程級的緩存 System.out.println("student.name=" +student.getName()); session.getTransaction().commit(); }catch(Exceptione) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } } ~~~ 打印結果如下圖所示。 ![](https://box.kancloud.cn/2016-06-21_576908fa7ec3a.jpg) 由此可知,雖然我們使用的是兩個session,但第二次查詢的時候沒有再向數據庫發出查詢語句。也就是第一次查詢的時候放入session的同時也放入SessionFactory緩存中一份,而第二個session再查詢的時候,就直接從二級緩存中取出就可以了。 ### 開啟二級緩存在兩個session中使用兩次get()進行查詢。 代碼就是把上述代碼load方法改動為get方法。 運行結果如下所示。 ![](https://box.kancloud.cn/2016-06-21_576908fa7ec3a.jpg) 同load一樣,對于sessionFactory級別的緩存,第二次查詢時就不再向數據庫發出查詢sql命令。 ### 開啟二級緩存,在兩個session中發出load查詢,采用SessionFactory管理二級緩存 代碼如下所示。 ~~~ /** * 開啟二級緩存 * * 在兩個session中發load查詢,采用SessionFactory管理二級緩存 */ public voidtestCache3() { Sessionsession = null; try { session= HibernateUtils.getSession(); session.beginTransaction(); Studentstudent = (Student)session.load(Student.class, 1); System.out.println("student.name=" +student.getName()); session.getTransaction().commit(); }catch(Exceptione) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } //管理二級緩存 (evict清除的意思) //HibernateUtils.getSessionFactory().evict(Student.class); HibernateUtils.getSessionFactory().evict(Student.class, 1); try { session= HibernateUtils.getSession(); session.beginTransaction(); Studentstudent = (Student)session.load(Student.class, 1); //會發出查詢語句,因為二級緩存中的數據被清除了 System.out.println("student.name=" +student.getName()); session.getTransaction().commit(); }catch(Exceptione) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } } ~~~ 顯示結果如下所示。 ![](https://box.kancloud.cn/2016-06-21_576908fa981c3.jpg) 根據顯示結果可知,在兩個session中發出load查詢,第一次放入session緩存同時放入了二級緩存sessionFactory中。在第二個session中,首先使用SessionFactory對二級緩存管理,使用evict()方法清除二級緩存,所以第二個session采用load查詢時,需要重新向數據庫發送sql命令。 ### 一級緩存和二級緩存交互 代碼如下所示。 ~~~ public voidtestCache4() { Sessionsession = null; try { session= HibernateUtils.getSession(); session.beginTransaction(); //禁止將一級緩存中的數據放到二級緩存中。緩存模式設置為忽略。 session.setCacheMode(CacheMode.IGNORE); Studentstudent =(Student)session.load(Student.class, 1); System.out.println("student.name=" + student.getName()); session.getTransaction().commit(); }catch(Exceptione) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } try { session= HibernateUtils.getSession(); session.beginTransaction(); Studentstudent = (Student)session.load(Student.class, 1); //會發出查詢語句,因為禁止了一級緩存和二級緩存的交互,一級緩存沒有放到二級緩存中。 System.out.println("student.name=" +student.getName()); session.getTransaction().commit(); }catch(Exceptione) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } } ~~~ ?顯示結果如下所示。 ![](https://box.kancloud.cn/2016-06-21_576908fa981c3.jpg) 從上圖可以看出,首先我們開啟session的事務,然后設置了當寫入session緩存中的同時不寫入二級緩存,session.setCacheMode(CacheMode.IGNORE),這樣第二個session再查詢的時候就不能從二級緩存中找到相應的內容,仍需向數據庫發出sql請求。 ### 大批量數據的添加。 當添加或更新大批量數據的時候,為了防止緩存中數據量過大,我們可以設置刪除session一級緩存,如果此時開啟二級緩存,那么也會同樣再二級緩存中存放一份,這樣的話很可能會導致緩存的溢出,所以對于大數據來說,如果放入了一級緩存中,就應該禁止再放入二級緩存中。 代碼如下所示。 ~~~ /** * 大批量的數據添加 */ public voidtestCache5() { Sessionsession = null; try { session= HibernateUtils.getSession(); session.beginTransaction(); //禁止一級緩存和二級緩存交互 session.setCacheMode(CacheMode.IGNORE); for (int i=0;i<100; i++) { Studentstudent = new Student(); student.setName("張三" +i); //一級緩存放一份,二級緩存也放一份。 session.save(student); //每20條更新一次 if (i %20 == 0) { session.flush(); //清除緩存的內容 //只清除了一級緩存中的內容,沒有清除一級緩存中的內容。如果數據量過大,一樣溢出。 //大于大數據量來說,如果配置了一級緩存的話,就應該禁止再放入二級緩存中。 session.clear(); } } session.getTransaction().commit(); }catch(Exceptione) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } } ~~~ 控制臺打印sql如下圖所示。 ![](https://box.kancloud.cn/2016-06-21_576908fa5c8c0.jpg) ### Hibernate二級緩存總結 從上可知,二級緩存時比一級緩存作用域更大,是在整個應用程序中。一級緩存是不能被卸載的,是必需的,不允許也無法卸載,它是事務范圍的緩存。而二級緩存是可配置的,可卸載的,SessionFactory生命周期和應用程序整個過程對應,就有可能出現并發問題。 什么樣的數據適合放到二級緩存中? 1、很少被修改的數據 2、不是很重要的,并允許出現偶爾的并發數據 3、不會被并發的數據 4、常量數據 什么樣的數據適不合放到二級緩存中? 1、經常被修改的數據。 2、絕對不允許并發的數據。 3、與其他應用共享的數據。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看