本篇內(nèi)容主要講解“Hibernate性能問題怎么解決”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Hibernate性能問題怎么解決”吧!
公司主營業(yè)務(wù):成都網(wǎng)站建設(shè)、網(wǎng)站建設(shè)、移動網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競爭能力。創(chuàng)新互聯(lián)是一支青春激揚、勤奮敬業(yè)、活力青春激揚、勤奮敬業(yè)、活力澎湃、和諧高效的團隊。公司秉承以“開放、自由、嚴謹、自律”為核心的企業(yè)文化,感謝他們對我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團隊有機會用頭腦與智慧不斷的給客戶帶來驚喜。創(chuàng)新互聯(lián)推出當雄免費做網(wǎng)站回饋大家。
在使用Hibernate進行分頁的過程中,如果你收到如下警告,那么這里就是一個潛在的Hibernate性能問題點:
WARNING: firstResult/maxResults specified with collection fetch; applying in memory!
出現(xiàn)這個警告的直接后果是:無論你想要看第幾頁的數(shù)據(jù),從Hibernate打印出的SQL來看它總是查詢了所有滿足條件的結(jié)果。這是為什么呢?來看看這句警告所在的代碼,它位于org.hibernate.hql.ast.QueryTranslatorImpl中,部分摘錄如下:
view plaincopy to clipboardprint?
QueryNode query = ( QueryNode ) sqlAst;
boolean hasLimit = queryParameters.getRowSelection() != null &&
queryParameters.getRowSelection().definesLimits();boolean needsDistincting = ( query.getSelectClause().isDistinct() || hasLimit ) &&
containsCollectionFetches();QueryParameters queryParametersToUse;
if ( hasLimit && containsCollectionFetches() ) {
log.warn( "firstResult/maxResults specified with collection fetch; applying in memory!" )
RowSelection selection = new RowSelection();
selection.setFetchSize( queryParameters.getRowSelection().getFetchSize() );
selection.setTimeout( queryParameters.getRowSelection().getTimeout() );
queryParametersqueryParametersToUse = queryParameters.createCopyUsing( selection );
}
else {
queryParametersqueryParametersToUse = queryParameters;
}
List results = queryLoader.list( session, queryParametersToUse );
QueryNode query = ( QueryNode ) sqlAst;
boolean hasLimit = queryParameters.getRowSelection() != null &&
queryParameters.getRowSelection().definesLimits();boolean needsDistincting = ( query.getSelectClause().isDistinct() || hasLimit ) &&
containsCollectionFetches();QueryParameters queryParametersToUse;
if ( hasLimit && containsCollectionFetches() ) {
log.warn( "firstResult/maxResults specified with collection fetch; applying in memory!" );
RowSelection selection = new RowSelection();
selection.setFetchSize( queryParameters.getRowSelection().getFetchSize() );
selection.setTimeout( queryParameters.getRowSelection().getTimeout() );
queryParametersqueryParametersToUse = queryParameters.createCopyUsing( selection );
}
else {
queryParametersqueryParametersToUse = queryParameters;
}
List results = queryLoader.list( session, queryParametersToUse );
關(guān)鍵在于if ( hasLimit && containsCollectionFetches() 這句判斷,如果滿足了這個條件,RowSelection將會被重新生成,原本分頁需要的firstRow和maxRows屬性將會丟失,后面的數(shù)據(jù)庫分頁自然也無法進行。Hibernate這么做的原因從代碼上也很容易理解,如果查詢需要限制條數(shù)(limit/offset)并且需要fetch結(jié)合對象,則重新生成RowSelection,進一步解釋,就是當一個實體(A)和另一個實體(B)是One-To-Many關(guān)系的時候,一個需要fetch的典型查詢語句是“select distinct a from A a left join fetch a.b”,由于1個A可能對應(yīng)多個B,這個時候數(shù)據(jù)庫查詢的結(jié)果條數(shù)和需要生成的A對象的條數(shù)可能不一致,所以無法利用數(shù)據(jù)庫層的分頁來實現(xiàn),因為你真正想分頁的是A而不是A left join B。出現(xiàn)這個警告就是提醒你這個查詢實際上是查詢了所有滿足條件的數(shù)據(jù),Hibernate是在內(nèi)存中對其進行了假分頁的處理。
這樣,對于查詢結(jié)果比較多的情況無疑是一個Hibernate性能上的潛在威脅。碰到這樣的情況,將Many的查詢進行分開也是一種解決辦法。
到此,相信大家對“Hibernate性能問題怎么解決”有了更深的了解,不妨來實際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學習!