Nhập môn Java với JDBC và MySQL (I)

JDBC là viết tắt của “Java DataBase Connectivity”. Nó là một API (Application Programming Interface) có chứa một tập hợp các lớp, các giao diện Java và các thông báo lỗi ngoại lệ nằm trong cùng một đặc tả mà theo đó cả các công ty sản xuất JDBC driver cũng như các nhà phát triển JDBC đều phải tuân thủ chặt chẽ khi phát triển ứng dụng.

JDBC là một chuẩn truy xuất cơ sở dữ liệu rất phổ biến. Các RDBMS (Relational Database Management Systems – Hệ quản trị cơ sở dữ liệu quan hệ) hay các nhà sản xuất phần mềm bên thứ ba phát triển các driver cho Java đều cần tuân thủ chặt chẽ đặc tả JDBC. Các nhà phát triển khác sử dụng các driver này để phát triển nên các ứng dụng có truy cập cơ sở dữ liệu

Ai phát triển đặc tả JDBC?

SUN chuẩn bị và duy trì đặc tả JDBC. Bởi JDBC chỉ là một đặc tả (đề xuất cách viết và sử dụng các JDBC driver), nên các công ty sản xuất phần mềm bên thứ ba sẽ phát triển các JDBC driver tuân thủ chặt chẽ đặc tả này. Các nhà phát triển JDBC sau đó sẽ sử dụng các driver này để truy cập vào các nguồn dữ liệu.

Tại sao lại dùng JDBC?

JDBC tồn tại là để giúp các nhà phát triển Java tạo nên các ứng dụng truy xuất cơ sở dữ liệu mà không cần phải học và sử dụng các API độc quyền do các công ty sản xuất phần mềm khác nhau bên thứ ba cung cấp. Bạn chỉ cần học JDBC và sau đó bạn sẽ được đảm bảo rằngbạn sẽ có thể phát triển nên các ứng dụng truy cập cơ sở dữ liệu có khả năng truy cập đến các RDBMS khác nhau bằng cách sử dụng các JDBC driver khác nhau.

Kiến trúc JDBC

Trong Java có 2 lớp chủ yếu chịu trách nhiệm về thiết lập kết nối đến một cơ sở dữ liệu.

1. DriverManager – Nạp các JDBC driver vào trong bộ nhớ. Có thể sử dụng nó để mở các kết nối tới một nguồn dữ liệu.

2. Connection – Biểu thị một kết nối đến một nguồn dữ liệu. Được dùng để tạo ra các đối tượng Statement, PreparedStatement và CallableStatement.
Statement – Biểu diễn một lệnh SQL tĩnh. Có thể sử dụng nó để thu về đối tượng ResultSet.

3. PreparedStatement – Một giải pháp thay thế hoạt động tốt hơn đối tượng Statement, thực thi một câu lệnh SQL đã được biên dịch trước.

4. CallableStatement – biểu diễn một thủ tục được lưu trữ. Có thể được sử dụng để thực thi các thủ tục được lưu trữ trong một RDBMS có hỗ trợ chúng.

5. ResultSet – biểu diễn một tập kết quả trong cơ sở dữ liệu tạo ra bởi việc sử dụng một câu lệnh SQL là SELECT.

  6. SQLException – một lớp xử lý lỗi ngoại lệ chứa các lỗi truy cập cơ sở dữ liệu.

Gói thứ hai, javax.sql là một bộ phận của J2SE 1.4 và J2EE 1.3. Nó bổ sung các tính năng sau đây vào JDBC để hỗ trợ thêm cho các tính năng đã có trong gói java.sql:

7. DataSource – Trừu tượng hóa một nguồn dữ liệu. Đối tượng này có thể sử dụng thế cho

8. DriverManager để tạo ra một cách có hiệu quả các kết nối cơ sở dữ liệu (có khả năng sử dụng việc chứa/phân chia các đường kết nối ngầm).
Tạo sẵn cơ chế phân chia đường kết nối (built-in connection pooling).

9. XADataSource, XAConnection – Cho phép/Hỗ trợ các giao dịch phân phối.
RowSet – Nó mở rộng giao diện ResultSet để tăng thêm sự hỗ trợ đối với các tập kết nối bị ngắt.

