[英]What is the correct way to use of isWrapperFor and unwrap functions in JDBC?
我想知道驗證isWrapperFor
和在JDBC中解包函數的正確方法。 這里使用HIRAConnection
和標准的Connection
類。
HIRAConnection hiraCon1 = (HIRAConnection) ds.getConnection();
Connection conn = ds.getConnection();
if (hiraCon1 instanceof Wrapper) {
// try to use java 6 unwrapping
try {
Wrapper w = conn;
if (hiraCon1.isWrapperFor(Connection.class)) {
hiraCon1 = conn.unwrap(HIRAConnection.class);
hiraCon1= hiraCon1.unwrap(HIRAConnection.class);
hiraCon1= ds.unwrap(HIRAConnection.class);//returns SQLException
}
if (hiraCon1.isWrapperFor(HIRAConnection.class)) {
hiraCon1 = conn.unwrap(HIRAConnection.class);
hiraCon1 = hiraCon1.unwrap(HIRAConnection.class);
}
if (conn.isWrapperFor(com.hira.HIRAConnection.class)) {
hiraCon1 = conn.unwrap(com.hira.HIRAConnection.class);
}
if (conn.isWrapperFor(Connection.class)) {
hiraCon1 = conn.unwrap(com.hira.HIRAConnection.class);
}
} catch (Throwable t) {
System.out.println("Failed to unwrap connection using java 6 facilities");
}
}
在其javadoc中記錄了使用java.sql.Wrapper
的正確方法。
對於isWrapperFor(Class<?> iface)
:
如果此方法實現了接口參數,或者直接或間接地對該對象進行了包裝,則返回true。 否則返回false。 如果這實現了接口,則返回true,否則返回true,否則返回包裝對象上遞歸調用
isWrapperFor
的結果。 如果這沒有實現接口並且不是包裝器,則返回false。 與unwrap
相比,此方法應作為一種低成本操作來實現,以便調用者可以使用此方法來避免可能失敗的昂貴的unwrap
調用。 如果此方法返回true,則使用相同參數調用unwrap
應該會成功。參數 :
iface
定義接口的類。
返回值 :
如果這實現了接口或直接或間接包裝了這樣做的對象,則為true。
返回一個實現給定接口的對象,以允許訪問非標准方法或代理未公開的標准方法。 如果接收方實現了接口,那么結果就是接收方或該接收方的代理。 如果接收方是包裝器,並且包裝對象實現接口,則結果是包裝對象或包裝對象的代理。 否則,返回調用的結果
unwrap
的包裝對象或該結果的代理遞歸。 如果接收方不是包裝器,並且未實現該接口,則將引發SQLException
。類型參數 :
T
此Class對象建模的類的類型
參數 :
iface
定義結果必須實現的接口的類。
返回值 :
實現接口的對象。 可能是實際實現對象的代理。
拋出 :
SQLException
如果未找到實現該接口的對象
換句話說,您可以先使用wrapperFor
檢查包裝程序是否可以解包到接口,然后可以使用unwrap
真正解包到該接口。 請注意,該規范僅提及支持對接口進行拆包,因此實際上可能無法對具體類進行拆包。
是否起作用,取決於所使用的驅動程序(並非所有驅動程序都支持解包,或者可能沒有對解包有用的東西),如果您使用的是連接池庫,則很可能不允許您解包。 -例如-基礎連接,因為這樣做可以使您規避或打破連接池的某些限制和要求。
因此,使用包裝的正確方法是:
Connection conn = ds.getConnection();
if (conn.isWrapperFor(HiraConnection.class)) {
HIRAConnection hiraCon1 = conn.unwrap(HiraConnection.class);
// use hiraCon1...
)
但是,如果HiraConnection
是一個具體的類而不是一個接口,則可能不起作用。 而且展開通常也會導致代碼變脆。 除非絕對必要,否則通常最好避免依賴於特定於驅動程序的接口。
有關您問題中代碼的一些說明:
HIRAConnection hiraCon1 = (HIRAConnection) ds.getConnection();
有效,那么您根本不需要拆包。 hiraCon1 instanceof Wrapper
是沒有用的檢查,因為如果HIRAConnection
實現java.sql.Connection
,那么它將始終實現java.sql.Wrapper
(否則,運行代碼將為java.sql.Wrapper
產生ClassNotFoundException
,這意味着您可以運行它在Java 5或更低版本上)。 hiraCon1.isWrapperFor(Connection.class)
,然后將conn
展開為HIRAConnection
是不安全的,沒有任何意義。 如果要將conn
HIRAConnection
為HIRAConnection
,則需要使用conn.isWrapperFor(HiraConnection.class)
hiraCon1= ds.unwrap(HIRAConnection.class);
, hiraCon1= ds.unwrap(HIRAConnection.class);
引發SQLException
: javax.sql.DataSource
實現不太可能將自己視為連接的包裝。 hiraCon1.isWrapperFor(HIRAConnection.class)
有點奇怪:您已經知道hiraCon1
是 HIRAConnection
hiraCon1
之后hiraCon1
conn
沒有意義。 conn.isWrapperFor(Connection.class)
有點奇怪:您已經知道conn
是一個Connection
conn.isWrapperFor(Connection.class)
然后使用conn.unwrap(com.hira.HIRAConnection.class)
是不安全的,因為您僅檢查了conn
是否解包到Connection
而不是HIRAConnection
。 除了下面的@MarkRotteveel指出的以外,它們不是真正供應用程序使用的。 JDBC驅動程序作者(例如Apache DBCP)更多地使用它們。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.