3 回答

TA貢獻(xiàn)1824條經(jīng)驗(yàn) 獲得超8個(gè)贊
HikariCP 實(shí)際上不支持PreparedStatement 緩存
其他人提供 PreparedStatement 緩存。HikariCP 沒有。為什么?
它被認(rèn)為是錯(cuò)誤的實(shí)施
在池層使用語句緩存是一種反模式,與驅(qū)動(dòng)程序提供的緩存相比,會(huì)對(duì)您的應(yīng)用程序性能產(chǎn)生負(fù)面影響。
解釋:
在連接池層 PreparedStatements 只能緩存每個(gè)連接。如果您的應(yīng)用程序有 250 個(gè)經(jīng)常執(zhí)行的查詢和一個(gè)包含 20 個(gè)連接的池,您要求您的數(shù)據(jù)庫保留 5000 個(gè)查詢執(zhí)行計(jì)劃——同樣,池必須緩存這么多 PreparedStatements 及其相關(guān)的對(duì)象圖。
大多數(shù)主要的數(shù)據(jù)庫 JDBC 驅(qū)動(dòng)程序已經(jīng)有一個(gè)可以配置的語句緩存,包括 PostgreSQL、Oracle、Derby、MySQL、DB2 等等。JDBC 驅(qū)動(dòng)程序處于利用數(shù)據(jù)庫特定功能的獨(dú)特位置,幾乎所有緩存實(shí)現(xiàn)都能夠跨連接共享執(zhí)行計(jì)劃。這意味著您的 250 個(gè)經(jīng)常執(zhí)行的查詢會(huì)在數(shù)據(jù)庫中產(chǎn)生恰好 250 個(gè)執(zhí)行計(jì)劃,而不是內(nèi)存中的 5000 個(gè)語句和相關(guān)的執(zhí)行計(jì)劃。聰明的實(shí)現(xiàn)甚至不會(huì)在驅(qū)動(dòng)程序級(jí)別的內(nèi)存中保留 PreparedStatement 對(duì)象,而只是將新實(shí)例附加到現(xiàn)有計(jì)劃 ID。
如果你接受它,你不應(yīng)該嘗試\期望緩存PreparedStatement
如果拒絕,可以使用C3P0作為連接池
關(guān)于hibernate中的二級(jí)緩存,大多沒有在連接池中定義,而是使用相關(guān)的連接提供者:
HikariCP 現(xiàn)在有一個(gè)用于 Hibernate 4.x 的 ConnectionProvider,稱為 HikariConnectionProvider
為了在 Hibernate 4.x 中使用 HikariConnectionProvider,將以下屬性添加到您的 hibernate.properties 配置文件中:
hibernate.connection.provider_class=com.zaxxer.hikari.hibernate.HikariConnectionProvider從 Hibernate 4.3.6 開始,有一個(gè)來自 Hibernate 的官方 ConnectionProvider 類,應(yīng)該使用它來代替 HikariCP 實(shí)現(xiàn)。該類稱為
org.hibernate.hikaricp.internal.HikariCPConnectionProvider

TA貢獻(xiàn)2051條經(jīng)驗(yàn) 獲得超10個(gè)贊
正如 user7294900 所解釋的,HikariCP 不緩存準(zhǔn)備語句。它將此任務(wù)委托給驅(qū)動(dòng)程序。
微軟從 v6.3.0-preview 添加了準(zhǔn)備好的語句緩存
JDBC 驅(qū)動(dòng)程序的準(zhǔn)備語句元數(shù)據(jù)緩存
它可以像這樣激活:
connection.setStatementPoolingCacheSize(10)
connection.setDisableStatementPooling(false)

TA貢獻(xiàn)1777條經(jīng)驗(yàn) 獲得超3個(gè)贊
對(duì)于任何尋找 Oracle JDBC 的人,從鏈接中引用,
盡管 Oracle JDBC 驅(qū)動(dòng)程序在設(shè)計(jì)時(shí)假設(shè)啟用了隱式緩存,但默認(rèn)情況下并未啟用此功能。要在連接上啟用隱式緩存,可以將相應(yīng) OracleConnection 對(duì)象的 implicitCachingEnabled 屬性設(shè)置為 true,并將 statementCacheSize 屬性設(shè)置為正整數(shù)
要在連接池上啟用它,我們需要
connectionPoolObject.setMaxStatements(10);
如果這樣做,將為池中的每個(gè)連接啟用語句緩存
要驗(yàn)證緩存是否已啟用,
if (conn.getImplicitCachingEnabled())
System.out.println("\nimplicit caching enabled");
else
System.out.println("\nimplicit caching disabled");
我們甚至可以在語句級(jí)別進(jìn)行驗(yàn)證,
//Checking the creation state of the prepared statement
int creationState = stmt.creationState();
switch(creationState) {
case 0:
System.out.println("\nCreation state: new");
break;
case 1:
System.out.println("\nCreation state: from the implicit cache");
break;
case 2:
System.out.println("\nCreation state: from the explicit cache");
break;
}
當(dāng)該語句第一次在連接 C1 上執(zhí)行時(shí),情況 1 將為真,如果同一語句在同一連接 C1 上再次執(zhí)行,則情況 2 將為真。
添加回答
舉報(bào)