Có 4 loại JDBC driver. Thông dụng nhất và cũng là hiệu quả nhất là loại 4. Sau đây là mô tả:

JDBC Driver loại 1– Chúng là các trình điều khiển cầu nối JDBC-ODBC. Chúng ủy nhiệm công việc truy cập dữ liệu cho ODBC API. Chúng là trình điều khiển chậm nhất trong số còn lại. SUN cung cấp một phần mềm trình điều khiển JDBC/ODBC.

JDBC Driver loại 2 – Chúng chủ yếu sử dụng API mã nền để truy cập dữ liệu và cung cấp các lớp bao Java để có thể được gọi ra bằng cách dùng các JDBC driver.

JDBC Driver loại 3 – Chúng được viết thuần bằng Java và sử dụng giao thức Net độc lập nhà sản xuất để truy cập đến trình theo dõi từ xa độc lập nhà sản xuất. Trình theo dõi này đến lượt nó lại ánh xạ các lời gọi độc lập nhà sản xuất này vào các lời gọi phụ thuộc nhà sản xuất. Bước đặc biệt này đã làm tăng độ phức tạp và giảm tính hiệu quả trong truy cập cơ sở dữ liệu.

JDBC Driver loại 4 – Chúng được viết thuần túy bằng Java và là loại hiệu quả nhất. Chúng cho phép kết nối trực tiếp vào cơ sở dữ liệu, cung cấp kết quả tối ưu và cho phép lập trình viên thực hiện các chức năng tùy thuộc vào cơ sở dữ liệu cụ thể. Điều này đã tạo ra tính cơ động cao nhất là khi bạn cần thay đổi cơ sở dữ liệu bên dưới một ứng dụng. Loại driver này thường được dùng cho các ứng dụng phân tán cao.
SUN khuyến cáo sử dụng và phát triển các trình điều khiển loại 4 trong các ứng dụng .

Cài đặt MySQL

MySQL là hệ quản trị cơ sở dữ liệu mã nguồn mở phổ biến nhất thế giới và được các nhà phát triển rất ưa chuộng trong quá trình phát triển ứng dụng. MySQL miễn phí hoàn toàn nên bạn có thể tải về MySQL từ trang chủ www.mysql.com.

MySQL có nhiều phiên bản cho các hệ điều hành khác nhau: phiên bản Win32 cho các hệ điều hành dòng Windows, Linux, Mac OSX… Cài đặt Connector/J – JDBC Driver của MySQL JDBC Driver của MySQL có thể lấy về ở địa chỉ http://www.mysql.com/downloads/api-jdbc.html .

File bạn tải về sẽ là một file .zip hoặc .gz. Sau khi giải nén bạn sẽ có 1 file có tên tương tự như sau: mysql-connectorjava- 3.0.9-stable-bin.jar. Hãy chép file này vào thư mục %JAVA_HOME%/jre/lib/ext trên hệ thống của bạn. Ví dụ C:j2sdk1.4.2jrelibext.
Bạn cũng cần đưa đường dẫn đến file JAR này vào biến môi trường MYSQL_DRIVER của bạn.

javasun2

 

Sau khi bạn đã đặt đường dẫn đến Connector/J vào biến môi trường MYSQL_DRIVER thì bạn đã có thể yên tâm là JDBC driver của MySQL đã được cài đặt xong.

Kiểm tra xem Connector/J đã hoạt động chưa?

Chúng ta tạo ra một chương trình Java nhỏ để kiểm tra xem chúng ta đã cài đặt đúng JDBC driver của MySQL chưa. Nếu chương trình chạy thành công thì nghĩa là trình điều khiển JDBC đã sẵn sàng cho các tác vụ phức tạp hơn. Bạn hãy tạo ra một file Connect.java với đoạn mã sau:

