作爲工作流引擎的一部分,我正在實現一個通用的數據庫步驟,該步驟將執行任何給定的SQL查詢並將結果作爲XML返回。該工作流程可以動態配置,因此傳遞給執行層的查詢將是一個完全限定的靜態SQL查詢,例如尋找從Java中給定的SQL查詢創建動態SQL的方法
SELECT * FROM USER WHERE USERID = 10。這種方法的缺點是數據庫每次運行時都會編譯查詢。有沒有辦法我可以通過編程方式從查詢中創建動態SQL查詢。像JPA這樣的Java或Hibernate是否支持這種功能?
作爲工作流引擎的一部分,我正在實現一個通用的數據庫步驟,該步驟將執行任何給定的SQL查詢並將結果作爲XML返回。該工作流程可以動態配置,因此傳遞給執行層的查詢將是一個完全限定的靜態SQL查詢,例如尋找從Java中給定的SQL查詢創建動態SQL的方法
SELECT * FROM USER WHERE USERID = 10。這種方法的缺點是數據庫每次運行時都會編譯查詢。有沒有辦法我可以通過編程方式從查詢中創建動態SQL查詢。像JPA這樣的Java或Hibernate是否支持這種功能?
一般而言,您需要使用綁定變量將您的輸入參數化爲查詢模板。有兩種形式的綁定變量,即i)未命名的綁定變量(或位置綁定變量);和ii)命名綁定變量。
這可以通過vanilla JDBC完成。我發現Spring JDBC特別容易操作。特別看看JDBCTemplate接口和它的實現
我可以參數化查詢,如果我知道查詢模板編譯時間。在我的情況下,我只會得到一個完整的查詢與所有變量設置。我如何從填充的查詢中提取模板?爲了進行比喻,我想爲數據庫寫一個GUI,用戶可以執行任意的隨機查詢,但大部分時間查詢都會重複進行,從而留下優化的機會。 – Kannan 2011-05-21 09:36:36
要求是,當我得到一個輸入查詢「SELECT * FROM用戶,其中,USER_ID = 10」我應該能夠產生一份書面聲明「SELECT * FROM用戶,其中,USER_ID =?」並確定我需要將參數在第一個位置設置爲10的整型。 – Kannan 2011-05-21 15:14:09
如果只是你提到的一種情況,那麼去字符串解析。如果你想它通用於所有查詢你需要用自己的SQL語法實現分析器 – kuriouscoder 2011-05-21 15:28:54
我同意用戶kuriouscoder,你應該使用綁定變量。這適用於普通的JDBC。大多數RDBMS都有一個遊標緩存,如果查詢是相同的(即沒有內聯變量),則遊標緩存保留查詢的解析版本以及內存中的執行計劃。所以解析器的開銷會很小。
就XML輸出而言,我可以推薦jOOQ(我是開發者)。在即將發佈的1.6.2版本中,我將爲各種格式(XML,HTML,JSON,CSV)添加導出功能。您的查詢將與jOOQ的流暢API來構建,它應該是這樣的:
String xml = create.selectFrom(USER)
.where(USERID.equal(10))
.fetch()
.formatXML();
輸出看起來就像這樣(並且可以XSL轉換爲任何其他格式):
<result>
<fields>
<field name="USERID"/>
<field name="FIRSTNAME"/>
<field name="LASTNAME"/>
...
</fields>
<records>
<record>
<value field="USERID">1</value>
<value field="FIRSTNAME">Lukas</value>
<value field="LASTNAME">Eder</value>
...
</record>
...
</records>
</result>
更多詳細信息,請參閱http://www.jooq.org
如果我明白你在問什麼,那麼你應該查看empiredb http://incubator.apache.org/empire-db/ - 這是一個相當小的項目,但至少在我使用它時,得到了積極和有力的支持。它就像python的sqlalchemy一樣,它可以讓你使用語言中的類和函數構造sql查詢。
從鏈接引用:
類型安全,串自由和直觀的API。構建包含select子句的任何SQL語句,並將其用於任何POJO而不僅僅是全功能實體bean。
我在項目中使用了MyBatis以獲得非常類似的行爲。 另請參閱User Guide以獲取完整信息。
在MyBatis中,您可以使用動態SQL定義查詢;你可以向SqlMapClient傳遞一個包含屬性的對象(例如POJO或Map),並在查詢文本中將它們用作:
那麼你的SQL映射器將執行查詢並返回一個Java對象:如果從查詢返回的記錄已知,則可以將列映射到POJO;否則在MyBatis中,可以將HashMap作爲結果類,最終通過SqlMapClient的queryWithRowHandler()方法處理每個記錄,以處理返回的數據。
一旦你至少有查詢的一個HashMap表示你就可以輕鬆地將它的XML。
這個問題的最佳答案可能是你在找什麼:http://stackoverflow.com/questions/222019/how-to-use-mysql-prepared-statement-caching – 2011-05-21 03:51:31