Giao diện CallableStatement được sử dụng để thực thi Stored Procedure. Một đối tượng CallableStatement có thế trả về một hoặc nhiều đối tượng ResultSet. Như bạn đã biết, việc sử dụng Stored Procedure giúp nâng cao hiệu suất bởi vì chúng đã được biên dịch trước. Nếu bạn chưa tìm hiểu về Stored Procedure, thì dưới đây chúng tôi liệtkê một số điếmkhác nhau giữa Stored Procedure và hàm đế bạn dễ theo dõi:
Bảng 7.3. Một số điềm khác nhau giữa stored Procedure và hàm
StoredProcedure Hàm
Được sử dụng đế thực hiện một trình tự logic nào đó
Được sử dụng để thực hiện phép tính toán Không bắt buộc phải có kiếu trả về Phải có kiểu trả về
Có thể trả về 0hoặc nhiều giá trị Có thể trả về chỉ một giá trị
Chúng ta có thể gọi hàmtừprocedure Procedure không thể được gọi từ hàm Procedure hỗ trợ các tham so input và
output
Hàm chỉ hỗ trợ các tham số input Xử lý ngoại lệ với khối try/catch có
thể được sử dụngtrongprocedure
Xử lý ngoại lệ với try/catch không thể được sử dụng trong các hàm do người dùng tự định nghĩa
7.11.1. Tạo đối tượng CallableStatement trong JDBC
Đầu tiên, bạn tạo một stored procedure đơn giản trong MySQL đế lấy tên sinh viên như sau:
DELIMITER $$
DROP PROCEDUREIF EXISTS 'sinhvien'.'getTenSV' $$
CREATE PROCEDURE 'sinhvienVgetTenSV'
(IN MS-SINHVIEN INT, OUT TEN-SINHVIEN VARCHAR(255)J BEGIN
SELECT ten INTO TEN-SINHVIEN FROM sinhvienkóO
WHEREMSSV = MS-SINHVIEN;
END $$
DELIMITER;
Chạy đoạn code trên trong MySQL của bạn sẽ tạo một Stored Procedure. Trong đó:
-sinhvien là tên cơ sở dữ liệu.
-getTenSV là tên của stored procedure.
- sinhvienkóO là tên bảng.
Bạn cũng phải chú ý các DELIMITER $$ và DELIMITER, hai cái này là không thể thiếu. Có ba kiêu thamsố là IN, OUT và INOUT. Đối tượngPreparedStatement chỉ sử dụng tham số IN, trong khiđốitượng CallableStatement có thể sử dụngcảba tham sốnày.
- Tham số IN: Là một tham số mà giá trị của nó chưađược biết khi lệnh SQL được tạo. Bạn gắn kết các giá trị tới các tham số INbời các phương thức setXXXQ.
-Tham so OUT: Là một tham số mà giá trị của nó được cung cấp bời lệnh SQL nó trả về. Giá trị của chúng được thunhận thông qua phương thức getXXXQ. Trong đó, kiểu của tất cả tham so OUT phải được đăng ký trước khi thực thistored procedure.
- Tham số INOUT: Là một tham số mà cung cấp cả giá trị input và output. Bạn gắn kết các biếnvới phương thứcsetXXXQ vàthunhận giá trị với phương thức getXXXQ.
Để lấy instance của đối tượng CallableStatement, bạn sử dụng phương thức prepareCall() của giao diện Connection. Dưới đây là cú pháp củaphương thức này:
public CallableStatementprepareCall("{ call ten_procedure(?,?...?)}");
Trong đó, mỗi dấu ? đại diện cho một tham số. Tiếp theo, bạn theo dõi mẫu code đế gọi một stored procedure. Bạn để ỷ rằng ở đây getEmp nhận hai tham số:
CallableStatement cstmt= null;
try{
String SQL = "{call getTenSV (?, ?)}";
cstmt = conn.prepareCall (SQL);
}
catch (SQLException e) {
}
finally { }
7.11.2. Đóng đối tượng CallableStatement trong JDBC
Để đóng đối tượng CallableStatement, bạn sử dụng phương thức close() theo mẫu sau:
CallableStatementcstmt= null;
try{
String SQL = "{call getTenSV (?, ?)}";
cstmt = conn.prepareCall (SQL);
}
catch (SQLException e) { }
finally {
cstmtcloseQ;
}
7.11.3. Ví dụ về đối tượng CallableStatement trong JDBC
Chương trình 7.6 minh họa cách sử dụng giao diện PreparedStatement trong JDBC với cơ sở dữ liệu MySQL.
Chương trình 7.6
//Buoc 1: Ban can importcacgoi can thiet importjava.sql.*;
public class JDBCCallableStatement {
/1 Ten cua driver vadia chi URL cua co so du lieu
staticfinal StringJDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB-URL = "jdbc:mysql://localhost/sinhvien";
//Ten nguoi dung va mat khau cua co so du lieu static final String USER = "root";
static final String PASS = "123456";
public static void main(String[] args) { Connection conn - null;
CallableStatement stmt = null;
try{
/1 Buoc 2: Dang ky Driver
Class.forNamef'com.mysql.jdbc.Driver");
// Buoc 3: Momot ket noi
System.out.printlnf'Dang ket noi toi co so du lieu...");
conn = DriverManager.getConnection(DB_URL, USER, PASS);
// Buoc 4: Thue thi truy van
System.out.printlnf'Tao cac lenh truy van SQL...");
Stringsql= "{call getTenSV (?, ?)}";
stmt = conn.prepareCall(sql);
// Dautien gan ket tham so IN,sau do la tham so OUT int MS-SINHVIEN = 2;
stmt.setlntfl, MS-SINHVIEN); 11 Lenh nay thietlap mssv la 2 // Dang ky tham so thuhai
stmt.register0utParameter(2, java.sql.Types.VARCHAR);
// Su dung phuong thuc execute dechay stored procedure.
System.out.printlnf'Thuc thistored procedure...");
stmt.executeQ;
// Lay ten sinh vien vol phuong thuc getxxx String TEN_SINHVIEN = stmt.getString(2);
System.out.printlnf'Tensinh vien co MSSV:" +
MS-SINHVIEN + " la " + TEN-SINHVIEN);
stmt.close();
conn.closeQ;
} catch(SQLException se) { // Xu ly cac loi cho JDBC se.printStackT race 0;
} catchfException e) {
// Xu lycac loi cho Class.forName e.printStackTraceQ;
} finally {
// Khoi finallyduoc sudung de dong cacresource try {
if(stmt!=null) stmtcloseQ;
} catchfSQLException se2) {}
try{
if(conn!=null)
conn.closeQ;
} catch(SQLException se) { se.printStackTraceQ;
}// Ket thuckhoi finally }//Ketthuckhoi try }// Ketthucmain
}// KetthucJDBCCallableStatement