[英]Do I get a memory leak by not closing my JDBC PreparedStatements?
[英]Why do I need a connection to create PreparedStatements?
出於多種原因 ,我想使用准備好的陳述。 但是,我想創建一個如下所示的方法:
/* This opens a connection, executes the query, and closes the connection */
public static void executeNonQuery(String queryString);
換句話說,我希望我的應用程序邏輯只需要制定查詢和feed參數,但不要處理連接和語句。 但是,PreparedStatements是從連接對象創建的,因此我當前不得不使用String.format()來准備查詢字符串 - 這很丑陋且危險。
有沒有辦法在不使用String.format()的情況下做我想做的事情?
為什么我需要連接來創建PreparedStatements?
因為這些語句是在大多數RDBMS
基於每個連接准備的。
准備好的語句實際上是緩存的執行計划,不會考慮您的權限,編碼,整理設置等。
所有這些都是在查詢解析期間完成的。
有沒有辦法在不使用
String.format()
情況下做我想做的事情
不明白為什么你需要String.format()
。
您可以將查詢實現為類,創建連接並在類構造函數中准備查詢,然后在方法中執行它。
參數化查詢通常如下所示:
SELECT *
FROM table
WHERE col1 = ?
AND col2 = ?
,綁定參數將被替換?
在查詢執行期間。
如果你想要一個static
方法:
static
連接句柄。 key
創建准備好的查詢的static
哈希表,並將准備好的查詢的句柄作為value
。 為什么不讓您的“應用程序”邏輯使用您創建的可以呈現這種接口方法的數據層?
然后,您的數據層可以處理在executeNonQuery
方法中創建連接,准備語句等。
我認為如果你試圖將查詢/語句中的參數自己合並到一個String中,那么你就是在自己的腳下拍攝,而實際上並沒有使用PreparedStatements的參數功能。 不知道你為什么要這樣做。
您可能還希望使用諸如Spring之類的API,它具有一系列JdbcTemplate
類,可以抽象遠離您的所有連接處理,但仍允許您使用Map
參數。
我通過讓我調用QueryRunner的類來抽象出所有JDBC的東西,該類具有一個帶有sql的execute方法,一個表示參數的對象List,以及一個將處理ResultSet的對象。 如果使用JDBC中的setObject方法設置參數,它將根據底層對象確定要使用的相應數據庫類型。 這是我的一部分代碼。 我有另一個方法來包裝這個並獲得連接。
public void executeNoCommit(Connection conn,
String sql,
List params,
ResultSetProcessor processor) throws SQLException {
PreparedStatement stmt = null;
ResultSet rs = null;
int updateCount = 0;
Iterator it;
int paramIndex = 1;
boolean query;
try {
stmt = conn.prepareStatement(sql);
if (params != null) {
it = params.iterator();
while (it.hasNext()) {
stmt.setObject(paramIndex, it.next());
paramIndex++;
}
}
query = stmt.execute();
if (query) {
rs = stmt.getResultSet();
}
else {
updateCount = stmt.getUpdateCount();
}
processor.process(rs, updateCount);
}
finally {
if (rs != null) {
try {
rs.close();
}
catch (SQLException e) {
log.error(e);
}
}
if (stmt != null) {
try {
stmt.close();
}
catch (SQLException e) {
log.error(e);
}
}
}
}
你可能想要像Apache Commons庫中的DbUtils包這樣的東西:[ http://commons.apache.org/dbutils/index.html] [1 ]
QueryRunner類允許您執行sql語句,而無需手動創建PreparedStatements,甚至可以打開連接。 從示例頁面:
QueryRunner run = new QueryRunner( dataSource );
try
{
// Create an object array to hold the values to insert
Object[] insertParams = {"John Doe", new Double( 1.82 )};
// Execute the SQL update statement and return the number of
// inserts that were made
int inserts = run.update( "INSERT INTO Person (name,height) VALUES (?,?)",
insertParams );
// Now it's time to rise to the occation...
Object[] updateParams = {new Double( 2.05 ), "John Doe"};
int updates = run.update( "UPDATE Person SET height=? WHERE name=?",
updateParams );
}
catch(SQLException sqle) {
// Handle it
}
所以它基本上是透明地處理預准備語句的創建,而你真正需要知道的唯一事情是DataSource。 這也適用於非更新/插入語句,即普通選擇查詢,並且創建ResultSetHandlers的功能使您能夠將ResultSet轉換為類似完全准備好的bean或帶有鍵的Map。作為列名,值是實際的行值。 當您無法實現整個ORM解決方案時非常有用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.