日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

hibernate查询缓存_Hibernate查询缓存如何工作

發(fā)布時(shí)間:2023/12/3 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hibernate查询缓存_Hibernate查询缓存如何工作 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

hibernate查詢緩存

介紹

現(xiàn)在,我已經(jīng)介紹了實(shí)體和集合緩存,現(xiàn)在該研究查詢緩存的工作原理了。

查詢緩存與實(shí)體嚴(yán)格相關(guān),它在搜索條件和滿足該特定查詢過濾器的實(shí)體之間繪制關(guān)聯(lián)。 像其他Hibernate功能一樣,查詢緩存也不像人們想象的那么瑣碎。

實(shí)體模型

對(duì)于我們的測(cè)試用例,我們將使用以下域模型:

Post實(shí)體與Author 具有多對(duì)一關(guān)聯(lián),并且兩個(gè)實(shí)體都存儲(chǔ)在第二級(jí)緩存中。

啟用查詢緩存

默認(rèn)情況下,查詢緩存處于禁用狀態(tài),要激活它,我們需要提供以下Hibernate屬性:

properties.put("hibernate.cache.use_query_cache", Boolean.TRUE.toString());

為了使Hibernate緩存給定的查詢結(jié)果,我們需要在創(chuàng)建Query時(shí)顯式設(shè)置cachable查詢屬性 。

直讀緩存

查詢緩存是只讀的 ,就像NONSTRICT_READ_WRITE并發(fā)策略一樣 ,它只能使過時(shí)的條目無效。

在下一個(gè)示例中,我們將緩存以下查詢:

private List<Post> getLatestPosts(Session session) {return (List<Post>) session.createQuery("select p " +"from Post p " +"order by p.createdOn desc").setMaxResults(10).setCacheable(true).list(); }

首先,我們將使用以下測(cè)試案例來研究查詢緩存的內(nèi)部結(jié)構(gòu):

doInTransaction(session -> {LOGGER.info("Evict regions and run query");session.getSessionFactory().getCache().evictAllRegions();assertEquals(1, getLatestPosts(session).size()); });doInTransaction(session -> {LOGGER.info("Check get entity is cached");Post post = (Post) session.get(Post.class, 1L); });doInTransaction(session -> {LOGGER.info("Check query result is cached");assertEquals(1, getLatestPosts(session).size()); });

該測(cè)試生成以下輸出:

QueryCacheTest - Evict regions and run queryStandardQueryCache - Checking cached query results in region: org.hibernate.cache.internal.StandardQueryCache EhcacheGeneralDataRegion - Element for key sql: selectquerycache0_.id as id1_1_,querycache0_.author_id as author_i4_1_,querycache0_.created_on as created_2_1_,querycache0_.name as name3_1_ fromPost querycache0_ order byquerycache0_.created_on desc;parameters: ; named parameters: {}; max rows: 10; transformer: org.hibernate.transform.CacheableResultTransformer@110f2 is null StandardQueryCache - Query results were not found in cacheselectquerycache0_.id as id1_1_,querycache0_.author_id as author_i4_1_,querycache0_.created_on as created_2_1_,querycache0_.name as name3_1_ fromPost querycache0_ order byquerycache0_.created_on desc limit 10StandardQueryCache - Caching query results in region: org.hibernate.cache.internal.StandardQueryCache; timestamp=5872026465492992 EhcacheGeneralDataRegion - key: sql: selectquerycache0_.id as id1_1_,querycache0_.author_id as author_i4_1_,querycache0_.created_on as created_2_1_,querycache0_.name as name3_1_ fromPost querycache0_ order byquerycache0_.created_on desc;parameters: ; named parameters: {}; max rows: 10; transformer: org.hibernate.transform.CacheableResultTransformer@110f2 value: [5872026465492992, 1]JdbcTransaction - committed JDBC Connection------------------------------------------------------------QueryCacheTest - Check get entity is cachedJdbcTransaction - committed JDBC Connection------------------------------------------------------------QueryCacheTest - Check query is cachedStandardQueryCache - Checking cached query results in region: org.hibernate.cache.internal.StandardQueryCache StandardQueryCache - Checking query spaces are up-to-date: [Post]EhcacheGeneralDataRegion - key: Post UpdateTimestampsCache - [Post] last update timestamp: 5872026465406976, result set timestamp: 5872026465492992 StandardQueryCache - Returning cached query resultsJdbcTransaction - committed JDBC Connection
  • 清除所有緩存區(qū)域,以確保緩存為空
  • 運(yùn)行后查詢后,查詢緩存將檢查以前存儲(chǔ)的結(jié)果
  • 因?yàn)闆]有緩存條目,所以查詢轉(zhuǎn)到數(shù)據(jù)庫(kù)
  • 所選實(shí)體和查詢結(jié)果均被緩存
  • 然后,我們驗(yàn)證Post實(shí)體是否存儲(chǔ)在二級(jí)緩存中
  • 后續(xù)查詢請(qǐng)求將從緩存中解決,而無需訪問數(shù)據(jù)庫(kù)

