7.4. Kết nối JDBC với cơ sử dữ liệu
7.4.5. Đóng kết nối JDBC
Garbage Collector của Java sẽ đóng kết nối khi nó thực hiện quá trình xóa các đối tượng đã cũ. Tuy nhiên, sau khi đã thực hiện xong tác vụ với Database, bạn nên đóng tất cả kết nối tới cơ sở dữ liệu. Bước thực hành này là cần thiết và thực sự tốt, vì đồikhiviệc quá tin tưởng vàotrình dọn rác sẽ gây ra những hậu quả không mong muốn. Đe bảo đảm rằng một kết nối đã được đóng, bạn có thế cung cấp một khối finally trong phần code.
Khối finally luôn luôn được thực thi, nếu không thì một exception sẽ xuất hiện. Để đóng kết nối đã mờở trên, bạn nên gọi phương thức close() có cú pháp như sau:
publicvoid conn.closef) throws SQLException 7.5. KÉT NỐI JDBC VỚI cơ SỞ DỮ LIỆU ORACLE
Phần này chúng ta cùng tìm hiểu các bước đơn giản để thiết lập một kết nối JDBC với cơ sở dữ liệu Oracle. Để kết nối ứng dụng Java với cơ sở dữ liệu Oracle, bạn cần tải ojdbc!4.jar file. Tiếp đó, bạn có thể làm theo một trong hai cách sau trong hệ điều hành Windows:
-Dán tệp ojdbcl4.jartrongthư mục JRE/lib/ext.
- Thiết lập classpath:
+ Thiết lập classpath tạm thời: đầu tiên bạn tim tệp ojdbcl4.jar, sau đó mở cửa sổ lệnh và gõ lệnh: C:>set classpath=c:\folder\ojdbcl4.jar;.;
+ Thiết lập classpath vĩnh viễn (xem hình 7.6): Vào MyComputer Properties —>
Advanced tab Environment variables Tạo tab mới user variable Viết giá trị path trong tên biến dẫn đến thư mục bin của cài đặt java —> OK —> OK OK. Trong phần variable name, bạn viết classpath và trong phần variable value, bạn dán đường dẫn là C:\oraclexe\app\oracle\product\102.0\server\jdbc\lib\ojdbcl4.jar;.;
Hình 7.6. Thiết lập classpath vĩnh viễn cho thư viện Oracle.
Sau đó, để kết nối ứng dụng Java với cơ sở dữ liệu Oracle, bạn thực hiện theo các bước như dưới đây. Trong ví dụ này, chúng ta sử dụng cơ sở dữ liệu Oracle10G. Vì thế, chúngta cần biết các thông tin sau về cơ sỡ dữ liệuOracle:
- Lớp Driver cho cơ sở dữ liệu Oracle làoracle.jdbc.driver.OracleDriver.
-Địa chỉ kết nối cho cơ sở dữ liệu OraclelOG là jdbc:oracle:thin:@localhost:1521:xe.
Trongđó:
+ jdbc là API.
+ oracle là cơ sở dữ liệu.
+ thin làtrình điều khiển.
+ localhost là tên server mà Oracle đang chạy (có thể sử dụng địa chỉ IP tại đây).
+ 1521 là số hiệucống.
+ xe là tên Oracle Service.
Bạn có thể lấy tất cả thông tin này từ tệp tintnsnames.ora.
-Username mặc định cho cơ sờ dữ liệu Oracle làsystem.
- Password đượccung cấp bởi người dùngtại thời điểm cài đặt cơ sở dữ liệu Oracle.
Bây giờ, chúng tasẽ tạo một bảng trong cơ sởdữ liệuOracle.
// Tao co so du lieu co ten lasinhvien create database sinhvien;
// Chon co so du lieudelam viec use sinhvien;
// Tao bang hocphi trong co so du lieutren
create table hocphifmssv number(lO), ho varchar2(50], ten varchar2(30), hocphi number(3J);
Chương trình mau kết nối ứngdụng Java với cơ sở dữ liệu Oracle
Trong ví dụ này, chúng ta sử dụng usemame mặc định là system và password là 123oracle. Chương trình đơn giản này được sử dụng để lấy tấtcả bản ghi có trong bảng hocphi. Chúng tôi đã liệt kê và comment chi tiết về các bước trong khi kết nối ứng dụng Java với cơ sở dữ liệu Oracleđể bạn tiện theo dõi như trongchương trình 7.2.
Chương trình 7.2 importjava.sql.*;
public class JDBCOracle {
public static void mainfString args[]) { try{
// Buoc 1: Tai lop Driver
Class.forNamef'oracle.jdbc.driver.OracleDriver");
11 Buoc 2: Tao doituong Connection
Connection con=DriverManager.getConnection(
"jdbc:oracle:thin:@localhost:1521:xe'7,system"/'123oracle");
11 Buoc 3: Tao doituong Statement Statementstmt=con.createStatementO;
// Buoc 4: Thue thi truy van
ResultSetrs=stmt.executeQuery("select * from hoephi");
while(rs.nextO)
System.out.println(rs.getlnt(l) + ""+ rs.getString(2) + "" + rs.getString(3) 4- rs.getlnt(4));
// Buoc 5: Dong doituong Connection con.closeQ;
} catch(Exception e){ System.out.println(e);}
} }
7.6. KÉT NỐI JDBC VỚI cơ SỞ DỮ LIỆU MYSQL
Trong phần này, chúng ta cùng tìm hiểu các bước đơn giản để thiết lập một kết nối JDBC với cơ sờ dữ liệu MySQL. Chúng tôi sử dụng usemame là root và mật khẩu là 123457. Để kết nối ứng dụng Java với MySQL Database, bạn cần tải mysqlcoimector.jar file. Tiếp theo, bạn có thế làm theo một trong hai cách trong hệ điều hành Windows:
- Dán tệp mysqlconnector.jar vào trong thư mục JRE/lib/ext.
-Thiết lập classpath:
+ Thiết lập classpath tạm thời: đầu tiên bạn tìm tệp mysqlconnector.jar, sau đó mờ cửa sổ lệnh và gõ lệnh: C:>set classpath=c:\folder\mysql-connector-java-7.0.8- bin.jar;.;
+ Thiết lập classpath vĩnh viễn (xem hình 7.6): Vào MyComputer properties —>
Advanced tab —> Environment variables —> Tạo tab mới user variable Viết giá trị path trong tên biến —> Dần đến thư mục bin củacài đặt java —> OK —> OK —> OK. Trong phần variable name, bạn viết classpath và trong phần variable value, bạn dán đường dẫn là C:\folder\mysql-connector-java-7.0.8-bin.jar;.;
Sauđó, đế kết nối ứng dụng Java với MySQL Database, bạn thựchiện theo các bước như dướiđây. Chúng ta cầnbiết các thôngtin sau về MySQL Database:
-Lớp Driver cho MySQL Database là com.mysql.jdbc.Driver.
-Địa chỉ kết nối cho MySQL Database làjdbc:mysql://localhost:3306/sinhvien.
Trongđó:
+ jdbc là API.
+ mysqllà cơ sở dữ liệu.
+ localhost là tên server mà MySQL đang chạy (chúng ta cũng có thể sử dụng địa chỉ IP tại đây).
+ 3306 là số hiệu cống.
+ sinhvien là tên của cơ sở dữ liệu (tùy theo cơ sở dữ liệu mà bạn muốn sử dụng).
- Username mặc định cho MySQL Database là root.
-Password đuợc cung cấp bởi nguời dùng tại thời điếm cài đặt MySQL Database (trong ví dụ này là 123456).
Bây giờ, chúngtasẽ tạo một bảng trongMySQL Database.
// Tao co so dulieu co ten la sinhvien create databasesinhvien;
// Chon co so du lieude lam viec use sinhvien;
// Tao bang hocphi trong co so dulieutren
create table hocphifmssv number(lO), ho varchar2(50), ten varchar2(30), hocphi number(3));
Chương trình mẫu kết noi ứngdụng Java với MySQL Database
Chươngtrình 7.3 được sử dụng đế lấy tất cả bản ghi có trongbảng hocphi. Chúng tôi đã liệt kê và comment chi tiết về các bước trong khi kết nối ứng dụng Java với MySQL Databaseđể bạn tiện theo dõi.
Chương trình 7.3 import java.sql.*;
public class JDBCMySQL {
public static void main(String args[]) { try{
// Buoc 1: Tai lop Driver
Class.íorNameCcom.mysql.idbc.Driver");
// Buoc 2: Tao doi tuongConnection, trong do sinhvien la ten co so du lieu, root la username vamat khau la 123456
Connection con=DriverManager.getConnection(
"jdbc:mysql://localhost:3306/sinhvien","root","123456");
// Buoc 3: Tao doituong Statement
Statement stmt=con.createStatementO;
/1 Buoc 4: Thue thitruy van
ResultSetrs=stmt.executeQuery("SELECT * FROM hoephi");
while(rs.nextO)
System.out.println(rs.getlnt(l) + "" + rs.getString(2) + "" + rs.getString(3) + rs.getlnt(4));
// Buoc 5: Dongdoituong Connection con.closeQ;
} catch(Exception e){ System.out.println(e);}
} }
7.7. LỚP DRIVERMANAGER TRONG JDBC
Lóp DriverManager hoạtđộng như một giao diện giữa người dùng vàcác trình điều khiển. Nó theo dõi các trình điều khiển có sẵn và xử lý việc thiết lập kết nối giữa một Database và trình điều khiển thích hợp. Lớp DriverManager duy trì một danh sách các lớp Driver mà đã được đăng ký bởi chính chúng bằng cách gọi phương thức DriverManager.registerDriverQ.
Một số phưong thức được sử dụng phố biến củalóp DriverManager:
- public static void registerDriver(Driver driver)throws SQLException:
Phuong thức này được sửdụng đế đăng ký trình điều khiến đã cho với DriverManager.
- public static void deregisterDriver(Driver driver):
Phương thức này được sử dụng để xóa trình điều khiển đã cho khỏi danh sách đăng ký với DriverManager.
- public staticConnection getConnection(String url):
Phương thức này được sửdụng để thiết lập kết nối với URL đãcho.
- public static Connection getConnection(String url, string userName, string password):
Phương thức này được sử dụng để thiếtlập kết nối với URL, usemame và password đã cho.
- public static void setLoginTimeout(int second):
Phương thức này thiết lập thời gian (bằng giây) tối đa mà một trình điềukhiến sẽ đợi trongkhi cố gắng kết nốivới một cơ sở dữ liệu.
- public static int getLoginTimeout():
Phương thức này lấy thời gian (bằng giây) tối đa mà một trình điều khiển sẽ đợi trongkhi cố gắng đăng nhập vào một cơ sở dữ liệu.
7.8. GIAO DIỆN CONNECTION TRONG JDBC
Đối tượng Connection biểu diễn ngữ cảnh giao tiếp. Đối tượng của Connection có thể được sử dụng để lấy đối tượng của Statement và DatabaseMetaData. Giao diện Connection cung cấp nhiều phương thức để quản lý giao tác như commitQ, rollback(),...
Khi cấu hình một Connection, các ứng dụng JDBC nên sử dụng phương thức thích họp, chẳng hạn như setAutoCommint hoặc setTransactionlsolation. Các ứng dụng không nên triệu hồi các lệnh SQL trực tiếp để thay đổi cấu hình củaConnectionkhi đã có một phương thức JDBC có sẵn. Theo mặc định, đối tượng Connection trong chế độ auto-commit,tức là nó tự động ký thác các thay đổi sau khi thực thi mỗi lệnh. Nếu chế độ auto-commit đã bị vô hiệu hóa, thì phương thức commitphải được gọi tường minh đế ký thác cácthayđối.
Dưới đây là một số phương thức được sử dụngphổ biến của giao diện Connection:
-public Statement createStatement():
Phương thức này tạo đối tượng Statement để thực thi các truy vấn SQL.
- public Statement createStatement(int resultSetTypeJnt resultSetConcurrency) throws SQLException:
Phương thức này tạo một đối tượng Statement mà sẽ tạo các đối tượng ResultSet với type và concurrency đã cung cấp. Tham số resultSetType là một trong các kiểu sau: ResultSet.TYPE_FORWARD ONLY, ResultSet.TYPE_SCROLL_INSENSITIVE, hoặc ResultSet.TYPE SCROLL SENSITIVE. Tham số resultSetConcurrency là một trong các kiểu ResultSet.CONCURREADONLY hoặc ResultSet.CONCƯR-UPDATABLE.
- public void setAutoCommit(boolean autoCommit) throws SQLException:
Phương thức này thiết lập Connection trong chế độ auto-commit. Neu một Connection trong chế độ tự động kýthác thì tất cả các lệnh SQL củanó sẽ được thực thi và ký thác sau mỗi giao tác. Theo mặc định thì các Connection mới là trong chế độ auto-commit. Neu tham so autoCommit được thiết lập là true tức là kích hoạt chế độ auto-commit, nếu là false là vô hiệu hóa chế độ này.
-public void commỉto throws SQLException:
Phương thức này lưu các thay đổi đã được thực hiện trước đó, nên chỉđược sử dụng khi chế độ auto-commit đã bị vô hiệu hóa.
- public void rollback():
Phương thức này xóa tất cả các thay đổi đã được thực hiệntrướcđó vàqưay về trạng thái trước khi thực hiện thayđổi. Phương thức này được gọi trên một kết nốiđã được đóng hoặcđối tượng Connection này là trong chế độ auto-commit.
- public void close():
Phương thức này đóng kết nối và giải phóng resource ngay lập tức thay vì chờđợi chúng tựđộng được giảiphóng. Phương thức này sẽkhông hoạtđộng nếu bạn gọi nó trên một đối tượng đãbịđóng.
- setSavepoint (Stringten) throws SQLException:
Phương thức này tạo một savepoint với tên ten đã cho trong giao tác hiện tại và trả vềđối tượng Savepoint mới biểu diễn nó. Ở đây ten là tên của savepoint.
7.9. GIAO DIỆN STATEMENT TRONG JDBC
Tiếp theo, chúngta cùng tìm hiểu về giao diện Statement trong JDBC. Giao diện này cung cấp nhiều phương thức để thực thicác truy vấn vớicơ sở dữ liệu và trả về kết quà mà nó tạo ra. Theo mặc định, tại cùng một thời điểm chỉ có một đối tượng ResultSet có thể được mở cho mỗi đốitượng Statement. Vì thế, nếu hoạtđộng đọc một đối tượng ResultSet bị chen ngang bời hoạt động đọc đối tượng khác thì đối tượng khác này phải đượctạo bởi đốitượng Statementkhác.
7.9.1. Tạo đối tượng statement
Đe tạo đối tượng Statement, bạn sử dụng phương thức createStatementO của đối tượng Connection, như sau:
Statement stmt = null;
try{
stmt = conn.createStatementQ;
}
catch (SQLException e) { }
finally { }
Sau khi đã tạo đối tượng Statement, bạn có thể sử dụng rất nhiều phương thức của đối tượng này để thực thi một lệnh SQL. Dưới đây là một số phương thức được sử dụng phổ biếncủaStatement giao diện.
- public ResultSet executeQuery(String sql):
Thực thimột lệnh SQL đã cho và trả về một đối tượng Resultset đơn. Tham số sql là một lệnh SQL. Phương thức này không thể được gọi trên một đối tượng PreparedStatement hoặc CallableStatement.
- public int executeUpdate(String sql):
Thực thi lệnh SQL đã cho, có thể là INSERT, UPDATE, DELETE hoặc một lệnh SQL mà không trả về bất kỳ cái gì như lệnh SQL DDL. Phương thức nàykhông thể được gọitrên một đối tượng PreparedStatement hoặc CallableStatement.
- public boolean execute(String sql):
Thực thi lệnh SQL đã cho mà có thể trả về nhiều kết quả. Thường thì bạn có thể bò qua phương thức này, trừkhi bạn đang thực thi một store procedure mà bạn biết rằng nó sẽ trả về nhiều kết quả hoặc bạn đang thực thi một chuỗi SQL mà bạn chưa biết. Phương thức này không thể được gọi trên một đốitượngPreparedStatementhoặc CallableStatement.
- public int[] executeBatch():
Được sử dụng để thực thi một nhóm các lệnh và nếu thành công thì trả về một mảng.
Các phần tử trong mảng trả về được sắp xếp theo thứ tự tương ứng với lệnh trong batch.
Cácphần tử trongmảng được trả về này có thế là:
+ Một số lớn hơn hoặc bằng 0, chỉ rằng lệnh được thực thi thành công và đó là số hàng bị tác động trongcơsở dữ liệu.
+ Một giá trị SUCCESS NO INFOchỉ rằng lệnh được thực thi thành công nhưng số hàng bị tác động làchưa biết.
+ Một giá trịEXECUTE-FAILED chỉ rằng lệnh đã thất bại.
-void close() throws SQLException:
Đóng đối tượng Statement và giải phóng resource ngay lập tức. Khi đã đóng đối tượng Statement rồi, thì các lời gọi phương thức nào tới đối tượngđó sẽ không hoạt động.
Khi một đốitượng Statement đã bị đóng thìđối tượng ResultSet củanó cũng bị đóng.
7.9.2. Đóng đối tượng statement
Lý do tương tự như khi bạn đóng đối tượng Connection để giải phóng tài nguyên, thì ở đây sau khi đã thực hiện xong các hoạt động với giao diện Statement thỉ bạn nên đóng đối tượng Statementlại. Việc này được thực hiện đơngiảnbởi phương thức close() ở trên.
Điều tất nhiên là nếu bạn đã đóng đối tượng Connection thì đối tượng Statement cũng sẽ bị đóng (theo ngầm định). Tuy nhiên, việc đóng tường minh đối tượng Statement là
một bước thực hành tốt đế đảm bảo chắc chắn rằng đối tượng đã được đóng và resource đượcgiải phóng.
Dưới đây là mẫu chung:
Statement stmt = null;
try{
stmt = conn.createStatementQ;
}
catch (SQLException e) { }
finally { stmtcloseQ;
}
7.9.3. Ví dụ minh họa đối tượng statement trong JDBC
Chưong trình 7.4 minh họa cách sử dụng giao diện Statement trong JDBC với cơ sở dữ liệu MySQL.
Chương trình 7.4
//Buoc 1: Ban can import cacgoi can thiet import java.sql.*;
public classJDBCStatement{
// Ten cua driver vadia chi URL cuaco so du lieu
static final StringJDBC-DRIVER= "com.mysql.jdbc.Driver";
static final String DB-URL = "jdbc:mysql://localhost/sinhvien";
// Ten nguoi dung va matkhau cua co so du lieu static final String USER = "root";
static final String PASS = "123456";
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
try{
// Buoc 2: Dang ky Driver
Class. forName("com.mysql.jdbc.Driver");
// Buoc 3: Mo mot ket noi
System.out.printlnf'Dang ket noi toi co so du lieu...");
conn = DriverManager.getConnection(DB_URL,USER,PASS);
// Buoc 4: Thue thitruy van
System.out.printlnf'Tao cac lenh truy van SQL...");
stmt = conn.createStatementf);
String sql = "UPDATE sinhvienkóO SET diemthi=10 WHERE mssv=3";
// Chung takiem tra xem no co tra vemottrue ResultSet hay khong Booleanret= stmtexecute(sql);
System.out.println("\nGia tri tra ve la:" +ret.toStringO);
11Chung ta cap nhat diem thi cua ban ghi co mssv = 3;
int rows = stmt.executeUpdate(sql);
System.out.println("So hang bi tacdong:" + rows);
11 Lua chon tat ca ban ghiva hien thi.
sql = "SELECT mssv, ho, ten, diemthi FROM sinhvienkóO";
ResultSetrs - stmt.executeQuery(sql);
11Buoc 5: Lay du lieu tu Result Set while(rs.next()){
// Lay du lieu boi su dung ten cot int mssv = rs.getlntf'mssv");
int diemthi = rs.getlntf'diemthi");
String ho = rs.getStringf'ho");
String ten = rs.getStringf'ten");
11 Hien thi cac gia tri
System.out.print("\nMSSV:" + mssv);
System.out.print("\nHo:" +ho);
System.out.println("\nTen:" + ten);
System.out.print("\nDiem Thi:" + diemthi);
System.out.print("\n=================");
}
// Buoc 6: Don sach moi truong va giaiphongresource rs.closeQ;
stmt.closeQ;
conn.closeQ;
} catchfSQLException se) { // Xu ly cac loi cho JDBC se.printStackTracef);
} catch(Exception e) {
// Xu ly cac loi cho Class.forName e.printStackTraceQ;
} finally {
// Khoi finally duoc sudung de dong cacresource try{
if (stmt!=null) stmtcloseQ;
} catchfSQLException se2){) try{
if (conn!=null) conn.closeQ;
} catch(SQLException se) {
se.printStackTraceQ;
}// Ketthuckhoi finally }// Ket thuckhoi try }// Ketthucmain }// KetthucJDBCStatement
7.10. GIAO DIỆN PREPAREDSTATEMENTTRONG JDBC
Giao diện PreparedStatement là một giao diện con của Statement. Nó được sử dụng để thực thi các truy vấn được tham số hóa. Ví dụcâu lệnh sau:
String sql="INSERT INTO ten.bang values(?,?,?)";
Nhưbạn thấy, chúng ta đang truyền các tham số cho values. Giá trị của nó sẽ được thiết lập bằng việc gọi phương thức setter (ví dụ như setShort, setstring,...) của PreparedStatement. Đối tượngPreparedStatement là một đối tượngmà biểu diễn một lệnh SQL được biên dịch trước. Tức là, một lệnh SQL được biên dịch trước và được lưu trữ trong một đối tượng PreparedStatement. Đối tượng này sau đó có thể được sử dụng để thực thi có hiệu quả Statement này nhiều lần.
Sửdụng PreparedStatement giúp tăng hiệu suất, bởi vìtruy vấn của bạn sẽ được biên dịch chỉ một lần.
7.10.1. Tạo đối tượng PreparedStatement trong JDBC
Phương thức PrepareStatement() của giao diện Connection được sử dụng để trả về đối tượng PreparedStatement. Dưới đây là cú pháp chung:
public PreparedStatement prepareStatementfString queryjthrows SQLException{}
Đe tạo đối tượng PreparedStatement, bạn có thế theo mẫu chung sau:
PreparedStatement pstmt = null;
try{
String SQL = "UPDATE sinhvienkóO SET diemthi=? WHERE mssv=?";
pstmt = conn.prepareStatement(SQL);
}
catch (SQLException e) {