本篇講述如何使用JDBC來調用MySQL數據庫中的存儲過程。建議在學習如何使用JDBC調用存儲過程前,請先了解如何在數據庫中使用存儲過程。html
存儲過程是指在數據庫系統中,一組爲了完成特定功能的SQL語句集,存儲在數據庫中,通過第一次編譯後之後再調用任意次都不須要從新編譯了。說白了就是一堆SQL語句的合併,中間加了點邏輯控制,俗稱爲數據庫中的函數。在一些金融等大型企業中,基本都是由內部人員編寫好存儲過程,而後由外部程序員調用存儲過程,由於內部數據邏輯處理方式涉及商業機密等等。mysql
也就是說咱們如今有兩種方式來處理數據庫中的數據,一是經過JDBC從數據庫中取出數據而後經過業務層編寫處理數據的邏輯代碼;二是在數據庫中定義數據的存儲過程,在這個存儲過程當中完成對數據的邏輯操做,就比如數據庫中的函數,而咱們在Java程序中只要調用數據庫中的這個存儲過程便可。程序員
操做:sql
在MySQL數據庫中肯定要調用哪一個存儲過程,包括肯定該存儲過程的參數列表爲哪些SQL類型。數據庫
在JDBC中經過連接Connection對象,調用prepareCall(…)方法,在prepareCall方法中的參數爲字符串,內容應該爲」{call 存儲過程名(?(佔位符,個數根據存儲過程參數來定)...)}」,調用這個方法後返回CallableStatement對象。ide
經過返回的CallableStatement對象對於傳入類型的參數(IN),如PreparedStatement對象同樣設置佔位符的替代參數,而對於佔位符對應的參數是輸出類型(INOUT),則調用CallableStatement對象的registerOutParameter(…)方法,該方法第一個參數指明替代第幾個佔位符,第二個參數指明該存儲過程的輸出參數在數據庫中的SQL類型,在Java程序中可使用Types類的字段指定。函數
最後經過CallableStatement對象的execute()方法執行存儲過程,便可經過getXXX方法獲取prepareCall方法參數中佔位符類型爲輸出的參數值。工具
下面經過一個例子來講明。學習
例:url
咱們如今數據庫中自定義一個存儲過程,這個存儲過程的功能是在咱們傳入的每個字符串參數面前加上一段字符串,即將兩端字符串鏈接,最後返回:
delimiter //
create procedure addPrefix(in inputParam varchar(255),inout inOutParam varchar(255)) begin
select concat('long live sd...',inputParam) into inOutParam; end // delimiter ;
分析:第一行咱們將MySQL中的分隔符先定義爲「//」,由於等會在存儲過程的邏輯代碼中會使用到「;」,不先定義別的分隔符的話邏輯代碼還沒寫完數據庫就執行了。第二行定義存儲過程的名稱,同時在參數列表中定義參數輸入輸出類型(IN,OUT,INOUT),參數名稱,參數類型(SQL數據類型)。第三行開始以關鍵字「BEGIN」開始,以「END」和剛纔定義的分隔符結束,在這兩個中間就是日常的SQL語句了,也就是在這個部分編寫咱們處理參數的邏輯。最後,咱們將MySQL數據庫的分隔符從新定義回分號「;」。
注:在數據庫中定義存儲過程時,應先選擇使用的庫,這裏我使用jdbcdemo庫。
這裏順便一說在MySQL中如何使用SQL命令來調用存儲過程,對於咱們上面剛剛建立的存儲過程,可使用以下SQL命令語句來調用和查看結果:
set @inputParam = 'LRR'; call addPrefix(@inputParam,@result); select @result;
由於咱們使用到了輸入參數,所以在調用存儲過程以前須要先設置好輸入類型In的參數,在MySQL中,使用「@」表明該參數是一個用戶變量,而對於輸出類型out或inout也須要一個自定義用戶變量,最後由select將結果顯示,結果以下圖所示:
(注:用戶變量在退出MySQL命令行窗口後會自動釋放資源)
下面開始介紹在Java中如何調用數據庫中的存儲過程。
建立Java工程,在工程中導入數據庫鏈接驅動的jar包。在【src】目錄下新建一個database.properties文件,內容以下:
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcdemo
username=root
password=root
構建JDBC的工具類,包括註冊驅動,獲取鏈接,釋放資源和鏈接等,這部分同《JDBC操做數據庫的學習(2)》中相同,此處略。
接着,咱們將使用JDBC來調用上面剛剛定義的存儲過程:
1 public void callableTest() throws SQLException { 2 Connection conn = null; 3 CallableStatement st = null; 4 ResultSet rs = null; 5 try{ 6 conn = JdbcUtils.getConnection(); 7 st = conn.prepareCall("{call addPrefix(?,?)}"); 8 st.setString(1, "love LRR"); 9 st.registerOutParameter(2, Types.VARCHAR); 10 st.execute(); 11 String contactPrefix = st.getString(2); 12 System.out.println(contactPrefix); 13
14 }finally{ 15 JdbcUtils.release(conn, st, rs); 16 } 17 }
觀察程序運行結果:
CallableStatement對象是Statement對象的子類,所以在調用JdbcUtils.release方法時使用了多態。在prepareCall方法中的參數是指定調用哪一個存儲過程的字符串,同時使用到了佔位符,那麼經過CallableStatement對象對傳入類型的參數設置要替代佔位符的數據,而對於輸出類型的參數則調用registerOutParameter方法替代佔位符並指定SQL類型。在Java中Types類封裝了各類SQL類型的字段。
以上就是如何使用JDBC調用MySQL數據庫中的存儲過程的步驟。