查詢參數(shù)

查詢參數(shù)嵌入在緩存條目鍵中,如以下示例所示。

基本類型

首先,我們將使用基本的類型過濾:

private List<Post> getLatestPostsByAuthorId(Session session) {return (List<Post>) session.createQuery("select p " +"from Post p " +"join p.author a " +"where a.id = :authorId " +"order by p.createdOn desc").setParameter("authorId", 1L).setMaxResults(10).setCacheable(true).list(); }doInTransaction(session -> {LOGGER.info("Query cache with basic type parameter");List<Post> posts = getLatestPostsByAuthorId(session);assertEquals(1, posts.size()); });

查詢緩存條目如下所示:

EhcacheGeneralDataRegion - key: sql: selectquerycache0_.id as id1_1_,querycache0_.author_id as author_i4_1_,querycache0_.created_on as created_2_1_,querycache0_.name as name3_1_ fromPost querycache0_ inner joinAuthor querycache1_ on querycache0_.author_id=querycache1_.id wherequerycache1_.id=? order byquerycache0_.created_on desc;parameters: ; named parameters: {authorId=1}; max rows: 10; transformer: org.hibernate.transform.CacheableResultTransformer@110f2 value: [5871781092679680, 1]

該參數(shù)存儲(chǔ)在高速緩存條目鍵中。 緩存條目值的第一個(gè)元素始終是結(jié)果集的獲取時(shí)間戳。 以下元素是此查詢返回的實(shí)體標(biāo)識(shí)符。

實(shí)體類型

我們還可以使用實(shí)體類型作為查詢參數(shù):

private List<Post> getLatestPostsByAuthor(Session session) {Author author = (Author) session.get(Author.class, 1L);return (List<Post>) session.createQuery("select p " +"from Post p " +"join p.author a " +"where a = :author " +"order by p.createdOn desc").setParameter("author", author).setMaxResults(10).setCacheable(true).list(); }doInTransaction(session -> {LOGGER.info("Query cache with entity type parameter");List<Post> posts = getLatestPostsByAuthor(session);assertEquals(1, posts.size()); });

緩存條目與我們之前的示例相似,因?yàn)镠ibernate僅將實(shí)體標(biāo)識(shí)符存儲(chǔ)在緩存條目鍵中。 這很有意義,因?yàn)镠ibernate已經(jīng)緩存了Author實(shí)體。

EhcacheGeneralDataRegion - key: sql: selectquerycache0_.id as id1_1_,querycache0_.author_id as author_i4_1_,querycache0_.created_on as created_2_1_,querycache0_.name as name3_1_ fromPost querycache0_ inner joinAuthor querycache1_ on querycache0_.author_id=querycache1_.id wherequerycache1_.id=? order byquerycache0_.created_on desc;parameters: ; named parameters: {author=1}; max rows: 10; transformer: org.hibernate.transform.CacheableResultTransformer@110f2 value: [5871781092777984, 1]

一致性

HQL / JPQL查詢無效