import java.sql.*;
public class Connect{
public static void main (String[] args){

Connection conn = null;
try{
String userName = “root”;
String password = “localhost”;
String url = “jdbc:mysql://127.0.0.1:3306/mysql”;
Class.forName (“com.mysql.jdbc.Driver”).newInstance ();

conn = DriverManager.getConnection (url,userName, password);
System.out.println (“Da ket noi CSDL”);
}
catch (Exception e){
System.err.println (“KHONG KET NOI DUOC”);
}
finally{
if (conn != null){
try{
conn.close ();
System.out.println (“Dong ket noi”);
}
catch (Exception e) { /* bo qua loi luc dong csdl */ }
}
}
}
}
Trước hết bạn hãy biên dịch file này ra mã bytecode nhưng để chạy nó, bạn cần chú ý đảm bảo MySQL đang chạy trên máy tính cá nhân của bạn. Nếu bạn đã cài đặt MySQL để nó chỉ chạy khi bạn gọi thì bạn hãy bật MySQL với câu lệnh mysqld-nt –console hay nếu bạn đã cài chương trình quản trị cơ sở dữ liệu này dưới hình thức một dịch vụ thì bạn có thể gõ net start mysql trong shell Run trong Windows.

Đoạn mã trên sử dụng cặp tên người sử dụng và mật khẩu là root/localhost với cơ sở dữ liệu là mysql. Nếu kết nối thành công, bạn sẽ thấy một màn hình như dưới đây xuất hiện.

javasun4

Chương trình trên sử dụng TCP/IP để kết nối vào hệ cơ sở dữ liệu MySQL.

* Phân tích

Để kết nối và sử dụng một cơ sở dữ liệu từ Java applet, servlet hay ứng dụng Java thì chúng ta cần thực hiện qua 3 bước:

1. Đăng kí/Nạp (các) driver

2. Thiết lập kết nối đến cơ sở dữ liệu

3. Gửi câu lệnh SQL và xử lý kết quả thu về

Bước đầu tiên để tạo ra một kết nối giữa ứng dụng Java và một cơ sở dữ liệu là đăng kí một JDBC driver với máy ảo Java (JVM) mà ứng dụng Java chạy trên đó. Với cơ chế kết nối truyền thống (sẽ nói trong phần cơ chế kết nối DataSource, thảo luận sau), thì kết nối và tất cả các hình thức giao tiếp với cơ sở dữ liệu đều do đối tượng DriverManager kiểm soát. Để thiết lập một đường kết nối, một JDBC driver thích hợp dùng cho cơ sở dữ liệu mục tiêu phải được đăng kí với đối tượng DriverManager.

Đặc tả JDBC chỉ ra rằng các JDBC driver được xem là sẽ tự đăng kí với đối tượng DriverManager một cách tự động khi chúng được nạp vào một JVM. Ví dụ đoạn mã sau sử dụng một bộ khởi tạo tĩnh để lần đầu tiên tạo ra một mẫu của JDBC driver mang tên persistentjava và sau đó đăng kí nó với DriverManager.

static {
java.sql.DriverManager.registerDriver(new
com.persistentjava.JdbcDriver()) ;
}

Việc đăng kí một driver đơn giản chỉ là việc nạp lớp driver vào JVM. Chúng ta có thể làm điều đó bằng một số cách khác nhau. Một trong những cách đó là thông qua

ClassLoader Class.forName(com.persistentjava.JdbcDriver) ;.

Một cách khác, không phổ biến lắm là dùng thuộc tính hệ thống jdbc.drivers. Chúng ta có thể dùng cách này theo 3 hình thức khác nhau:

Từ dòng lệnh: java -Djdb.drivers =com.persistentjava.JdbcDriver Connect

* Bên trong ứng dụng java:

System.setProperty(“jdbc.drivers”, “com.persistentjava.JdbcDriver”) ;

* Bằng cách thiết lập thuộc tính jdbc.drivers vào file thuộc tính hệ thống, nhưng nhìn chung là lại tùy thuộc vào hệ thống Bằng phương pháp tách các driver bằng một dấu phẩy, chúng ta có thể đăng kí nhiều driver thông qua kĩ thuật thuộc tính hệ thống ở trên. Một trong các lợi ích của kĩ thuật này là ở chỗ các driver có thể đưa vào và ra khỏi JVM mà không cần thay đổi mã (hoặc chỉ cần thay đổi ở mức tối thiểu). Nếu đăng kí nhiều driver, thứ tự ưu tiên của chúng như sau:

1) Các JDBC driver do thuộc tính jdbc.drivers đăng kí lúc khởi tạo JVM, và

