2017-02-01 81 views
4

我正在研究一個繼承的大型Java代碼庫,其中許多不同的方法以瘋狂不同的方式對數據庫進行查詢;因爲我一直在調試,規範一切,最讓我寫的代碼最終看起來像這樣:從實用程序方法返回PreparedStatement是否是一種好習慣?

log.info("Audit-required logging for query: "+SOME_QUERY); 
log.info("Ditto for each argument: "+parameter+" "+otherParameter+ ...); 
ps = conn.prepareStatement(SOME_QUERY); 
ps.setString(1, aString); 
ps.setString(2, anotherString); 
// ... 
ps.setString(14, yetAnotherString); 
rs = ps.executeQuery(); 
log.debug("Query executed: "+SOME_QUERY); 

我恨我不得不三次寫下的查詢和參數兩次(加做了setString( )爲每一個) - 這是維護時將來的錯誤的食譜。我寧願把所有這些都放在一個(靜態的)通用目的方法中,這個方法可以讓我只說一次所有內容(加上面向未來的代碼庫,以防需要其他一些操作......例如,不同的法律部門要求進行某種記錄或者要求提供新的錯誤處理)。事情是這樣的:

public static PreparedStatement fullyPrepare(final Connection conn, final String query, final String... arguments) { ... } 

,我會再與單句(每次而不是整個代碼塊)稱:

ps = fullyPrepare(conn, CONSTANT_FOR_THIS_QUERY, parameter, otherParameter, ...); 

我,但是,發現耐此,基於「這將是不好的做法」的想法。我一直在嘗試閱讀這些內容,但是我找不到任何說明從PreparedStatement中準備PreparedStatement的方法是好的還是不好的做法(與處理ResultSet對象相反,如線程Is it Ok to Pass ResultSet?)。

爲什麼我預期的PreparedStatement預備好是一個壞主意?

+1

您可能想要檢查[DbUtils](https://commons.apache.org/proper/commons-dbutils/),[jdbc-helper](https://code.google.com/archive/) p/jdbc-helper /)或[jdbi](http://jdbi.org/)。他們完成您在問題中展示的所有工作,並且在您不需要/需要整個ORM系統(如Hibernate,MyBatis,jooq等)時使用它們很好用。(編輯:修正了jdbc-helper鏈接到我正在考慮的那個,而不是Jruby的那個) –

回答

2

由於PreparedStatement綁定到Connection對象,因此需要同步它以便跨多個方法訪問,這將限制您的多用戶性能。

在這裏看到更多的信息:Reusing of a PreparedStatement between methods?

+2

我不認爲OP正在討論重複使用聲明。 – CKing

+0

是的,但問題在於談論您不再擁有本地方法的PreparedStatement的場景。它在一個地方創建並傳遞給另一個方法。這是我的擔憂。 – sharath

3

這樣做是一個很好的一個極好的主意

爲什麼它好?因爲您將您的PrepareStatement創作集中在一個地方。你的同事可以更乾淨地閱讀你的代碼。如果有錯誤,它會固定在一個地方,而不是到處都是。

這是一個好主意,幾個框架甚至可以在你的位置設計。我在我的評論中提到DbUtilsjdbc-helperjDBI。其他的是jcabi-jdbc,或流行的JOOQ。好吧,它們並不都是完全活躍的(jdbc-helper甚至可能已經死了),但它們仍然用於生產項目。

您特別提到的情況也可能依賴於您使用的數據庫層,因爲某些DB期望輸入像空列表或某些不同的值,或者只是null(Oracle,我在看着你!)。所以我強烈鼓勵使用這些庫,而不是編寫我自己的實用工具方法,jDBI是我的首選,因爲它是目前正在積極開發中的方法。

相關問題