Hibernate二級(jí)緩存偏向于強(qiáng)一致性,而查詢緩存也不例外。 與刷新一樣,只要關(guān)聯(lián)的表空間發(fā)生更改,查詢緩存就可以使其條目無效。 每次我們持久/刪除/更新實(shí)體時(shí) ,使用該特定表的所有查詢緩存條目都將失效。

doInTransaction(session -> {Author author = (Author) session.get(Author.class, 1L);assertEquals(1, getLatestPosts(session).size());LOGGER.info("Insert a new Post");Post newPost = new Post("Hibernate Book", author);session.persist(newPost);session.flush();LOGGER.info("Query cache is invalidated");assertEquals(2, getLatestPosts(session).size()); });doInTransaction(session -> {LOGGER.info("Check Query cache");assertEquals(2, getLatestPosts(session).size()); });

該測(cè)試將添加一個(gè)新的Post ,然后重新運(yùn)行可緩存的查詢。 運(yùn)行此測(cè)試將給出以下輸出:

QueryCacheTest - Insert a new Postinsert intoPost(id, author_id, created_on, name) values(default, 1, '2015-06-06 17:29:59.909', 'Hibernate Book')UpdateTimestampsCache - Pre-invalidating space [Post], timestamp: 5872029941395456 EhcacheGeneralDataRegion - key: Post value: 5872029941395456QueryCacheTest - Query cache is invalidated StandardQueryCache - Checking cached query results in region: org.hibernate.cache.internal.StandardQueryCache EhcacheGeneralDataRegion - key: sql: selectquerycache0_.id as id1_1_,querycache0_.author_id as author_i4_1_,querycache0_.created_on as created_2_1_,querycache0_.name as name3_1_ fromPost querycache0_ order byquerycache0_.created_on desc;parameters: ; named parameters: {}; max rows: 10; transformer: org.hibernate.transform.CacheableResultTransformer@110f2StandardQueryCache - Checking query spaces are up-to-date: [Post] EhcacheGeneralDataRegion - key: Post UpdateTimestampsCache - [Post] last update timestamp: 5872029941395456, result set timestamp: 5872029695619072 StandardQueryCache - Cached query results were not up-to-dateselectquerycache0_.id as id1_1_,querycache0_.author_id as author_i4_1_,querycache0_.created_on as created_2_1_,querycache0_.name as name3_1_ fromPost querycache0_ order byquerycache0_.created_on desc limit 10StandardQueryCache - Caching query results in region: org.hibernate.cache.internal.StandardQueryCache; timestamp=5872029695668224 EhcacheGeneralDataRegion - key: sql: selectquerycache0_.id as id1_1_,querycache0_.author_id as author_i4_1_,querycache0_.created_on as created_2_1_,querycache0_.name as name3_1_ fromPost querycache0_ order byquerycache0_.created_on desc;parameters: ; named parameters: {}; max rows: 10; transformer: org.hibernate.transform.CacheableResultTransformer@110f2 value: [5872029695668224, 2, 1]JdbcTransaction - committed JDBC ConnectionUpdateTimestampsCache - Invalidating space [Post], timestamp: 5872029695680512 EhcacheGeneralDataRegion - key: Post value: 5872029695680512------------------------------------------------------------QueryCacheTest - Check Query cacheStandardQueryCache - Checking cached query results in region: org.hibernate.cache.internal.StandardQueryCache EhcacheGeneralDataRegion - key: sql: selectquerycache0_.id as id1_1_,querycache0_.author_id as author_i4_1_,querycache0_.created_on as created_2_1_,querycache0_.name as name3_1_ fromPost querycache0_ order byquerycache0_.created_on desc;parameters: ; named parameters: {}; max rows: 10; transformer: org.hibernate.transform.CacheableResultTransformer@110f2StandardQueryCache - Checking query spaces are up-to-date: [Post] EhcacheGeneralDataRegion - key: Post UpdateTimestampsCache - [Post] last update timestamp: 5872029695680512, result set timestamp: 5872029695668224 StandardQueryCache - Cached query results were not up-to-dateselectquerycache0_.id as id1_1_,querycache0_.author_id as author_i4_1_,querycache0_.created_on as created_2_1_,querycache0_.name as name3_1_ fromPost querycache0_ order byquerycache0_.created_on desc limit 10StandardQueryCache - Caching query results in region: org.hibernate.cache.internal.StandardQueryCache; timestamp=5872029695705088 EhcacheGeneralDataRegion - key: sql: selectquerycache0_.id as id1_1_,querycache0_.author_id as author_i4_1_,querycache0_.created_on as created_2_1_,querycache0_.name as name3_1_ fromPost querycache0_ order byquerycache0_.created_on desc;parameters: ; named parameters: {}; max rows: 10; transformer: org.hibernate.transform.CacheableResultTransformer@110f2 value: [5872029695705088, 2, 1]JdbcTransaction - committed JDBC Connection
  • 一旦Hibernate檢測(cè)到Entity狀態(tài)轉(zhuǎn)換 ,它就會(huì)使受影響的查詢緩存區(qū)域預(yù)先失效
  • 不會(huì)刪除查詢緩存條目,但會(huì)更新其關(guān)聯(lián)的時(shí)間戳
  • 查詢緩存始終檢查條目鍵時(shí)間戳,如果鍵時(shí)間戳比結(jié)果集加載時(shí)間戳新,則它會(huì)跳過讀取其值。
  • 如果當(dāng)前會(huì)話重新運(yùn)行此查詢,則結(jié)果將再次被緩存
  • 當(dāng)前數(shù)據(jù)庫(kù)事務(wù)的提交和更改從會(huì)話級(jí)隔離傳播到常規(guī)讀取一致性
  • 發(fā)生實(shí)際的無效,并且緩存條目時(shí)間戳再次被更新

