<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>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # Hiberate 二級緩存如何工作? > 原文: [https://howtodoinjava.com/hibernate/how-hibernate-second-level-cache-works/](https://howtodoinjava.com/hibernate/how-hibernate-second-level-cache-works/) 緩存是 ORM 框架提供的功能,可幫助用戶獲得快速運行的 Web 應用,同時幫助框架本身減少在單個事務中對數據庫的查詢數量。 Hibernate 還分兩層提供此緩存功能。 * **一級緩存**:默認情況下啟用,并在會話范圍內工作。 閱讀有關 [**Hiberate 一級緩存**](//howtodoinjava.com/hibernate/understanding-hibernate-first-level-cache-with-example/ "Understanding hibernate first level cache with example")的更多信息。 * **二級緩存**:與一級緩存不同,后者可以在會話工廠范圍內全局使用。 以上聲明意味著,**二級緩存是在會話工廠范圍**中創建的,并且**可用于在使用該特定會話工廠創建的所有會話**中使用。 這也意味著**一旦關閉會話工廠,與之關聯的所有緩存都將失效**,并且緩存管理器也會關閉。 此外,這還意味著,如果您有兩個會話工廠實例(通常沒有應用這樣做),則您的應用中將有兩個緩存管理器,并且在訪問存儲在物理存儲中的緩存時,您可能會得到不可預測的結果,例如緩存缺失。 ![hibernate first and second level cache_example](https://img.kancloud.cn/e1/04/e1046f2aee64f1963e2219b8d6cf5219_493x286.png) Hibernate 一級或二級緩存 在本教程中,我將提供有關 Hiberate 二級緩存的概念,并提供使用代碼段的示例。 ## 二級緩存的工作方式 讓我們逐點寫下所有事實: 1. 每當 Hiberate 會話嘗試加載實體時,它首先會在一級緩存(與特定的 Hiberate 會話關聯)中尋找實體的緩存副本。 2. 如果一級高速緩存中存在實體的高速緩存副本,則將其作為裝入方法的結果返回。 3. 如果第一級高速緩存中沒有高速緩存的實體,則在第二級高速緩存中查找高速緩存的實體。 4. 如果二級緩存已緩存實體,則將其作為裝入方法的結果返回。 但是,在返回實體之前,它也存儲在第一級緩存中,以便對實體的加載方法的下一次調用將從第一級緩存本身返回該實體,而無需再次進入第二級緩存。 5. 如果在一級緩存和二級緩存中均未找到實體,則在作為`load()`方法的響應返回之前,將執行數據庫查詢并將實體存儲在兩個緩存級別中。 6. 如果已通過 Hiberate 會話 API 完成了修改,則二級緩存會針對修改后的實體進行自我驗證。 7. 如果某些用戶或進程直接在數據庫中進行更改,則直到該緩存區域的“`timeToLiveSeconds`”持續時間過去之后,二級緩存才能更新自身。 在這種情況下,最好使整個緩存無效,然后讓 Hiberate 再次構建其緩存。 您可以使用下面的代碼片段使整個 Hiberate 二級緩存無效。 ```java /** * Evicts all second level cache hibernate entites. This is generally only * needed when an external application modifies the databaase. */ public void evict2ndLevelCache() { try { Map<String, ClassMetadata> classesMetadata = sessionFactory.getAllClassMetadata(); for (String entityName : classesMetadata.keySet()) { logger.info("Evicting Entity from 2nd level cache: " + entityName); sessionFactory.evictEntity(entityName); } } catch (Exception e) { logger.logp(Level.SEVERE, "SessionController", "evict2ndLevelCache", "Error evicting 2nd level hibernate cache entities: ", e); } } ``` 為了使用示例了解更多信息,我編寫了一個測試應用,其中將 EhCache 配置為 2 級緩存。 讓我們來看看各種場景: **a)實體是首次獲取的** ```java DepartmentEntity department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1)); System.out.println(department.getName()); System.out.println(HibernateUtil.getSessionFactory().getStatistics().getEntityFetchCount()); //Prints 1 System.out.println(HibernateUtil.getSessionFactory().getStatistics().getSecondLevelCacheHitCount()); //Prints 0 Output: 1 0 ``` ***說明***:實體不在第一級或第二級緩存中,因此從數據庫中獲取了該實體。 **b)第二次獲取實體** ```java //Entity is fecthed very first time DepartmentEntity department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1)); System.out.println(department.getName()); //fetch the department entity again department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1)); System.out.println(department.getName()); System.out.println(HibernateUtil.getSessionFactory().getStatistics().getEntityFetchCount()); //Prints 1 System.out.println(HibernateUtil.getSessionFactory().getStatistics().getSecondLevelCacheHitCount()); //Prints 0 Output: 1 0 ``` ***說明***:實體存在于一級緩存中,因此從那里獲取它。 無需轉到二級緩存。 **c)實體已從一級緩存中逐出并再次獲取** ```java //Entity is fecthed very first time DepartmentEntity department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1)); System.out.println(department.getName()); //fetch the department entity again department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1)); System.out.println(department.getName()); //Evict from first level cache session.evict(department); department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1)); System.out.println(department.getName()); System.out.println(HibernateUtil.getSessionFactory().getStatistics().getEntityFetchCount()); //Prints 1 System.out.println(HibernateUtil.getSessionFactory().getStatistics().getSecondLevelCacheHitCount()); //Prints 1 Output: 1 1 ``` ***說明***:首次從數據庫中獲取實體。 這導致它存儲在第一級和第二級緩存中。 從第一級緩存獲取第二個加載調用。 然后,我們從一級緩存中逐出實體。 因此,第三次`load()`調用轉到第二級緩存,并且`getSecondLevelCacheHitCount()`返回 1。 **d)從另一個會話訪問二級緩存** ```java //Entity is fecthed very first time DepartmentEntity department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1)); System.out.println(department.getName()); //fetch the department entity again department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1)); System.out.println(department.getName()); //Evict from first level cache session.evict(department); department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1)); System.out.println(department.getName()); department = (DepartmentEntity) anotherSession.load(DepartmentEntity.class, new Integer(1)); System.out.println(department.getName()); System.out.println(HibernateUtil.getSessionFactory().getStatistics().getEntityFetchCount()); //Prints 1 System.out.println(HibernateUtil.getSessionFactory().getStatistics().getSecondLevelCacheHitCount()); //Prints 2 Output: 1 2 ``` ***說明***:當從同一會話工廠創建的另一個會話嘗試獲取實體時,將在二級緩存中成功查找該會話,并且不會進行數據庫調用。 因此,現在我們清楚了 hibernate 如何使用二級緩存。 [下載源碼](https://docs.google.com/file/d/0B7yo2HclmjI4cVdNNXFWQmQ1ZTQ/edit?usp=sharing "hibernate second level cache demo source code") 如果有任何疑問或建議,請給我評論。 **祝您學習愉快!**
                  <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>

                              哎呀哎呀视频在线观看