CallableStatement 和 PreparedStatement用法特別相似,只是CallableStatement 可以用來調(diào)用存儲過程燎猛。
存儲過程簡介調(diào)用簡介
SQL語句需要先編譯然后執(zhí)行,而存儲過程(Stored Procedure)是一組為了完成特定功能的SQL語句集重绷,經(jīng)編譯后存儲在數(shù)據(jù)庫中,用戶通過指定存儲過程的名字并給定參數(shù)(如果該存儲過程帶有參數(shù))來調(diào)用執(zhí)行它昭卓。
存儲過程是可編程的函數(shù),在數(shù)據(jù)庫中創(chuàng)建并保存葬凳,可以由SQL語句和控制結(jié)構(gòu)組成。當(dāng)想要在不同的應(yīng)用程序或平臺上執(zhí)行相同的函數(shù)火焰,或者封裝特定功能時,存儲過程是非常有用的昌简。數(shù)據(jù)庫中的存儲過程可以看做是對編程中面向?qū)ο蠓椒ǖ哪M,它允許控制數(shù)據(jù)的訪問方式纯赎。
存儲過程的優(yōu)點:
(1). 增強(qiáng)SQL語言的功能和靈活性:存儲過程可以用控制語句編寫,有很強(qiáng)的靈活性犬金,可以完成復(fù)雜的判斷和較復(fù)雜的運(yùn)算。
(2). 標(biāo)準(zhǔn)組件式編程:存儲過程被創(chuàng)建后峰伙,可以在程序中被多次調(diào)用,而不必重新編寫該存儲過程的SQL語句该默。而且數(shù)據(jù)庫專業(yè)人員可以隨時對存儲過程進(jìn)行修改,對應(yīng)用程序源代碼毫無影響栓袖。
(3). 較快的執(zhí)行速度:如果某一操作包含大量的Transaction-SQL代碼或分別被多次執(zhí)行,那么存儲過程要比批處理的執(zhí)行速度快很多裹刮。因為存儲過程是預(yù)編譯的。在首次運(yùn)行一個存儲過程時查詢必指,優(yōu)化器對其進(jìn)行分析優(yōu)化,并且給出最終被存儲在系統(tǒng)表中的執(zhí)行計劃。而批處理的Transaction-SQL語句在每次運(yùn)行時都要進(jìn)行編譯和優(yōu)化霜第,速度相對要慢一些户辞。
(4). 減少網(wǎng)絡(luò)流量:針對同一個數(shù)據(jù)庫對象的操作(如查詢泌类、修改)底燎,如果這一操作所涉及的Transaction-SQL語句被組織進(jìn)存儲過程,那么當(dāng)在客戶計算機(jī)上調(diào)用該存儲過程時双仍,網(wǎng)絡(luò)中傳送的只是該調(diào)用語句,從而大大減少網(wǎng)絡(luò)流量并降低了網(wǎng)絡(luò)負(fù)載朱沃。
(5). 作為一種安全機(jī)制來充分利用:通過對執(zhí)行某一存儲過程的權(quán)限進(jìn)行限制,能夠?qū)崿F(xiàn)對相應(yīng)的數(shù)據(jù)的訪問權(quán)限的限制逗物,避免了非授權(quán)用戶對數(shù)據(jù)的訪問,保證了數(shù)據(jù)的安全翎卓。
MySQL的存儲過程
存儲過程是數(shù)據(jù)庫的一個重要的功能,MySQL 5.0以前并不支持存儲過程失暴,這使得MySQL在應(yīng)用上大打折扣。好在MySQL 5.0開始支持存儲過程锐帜,這樣即可以大大提高數(shù)據(jù)庫的處理速度,同時也可以提高數(shù)據(jù)庫編程的靈活性缴阎。
1. 創(chuàng)建MySQL存儲過程
DELIMITER //
create procedure findById(IN pid INTEGER)
BEGIN
SELECT * FROM `user` WHERE id= pid;
END //
DELIMITER;
2. 調(diào)用存儲過程
package com.jdbc;
import java.sql.*;
/**
* Created by Fant.J.
* 2018/3/5 20:14
*/
public class CallableStatementTest {
static String url = "jdbc:mysql://localhost:3306/user";
static String user = "root";
static String password = "root";
public static void main(String[] args) {
Connection connection = null;
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection(url, user, password);
String sql = "CALL findById(?)";
CallableStatement stmt = connection.prepareCall(sql);
stmt.setInt(1,27);
ResultSet resultSet = stmt.executeQuery();
while (resultSet.next()){
int id = resultSet.getInt("id");
String username = resultSet.getString("username");
String birthday = resultSet.getString("birthday");
String sex = resultSet.getString("sex");
String address = resultSet.getString("address");
System.out.println(" " + username + " " + birthday + " " + sex
+ " " + address);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Fant.J reUseTest 2017-04-20 男 xxxx
3. 全面科普
通過前面的講解和例子简软,我想你肯定已經(jīng)了解調(diào)用存儲過程到底是個什么東西,但是你肯定也能看到痹升,這例子只是一個特例,所以我在這里把 調(diào)用存儲代碼中的sql做個詳解疼蛾。
存儲過程參數(shù)詳解
- in:往過程里傳參。 (參考我創(chuàng)建存儲過程中的代碼(IN pid INTEGER))
- out:往過程外傳參。
- inout:in and out
相對于oracle數(shù)據(jù)庫來說衍慎,MySQL的存儲過程相對功能較弱转唉,使用較少稳捆。
創(chuàng)建的存儲過程保存在數(shù)據(jù)庫的數(shù)據(jù)字典中。