這種方法可能破壞READ COMMITTED一致性保證,因?yàn)榭赡苓M(jìn)行臟讀 ,因?yàn)樵谔峤粩?shù)據(jù)庫(kù)事務(wù)之前,當(dāng)前隔離的更改會(huì)傳播到Cache。

本機(jī)查詢無效

正如我前面提到 ,本機(jī)查詢Hibernate留在黑暗中,因?yàn)樗梢圆恢辣镜夭樵冏罱K可能會(huì)修改其表。 在以下測(cè)試中,我們將更新Author表,同時(shí)檢查它對(duì)當(dāng)前Post Query Cache的影響:

doInTransaction(session -> {assertEquals(1, getLatestPosts(session).size());LOGGER.info("Execute native query");assertEquals(1, session.createSQLQuery("update Author set name = '\"'||name||'\"' ").executeUpdate());LOGGER.info("Check query cache is invalidated");assertEquals(1, getLatestPosts(session).size()); });

測(cè)試生成以下輸出:

QueryCacheTest - Execute native queryUpdateTimestampsCache - Pre-invalidating space [Author], timestamp: 5872035446091776 EhcacheGeneralDataRegion - key: Author value: 5872035446091776 UpdateTimestampsCache - Pre-invalidating space [Post], timestamp: 5872035446091776 EhcacheGeneralDataRegion - key: Post value: 5872035446091776updateAuthor setname = '"'||name||'"'QueryCacheTest - Check query cache is invalidatedStandardQueryCache - Checking cached query results in region: org.hibernate.cache.internal.StandardQueryCache EhcacheGeneralDataRegion - key: sql: selectquerycache0_.id as id1_1_,querycache0_.author_id as author_i4_1_,querycache0_.created_on as created_2_1_,querycache0_.name as name3_1_ fromPost querycache0_ order byquerycache0_.created_on desc;parameters: ; named parameters: {}; max rows: 10; transformer: org.hibernate.transform.CacheableResultTransformer@110f2StandardQueryCache - Checking query spaces are up-to-date: [Post] EhcacheGeneralDataRegion - key: Post UpdateTimestampsCache - [Post] last update timestamp: 5872035446091776, result set timestamp: 5872035200290816 StandardQueryCache - Cached query results were not up-to-dateselectquerycache0_.id as id1_1_,querycache0_.author_id as author_i4_1_,querycache0_.created_on as created_2_1_,querycache0_.name as name3_1_ fromPost querycache0_ order byquerycache0_.created_on desc limit 10StandardQueryCache - Caching query results in region: org.hibernate.cache.internal.StandardQueryCache; timestamp=5872035200364544 EhcacheGeneralDataRegion - key: sql: selectquerycache0_.id as id1_1_,querycache0_.author_id as author_i4_1_,querycache0_.created_on as created_2_1_,querycache0_.name as name3_1_ fromPost querycache0_ order byquerycache0_.created_on desc;parameters: ; named parameters: {}; max rows: 10; transformer: org.hibernate.transform.CacheableResultTransformer@110f2 value: [5872035200364544, 1]JdbcTransaction - committed JDBC ConnectionUpdateTimestampsCache - Invalidating space [Post], timestamp: 5872035200372736 EhcacheGeneralDataRegion - key: Post value: 5872035200372736 UpdateTimestampsCache - Invalidating space [Author], timestamp: 5872035200372736 EhcacheGeneralDataRegion - key: Author value: 5872035200372736