2)Các JDBC driver được nạp động. Do thuộc tính jdbc. drivers chỉ được kiểm tra một lần vào lần gọi đầu tiên của phương thức DriverManager(), nên quan trọng là bạn phải đảm bảo rằng tất cả các driver được đăng kí đúng trước khi thiết lập kết nối.
Chú ý là có một số JVMs không tuân thủ đặc tả JVM và kết quả là các bộ khởi tạo tĩnh không phải lúc nào cũng làm việc thống nhất như mong muốn. Điều này dẫn tới việc có nhiều cách đăng kí một JDBC driver:

· Class.forName(“com.persistentjava. JdbcDriver”).newInstance() ;
· DriverManager.registerDriver(new com.persistentjava.JdbcDriver()) ;

Hai cách trên thường hoạt động tốt trong tất cả các JVM nên bạn có thể sử dụng chúng một cách thoải mái. Nhưng điều khác biệt là Class.forName() có thể chặn bắt một ClassNotFoundException, nên bạn cần bao mã đăng kí driver vào một bộ xử lý lỗi ngoại lệ thích hợp.
Ví dụ:

 

try{
Class.forName (“com.mysql.jdbc.Driver”).newInstance ();
}
catch (Exception e){
System.err.println (“KHONG KET NOI DUOC”);
}

 
Các sách về MySQL khuyến cáo bạn nên dùng cách trên. Phương thức Class.forname() nhận một chuỗi làm đối số. Trong trường hợp bạn dùng JDBC Driver của hãng MySQL AB cho MySQL bản 4.0 trở lên thì chuỗi đó là:

com.mysql.jdbc.Driver

Cần chú ý là bạn không cần phải tạo ra một mẫu của driver và đăng kí nó với DriverManager vì việc gọi Class.forName() sẽ làm cho bạn điều đó một cách tự động.
Bước tiếp theo sau khi bạn đã đăng kí JDBC Driver là thực hiện kết nối. Toàn bộ công đoạn này được minh họa qua dòng mã sau:

Connection conn = DriverManager.getConnection(url, “myLogin”, “myPassword”);

Cách khác:
Connection conn;
conn = DriverManager.getConnection(url, “myLogin”, “myPassword”);

Đoạn mã trên rất tường minh. Phương thức getConnection() được gọi để thực hiện một kết nối thực sự đến phần mềm máy chủ cơ sở dữ liệu. Lớp DriverManager tạo ra một đối tượng Connection khi bạn gọi phương thức getConnection(). Phương thức này nhận một chuỗi URL làm đối số. Ví dụ, với MySQL thì chuỗi đó có thể là:

jdbc:mysql://127.0.0.1:3306/mysql hoặc jdbc:mysql://localhost/mydatabase

Chuỗi này tuân theo quy tắc sau đây: jdbc:: trong đó:
thường là driver hoặc cơ chế kết nối cơ sở dữ liệu

phụ thuộc vào , có thể thay đổi theo các nhà cung cấp driver mà nó có thể là mysql, db2, oracle hay odbc.
có thể chứa địa chỉ Internet cho các cơ sở dữ liệu ở xa. Phần này có thể gồm có tên host, mã số cổng, và tên của hệ thống cơ sở dữ liệu.

Chú ý: là trong một số sách khác, công thức trên còn trình bày dưới dạng: jdbc:sub-protocol:database locator tuy về bản chất thì không có gì thay đổi.

Nếu một trong các driver mà bạn cung cấp nhận ra địa chỉ JDBC URL mà bạn cung cấp cho phương thức DriverManager.getConnection, thì driver đó sẽ thiết lập đường kết nối đến MySQL xác định trong JDBC URL.

Lớp DriverManager sẽ quản lý tất cả các chi tiết của việc thiết lập đường kết nối bên dưới nên bạn không cần phải quan tâm gì thêm.

Đường kết nối do phương thức DriverManager.getConnection trả về là một đường kết nối mở mà bạn có thể sử dụng để thông qua các lệnh JDBC nhằm gửi các lệnh SQL tới MySQL. Ở đây chúng ta có đối tượng conn chứa kết nối mở và chúng ta sẽ sử dụng chúng để thực hiện các ví dụ thao tác trên MySQL.