即使僅修改了Author表, Author和Post緩存區(qū)域也都無效。 為了解決這個(gè)問題,我們需要讓Hibernate知道我們要更改哪些表。

本機(jī)查詢緩存區(qū)域同步

Hibernate允許我們通過查詢同步提示來定義查詢表空間。 提供此信息時(shí),Hibernate可以使請(qǐng)求的緩存區(qū)域無效:

doInTransaction(session -> {assertEquals(1, getLatestPosts(session).size());LOGGER.info("Execute native query with synchronization");assertEquals(1, session.createSQLQuery("update Author set name = '\"'||name||'\"' ").addSynchronizedEntityClass(Author.class).executeUpdate());LOGGER.info("Check query cache is not invalidated");assertEquals(1, getLatestPosts(session).size()); });

正在生成以下輸出:

QueryCacheTest - Execute native query with synchronizationUpdateTimestampsCache - Pre-invalidating space [Author], timestamp: 5872036893995008 EhcacheGeneralDataRegion - key: Author value: 5872036893995008updateAuthor setname = '"'||name||'"'QueryCacheTest - Check query cache is not invalidatedStandardQueryCache - Checking cached query results in region: org.hibernate.cache.internal.StandardQueryCache EhcacheGeneralDataRegion - key: sql: selectquerycache0_.id as id1_1_,querycache0_.author_id as author_i4_1_,querycache0_.created_on as created_2_1_,querycache0_.name as name3_1_ fromPost querycache0_ order byquerycache0_.created_on desc;parameters: ; named parameters: {}; max rows: 10; transformer: org.hibernate.transform.CacheableResultTransformer@110f2StandardQueryCache - Checking query spaces are up-to-date: [Post] EhcacheGeneralDataRegion - key: Post UpdateTimestampsCache - [Post] last update timestamp: 5872036648169472, result set timestamp: 5872036648226816 StandardQueryCache - Returning cached query resultsJdbcTransaction - committed JDBC ConnectionUpdateTimestampsCache - Invalidating space [Author], timestamp: 5872036648263680 EhcacheGeneralDataRegion - key: Author value: 5872036648263680

只有提供的表空間無效,離開了郵政查詢緩存不變。 可以將本機(jī)查詢和查詢緩存混合使用,但是需要一些努力。

結(jié)論

查詢緩存可以提高頻繁執(zhí)行的實(shí)體查詢的應(yīng)用程序性能,但這不是免費(fèi)的。 它容易受到一致性問題的影響,并且如果沒有適當(dāng)?shù)膬?nèi)存管理控制機(jī)制,它很容易變得很大。

代碼可在GitHub上獲得 。

翻譯自: https://www.javacodegeeks.com/2015/06/how-does-hibernate-query-cache-work.html

hibernate查詢緩存

總結(jié)

以上是生活随笔為你收集整理的hibernate查询缓存_Hibernate查询缓存如何工作的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。