text:
Trước khi bạn bắt đầu
Về loạt bài viết này
Chứng chỉ Nhà phát triển ứng dụng được IBM công nhận xác nhận với mọi người rằng bạn là một nhà phát triển ứng dụng DB2 cho Linux, UNIX và Windows mức trung cấp hoặc cao cấp và cho biết rằng bạn có các kỹ năng giỏi trong tất cả các công việc lập trình chung cũng như lập trình SQL nhúng, lập trình ODBC/CLI, lập trình .NET hoặc lập trình Java.
Loạt bài gồm chín hướng dẫn miễn phí này được thiết kế để giúp bạn chuẩn bị cho kỳ thi lấy chứng chỉ Phát triển ứng dụng DB2 9 cho Linux, UNIX và Windows (kỳ thi 733). Mỗi hướng dẫn bao gồm một liên kết đến một bản tải về dùng thử miễn phí DB2 9 cho Linux, UNIX và Windows. Các hướng dẫn này cung cấp một cơ sở vững chắc cho mỗi phần của kỳ thi. Tuy nhiên, bạn không nên dựa vào các hướng dẫn này như là sự chuẩn bị duy nhất của bạn cho kỳ thi này.
Về hướng dẫn này
Trong hướng dẫn này, bạn sẽ tìm hiểu về cách viết mã Java có giao diện với các cơ sở dữ liệu DB2. Bạn sẽ thấy làm thế nào để:
- Kết nối với một cơ sở dữ liệu DB2 từ một ứng dụng Java.
- Sử dụng JDBC để đọc và cập nhật dữ liệu trong một cơ sở dữ liệu DB2.
- Sử dụng SQL với Java (SQLJ) để đọc và cập nhật dữ liệu trong một cơ sở dữ liệu DB2.
- Xử lý lỗi một ứng dụng Java DB2.
Hướng dẫn này cung cấp cho bạn những kỹ năng cơ bản cần thiết để phát triển các ứng dụng Java cho DB2.
Các điều kiện cần trước
Để tham dự kỳ thi Phát triển ứng dụng Họ DB2 9, bạn đã phải vượt qua được kỳ thi cơ bản về họ DB2 9 (kỳ thi 730). Bạn có thể sử dụng Loạt bài hướng dẫn Cơ bản về họ DB2 (DB2 Family Fundamentals tutorial series) (xem phần Tài nguyên) để chuẩn bị cho kỳ thi đó. Đây là một loạt hướng dẫn rất phổ biến đã giúp cho nhiều người hiểu các vấn đề cơ bản về họ các sản phẩm DB2.
Mặc dù không phải tất cả các tư liệu được thảo luận trong loạt bài hướng dẫn Cơ bản về họ DB2 này là cần thiết để hiểu các khái niệm được mô tả trong hướng dẫn này, nhưng bạn cần phải có một kiến thức cơ sở về:
- Các cá thể DB2.
- Các cơ sở dữ liệu.
- Các đối tượng cơ sở dữ liệu.
- An ninh DB2.
Bạn cũng cần phải có kiến thức cơ sở về SQL và nền tảng Java trước khi bắt đầu tìm hiểu hướng dẫn này. Bạn có thể xem lại phần Tài nguyên ở phần cuối của hướng dẫn này để biết thêm thông tin.
Các yêu cầu hệ thống
Bạn không cần một bản sao của DB2 để hoàn thành hướng dẫn này. Tuy nhiên, bạn có thể tải về một bản DB2 Express-C miễn phí từ trang tải về DB2 Express-C.
Nếu bạn có kế hoạch phát triển các ứng dụng Java cho DB2 hoặc bạn có kế hoạch tự mình thử nghiệm mã mẫu của hướng dẫn này, bạn cần phải hoàn thành nhiệm vụ sau:
- Cài đặt DB2 9 cho Linux, UNIX và Windows.
- Tạo cơ sở dữ liệu mẫu. Bạn có thể làm điều này từ trình đơn Các
bước đầu tiên tạo cơ sở dữ liệu (First Steps Database Creation)
hoặc bằng cách chạy
db2sampltừ trình xử lý dòng lệnh DB2 (CLP- Command Line Processor). Mã mẫu trong bài viết này đã được viết để làm việc với cơ sở dữ liệu ấy.
- Cài đặt Môi trường thời gian chạy chạy Java, Ấn bản công nghệ Java 2, Phiên bản 1.4.2 (Java Runtime Environment , Java 2 Technology Edition Version 1.4.2).
- Cập nhật biến môi trường PATH để chứa thư mục jdk\bin của Java SDK mà bạn đã cài đặt. Lưu ý rằng DB2 bao gồm Phiên bản 5 của SDK Java, trong thư mục $DB2PATH\sqllib\java\jdk\bin ($DB2PATH/sqllib/java/jdk/bin trong UNIX hoặc Linux).
Các môi trường phát triển
Tổng quan
Có nhiều môi trường ở đó bạn có thể phát triển các ứng dụng Java của bạn để sử dụng với các cơ sở dữ liệu DB2. DB2 9.1 cung cấp hai tùy chọn:
- Bàn làm việc của nhà phát triển DB2 (DB2 Developer Workbench): Một môi trường phát triển có tích hợp đồ họa.
- Dòng lệnh DB2 (DB2 command line): Môi trường cốt lõi ở đó bạn có thể thi hành các lệnh hoặc các kịch bản lệnh để xây dựng và chạy các ứng dụng mà bạn đã viết bằng một trình soạn thảo văn bản.
Bàn làm việc của nhà phát triển DB2
Bàn làm việc của nhà phát triển DB2 là một môi trường phát triển dựa trên Eclipse có cung cấp các khả năng sau đây, ngoài cơ sở hạ tầng phát triển ứng dụng Java của Eclipse :
- Duyệt và tạo ra các đối tượng cơ sở dữ liệu.
- Tạo, chỉnh sửa, gỡ rối, triển khai và thử nghiệm các thủ tục SQL lưu sẵn và các hàm do người dùng định nghĩa.
- Phát triển các ứng dụng SQLJ.
- Tạo, chỉnh sửa và chạy các câu lệnh SQL.
- Tạo, chỉnh sửa và chạy các biểu thức Xquery.
Bàn làm việc của nhà phát triển DB2 có sẵn dưới dạng một bản tải về miễn phí (xem phần Tài nguyên).
Dòng lệnh DB2
Từ dòng lệnh DB2, bạn có thể xây dựng và chạy các ứng dụng cơ sở dữ
liệu Java của bạn bằng cách sử dụng các lệnh
javac,
java và
sqljcustomize. Các ví dụ trong hướng dẫn này
giải thích làm thế nào để xây dựng và chạy cả hai, các ứng dụng SQLJ
và các ứng dụng JDBC, từ dòng lệnh DB2.
Kết nối đến một cơ sở dữ liệu
Tổng quan
JDBC là một API Java mà thông qua nó các chương trình Java có thể kết nối với các cơ sở dữ liệu quan hệ và thi hành các câu lệnh SQL. Để cho phép các ứng dụng Java giao tiếp với các cơ sở dữ liệu của nó, DB2 có gồm chứa các trình điều khiển JDBC.
Trong phần này, bạn sẽ tìm hiểu làm thế nào để nạp các trình điều khiển JDBC thích hợp nhất cho ứng dụng của bạn và làm thế nào để kết nối với một cơ sở dữ liệu DB2.
Các trình điều khiển JDBC
Một trình điều khiển JDBC hoạt động như một giao diện giữa một chương trình JDBC và cơ sở dữ liệu. DB2 bao gồm hai trình điều khiển JDBC: trình điều khiển JDBC DB2 Kiểu 2 và trình điều khiển IBM DB2 cho JDBC và SQLJ.
- Trình điều khiển JDBC DB2 Kiểu 2: Còn được gọi là trình
điều khiển ứng dụng (app driver). Các ứng dụng Java sử dụng
trình điều khiển này phải chạy trên một máy khách DB2, thông qua
nó các yêu cầu JDBC chảy đến một máy chủ DB2. Trình điều khiển này
đã lạc hậu và bị loại khỏi DB2 9.1, và các bản phát hành trong
tương lai của DB2 sẽ không hỗ trợ hoặc gồm chứa trình điều khiển
này nữa. Chúng tôi đề nghị bạn sử dụng trình điều khiển IBM DB2
cho JDBC và SQLJ thay cho Trình điều khiển JDBC DB2 Kiểu 2.
Để nạp Trình điều khiển JDBC DB2 Kiểu 2, hãy gọi phương thức
Class.forName()có đối số là
COM.ibm.db2.jdbc.app.DB2Driver.
- Trình điều khiển JDBC DB2 cho JDBC và SQLJ: Nó cung cấp cả
hai kết nối Kiểu 2 và Kiểu 4. Bạn có thể sử dụng trình điều khiển
này cho cả applet lẫn các ứng dụng; nó được đề nghị là trình điều
khiển cho cả hai.
Để nạp Trình điều khiển JDBC DB2 cho JDBC và SQLJ, hãy gọi phương thức
Class.forName()có đối số
com.ibm.db2.jcc.DB2Driver.
Để sử dụng một trong các trình điều khiển JDBC này trong ứng dụng của bạn, bạn cần phải nhập khẩu các gói Java có chứa API JDBC:
import java.sql.*;
Tải về mã và các ứng dụng mẫu trong hướng dẫn này đã được thử nghiệm để làm việc với các trình điều khiển JDBC DB2 cho JDBC và SQLJ.
Tạo một kết nối cơ sở dữ liệu
Khi bạn đã nạp trình điều khiển JDBC thích hợp, bạn có thể kết nối với
một cơ sở dữ liệu từ ứng dụng JDBC của bạn. Trong các ứng dụng JDBC,
một đối tượng
Connection (kết nối) biểu
diễn một kết nối cơ sở dữ liệu. Từ một đối tượng
DriverManager (có sẵn để sử dụng sau khi trình điều khiển
JDBC đã được nạp), bạn có thể sử dụng phương thức
getConnection() để thu được một
Connection (kết nối). Trong ví dụ sau đây, Trình điều
khiển IBM DB2 cho JDBC và SQLJ được nạp và đối tượng
DriverManager tạo ra một kết nối cơ sở dữ
liệu Kiểu 2.
String url = "jdbc:db2:sample"; Class.forName("com.ibm.db2.jcc.DB2Driver"); Connection con = DriverManager.getConnection(url);
Với Trình điều khiển IBM DB2 cho JDBC và SQLJ, kiểu kết nối cơ sở dữ
liệu được xác định bởi URL được chuyển tới phương thức
DriverManager.getConnection(). Trong các URL
như dưới đây, có liệt kê một tên miền và số cổng của máy chủ cơ sở dữ
liệu, đối tượng
DriverManager tạo ra một
kết nối cơ sở dữ liệu Kiểu 4.
String url = "jdbc:db2:sample://localhost:5021";
Bạn cũng có thể tạo các đối tượng
Connection khi sử dụng giao diện
DataSource.Giao diện này được khuyến khích nếu bạn đang
viết mã sẽ được sử dụng với nhiều máy chủ cơ sở dữ liệu và các trình
điều khiển JDBC. Giao diện
DriverManager
không khả chuyển, vì nó đòi hỏi ứng dụng phải chỉ rõ URL của trình
điều khiển và tên lớp của trình điều khiển JDBC của một nhà cung cấp
cụ thể. Các đối tượng
DataSource có thể
được định nghĩa và được quản lý trên các hệ thống ở đó các ứng dụng
của bạn chạy, sử dụng một công cụ như WebSphere. Khi sử dụng một công
cụ như vậy, một quản trị viên gán tên lô gic cho các đối tượng
DataSource và đăng ký chúng trong một danh
mục của Java Naming and Directory Interface (JNDI - Giao diện thư mục
và đặt tên Java). Ứng dụng Java có sử dụng đối tượng
DataSource sau đó có thể gọi nó bằng tên
logic của nó và không cần bất kỳ thông tin nào về nguồn dữ liệu nằm
bên dưới.
Kết nối cơ sở dữ liệu: Mã mẫu
Ứng dụng mẫu trong phần này giải thích các khái niệm sau đây:
- Nhập khẩu các gói Java có chứa API JDBC.
- Nạp Trình điều khiển IBM DB2 cho JDBC và SQLJ.
- Tạo một đối tượng
Connection.
- Sử dụng
DriverManagerđể mở một
Connection.
Ứng dụng này là một trình vỏ (shell) của một ứng dụng JDBC điển hình --
các gói JDBC được nhập khẩu, có một kết nối cơ sở dữ liệu và có logic
xử lý lỗi trong các khối
try/
catch (thử/bắt giữ). Để chứng tỏ rằng một kết
nối cơ sở dữ liệu là thực sự được thực hiện, đối tượng
Connection yêu cầu tên của trình điều khiển
JDBC đang được sử dụng bằng cách dùng các phương thức
Connection.getMetaData().getDriverName().
//ConnDb.java import java.sql.*; class ConnDb { public static void main(String[] argv) { String url = "jdbc:db2:sample"; Connection con; try { Class.forName("com.ibm.db2.jcc.DB2Driver"); con = DriverManager.getConnection (url); System.out.println("JDBC driver name: " + con.getMetaData().getDriverName()); con.close(); } catch (ClassNotFoundException drvEx) { System.err.println("Could not load JDBC driver"); System.out.println("Exception: " + drvEx); drvEx.printStackTrace(); } catch(SQLException sqlEx) { while(sqlEx != null) { System.err.println("SQLException information"); System.err.println("Error msg: " + sqlEx.getMessage()); System.err.println("SQLSTATE: " + sqlEx.getSQLState()); System.err.println("Error code: " + sqlEx.getErrorCode()); sqlEx.printStackTrace(); sqlEx=sqlEx.getNextException(); } } } }
Để biên dịch tệp tin trên (có tên là ConnDb.java), hãy thi hành lệnh sau đây:
javac ConnDb.java
Để chạy ứng dụng đã biên dịch, hãy thi hành lệnh sau đây:
java ConnDb
Kết quả đầu ra của ứng dụng sẽ trông như sau:
JDBC driver name: IBM DB2 JDBC Universal Driver Architecture
Đọc và cập nhật dữ liệu với JDBC
Tổng quan
Trong phần này, bạn sẽ học cách sử dụng các đối tượng JDBC
Statement và
PreparedStatement như thế nào để biểu diễn các câu lệnh
SQL trong JDBC. Bạn cũng sẽ học cách làm thế nào để sử dụng đối tượng
JDBC
ResultSet, được trả về bởi các đối
tượng
Statement và
PreparedStatement có chứa các truy vấn SQL.
Đối tượng Statement
Các đối tượng
Statement được tạo ra bằng
cách sử dụng phương thức
Connection.createStatement(). Ví dụ:
Statement stmt; ... stmt = con.createStatement();
Để thi hành một câu lệnh
INSERT,
UPDATE hoặc
DELETE
từ một đối tượng
Statement, hãy chuyển một
chuỗi ký tự chứa câu lệnh đến phương thức
Statement.executeUpdate(). Ví dụ:
stmt.executeUpdate("DELETE FROM EMPLOYEE WHERE EMPNO = '000099'");
Để thi hành một truy vấn bằng cách sử dụng một đối tượng
Statement, hãy chuyển một chuỗi ký tự chứa
câu lệnh
SELECT đến phương thức
Statement.executeQuery() và lấy ra đối tượng
ResultSet. Ví dụ:
ResultSet rs; rs = stmt.executeQuery("SELECT EMPNO, LASTNAME FROM EMPLOYEE");
Để phân tích cú pháp một đối tượng
ResultSet, trước tiên bạn phải tìm nạp mỗi hàng bằng cách
sử dụng phương thức
ResultSet.next(). Sau
đó, sau mỗi lần tìm nạp, lấy ra các giá trị cột bằng cách sử dụng các
phương thức có thể áp dụng đối với kiểu dữ liệu tương ứng (ví dụ,
ResultSet.getInt()).
rs = stmt.executeQuery("SELECT LASTNAME, BIRTHDATE FROM EMPLOYEE"); while (rs.next()) { System.out.println(rs.getString(1) + ", " + rs.getDate(2)); }
Đối tượng Statement: Mã mẫu
Ứng dụng sau đây giải thích tất cả các khái niệm được thảo luận trong phần trên:
- Tạo một đối tượng
Statement.
- Thực hiện một câu lệnh
INSERT,
UPDATEhoặc
DELETE.
- Thực hiện một truy vấn SQL.
- Phân tích cú pháp một đối tượng
ResultSet.
Ứng dụng này chèn một bản ghi nhân viên vào trong bảng Nhân viên (Employee) và sau đó chạy một truy vấn đối với bảng đó, yêu cầu mã số và tên họ nhân viên của mỗi bản ghi.
//StmtDb.java import java.sql.*; class StmtDb { public static void main(String[] argv) { String url = "jdbc:db2:sample"; Connection con; Statement stmt1, stmt2; ResultSet rs; String stmt1String = "INSERT INTO EMPLOYEE (EMPNO,FIRSTNME,MIDINIT,LASTNAME,EDLEVEL)" + " VALUES ('000099','MICHIEL','G','DEROOS',1)"; String stmt2String = "SELECT EMPNO, LASTNAME FROM EMPLOYEE"; try { Class.forName("com.ibm.db2.jcc.DB2Driver"); con = DriverManager.getConnection(url); con.setAutoCommit(true); stmt1 = con.createStatement(); stmt2 = con.createStatement(); stmt1.executeUpdate(stmt1String); rs = stmt2.executeQuery(stmt2String); System.out.println("Employee # Employee surname"); while (rs.next()) { System.out.println(rs.getString(1) + " " + rs.getString(2)); } rs.close(); stmt1.close(); stmt2.close(); con.close(); } catch (ClassNotFoundException drvEx) { System.err.println("Could not load JDBC driver"); System.out.println("Exception: " + drvEx); drvEx.printStackTrace(); } catch(SQLException sqlEx) { while(sqlEx != null) { System.err.println("SQLException information"); System.err.println("Error msg: " + sqlEx.getMessage()); System.err.println("SQLSTATE: " + sqlEx.getSQLState()); System.err.println("Error code: " + sqlEx.getErrorCode()); sqlEx.printStackTrace(); sqlEx=sqlEx.getNextException(); } } } }
Để biên dịch tệp tin trên (có tên là StmtDb.java), hãy thi hành lệnh sau đây:
javac StmtDb.java
Để chạy các ứng dụng đã biên dịch, hãy thi hành lệnh sau đây:
java StmtDb
Kết quả đầu ra của ứng dụng này trông giống như sau:
Employee # Employee surname 000010 HAAS 000020 THOMPSON 000030 KWAN 000050 GEYER 000060 STERN 000070 PULASKI 000090 HENDERSON 000100 SPENSER 000110 LUCCHESSI 000120 O'CONNELL 000130 QUINTANA 000140 NICHOLLS 000150 ADAMSON 000160 PIANKA 000170 YOSHIMURA 000180 SCOUTTEN 000190 WALKER 000200 BROWN 000210 JONES 000220 LUTZ 000230 JEFFERSON 000240 MARINO 000250 SMITH 000260 JOHNSON 000270 PEREZ 000280 SCHNEIDER 000290 PARKER 000300 SMITH 000310 SETRIGHT 000320 MEHTA 000330 LEE 000340 GOUNOT 200010 HEMMINGER 200120 ORLANDO 200140 NATZ 200170 YAMAMOTO 200220 JOHN 200240 MONTEVERDE 200280 SCHWARTZ 200310 SPRINGER 200330 WONG 200340 ALONZO 000099 DEROOS
Đối tượng PreparedStatement
Các đối tượng
PreparedStatement được tạo ra
bằng cách sử dụng phương thức
Connection.prepareStatement(). Ví dụ:
PreparedStatement stmt; ... stmt = con.prepareStatement();
Với một đối tượng
PreparedStatement, bạn có
thể chuẩn bị và thi hành các câu lệnh SQL theo phương thức động. Bằng
cách liên kết lại các giá trị tới các dấu tham số trong các câu lệnh
SQL, bạn có thể thi hành cùng một câu lệnh nhiều lần bằng cách sử dụng
các giá trị khác nhau. (Một dấu tham số được biểu diễn bằng một dấu
hỏi
?, và hoạt động như một ký hiệu giữ chỗ
cho một giá trị sẽ được gán trong thời gian chạy). Ví dụ:
pStmt = con.prepareStatement("UPDATE STAFF SET COMM=? WHERE ID=?"); pStmt.setDouble(1,710.53); pStmt.setInt(2,350); pStmt.executeUpdate(); pStmt.setDouble(1,710.53); pStmt.setInt(2,350); pStmt.executeUpdate();
Để biết thêm về các dấu tham số, đọc bài viết thứ tám trong loạt bài này (xem phần Tài nguyên).
Đối tượng PreparedStatement: Mã mẫu
Ứng dụng dưới đây giải thích tất cả các khái niệm được thảo luận trong phần trên:
- Tạo một đối tượng
PreparedStatement.
- Sử dụng dấu tham số để gán các giá trị trong các câu lệnh SQL theo phương thức động.
Ứng dụng này phân tích một mảng các tên và chức danh công việc. Ứng với mỗi mục trong mảng, nó chèn thêm một bản ghi vào bảng nhân viên.
//pStmtDb.java import java.sql.*; class pStmtDb { public static void main(String[] argv) { String url = "jdbc:db2:sample"; Connection con; PreparedStatement pStmt; Statement sStmt; ResultSet rs; String stmtString = "INSERT INTO STAFF (ID,NAME,DEPT,JOB) VALUES (?,?,99,?)"; String [][] staff = {{"Smyth","LW"},{"Hemsky","RW"},{"Horcoff","C"}}; try { Class.forName("com.ibm.db2.jcc.DB2Driver"); con = DriverManager.getConnection(url); con.setAutoCommit(false); pStmt = con.prepareStatement(stmtString); for (int i=0; i<3; i++) { pStmt.setInt(1,401+i); pStmt.setString(2,staff[i][0]); pStmt.setString(3,staff[i][1]); pStmt.executeUpdate(); } con.commit(); sStmt = con.createStatement(); rs = sStmt.executeQuery("SELECT ID, NAME FROM STAFF WHERE DEPT = 99"); System.out.println("Employee # Employee surname"); while (rs.next()) { System.out.println(rs.getString(1) + " " + rs.getString(2)); } rs.close(); pStmt.close(); sStmt.close(); con.commit(); con.close(); } catch (ClassNotFoundException drvEx) { System.err.println("Could not load JDBC driver"); System.out.println("Exception: " + drvEx); drvEx.printStackTrace(); } catch(SQLException sqlEx) { while(sqlEx != null) { System.err.println("SQLException information"); System.err.println("Error msg: " + sqlEx.getMessage()); System.err.println("SQLSTATE: " + sqlEx.getSQLState()); System.err.println("Error code: " + sqlEx.getErrorCode()); sqlEx.printStackTrace(); sqlEx=sqlEx.getNextException(); } } } }
Để biên dịch tệp tin trên (có tên là pStmtDb.java), hãy thi hành lệnh sau đây:
javac pStmtDb.java
Để chạy các ứng dụng đã biên dịch, hãy thi hành lệnh sau đây:
java pStmtDb
Kết quả đầu ra của ứng dụng này sẽ giống như sau:
Employee # Employee surname 401 Smyth 402 Hemsky 403 Horcoff
Cam kết các giao dịch
Trong các mã ví dụ về
Statement và
PreparedStatement, hai cách tiếp cận khác
nhau để cam kết các giao dịch đã được sử dụng: cam kết tự động
(autocommit) và cam kết thủ công.
Cách tiếp cận được sử dụng trong ví dụ
Statement là cam kết tự động, ở đó mỗi câu lệnh đã được
cam kết tự động. Cam kết tự động được bật cho phép từ trong đối tượng
Connection, như sau:
con.setAutoCommit(true);
Không giống như các bản phát hành trước, ấn bản DB2 9 của trình điều
khiển IBM DB2 cho JDBC và SQLJ sẽ đưa ra một lỗi ngoại lệ nếu bạn thi
hành
Connection.Commit() hoặc
Connection.Rollback() khi chế độ tự động cam
kết được kích hoạt.
Cách tiếp cận được sử dụng trong ví dụ
PreparedStatement là cam kết thủ công. Với cách tiếp cận
này, từng câu lệnh hoặc là được cam kết thủ công hoặc được khôi phục
lại. Nếu khi kết thúc ứng dụng các câu lệnh không được giao kết, chúng
sẽ tự động khôi phục lại. Các hoạt động cam kết thủ công hoặc khôi
phục lại được thực hiện từ đối tượng
Connection, như sau:
con.commit(); ... con.rollback();
Phát ra các giao dịch phân tán
Để phát ra các giao dịch phân tán từ các ứng dụng Java của bạn, bạn cần phải sử dụng API các giao dịch Java (JTA - Java Transaction API). (Các giao dịch phân tán, còn được gọi là các giao dịch cam kết hai giai đoạn, là các giao dịch cập nhật dữ liệu trong nhiều hơn một cơ sở dữ liệu). Đặc tả kỹ thuật JTA là thành phần quản lý giao dịch của tiêu chuẩn Nền tảng Java 2, Ấn bản Doanh nghiệp (J2EE - Java 2 Platform, Enterprise Edition).
Trong DB2, các giao dịch phân tán được quản lý thông qua lớp
DB2XADataSource, lớp này triển khai thực hiện
giao diện
XADataSource từ gói
javax.sql.
Đối với DB2 9, sự hỗ trợ JTA được cung cấp ở cả hai trình điều khiển
IBM DB2 cho JDBC và SQLJ và trình điều khiển JDBC DB2 Kiểu 2. Mã Java
dưới đây tạo ra một cá thể của lớp
DB2XADataSource sử dụng trình điều khiển IBM DB2 cho JDBC
và SQLJ:
DB2XADataSource db2ds = new com.ibm.db2.jcc.DB2XADataSource();
Đọc và cập nhật dữ liệu với SQLJ
Tổng quan
API SQLJ là một phần mở rộng của JDBC và nó hỗ trợ thi hành tĩnh câu lệnh SQL. Bởi vì DB2 hỗ trợ SQLJ, các nhà phát triển Java có thể khắc phục một hạn chế chính của JDBC, cụ thể là JDBC chỉ có thể thi hành các câu lệnh SQL theo phương thức động. Các câu lệnh SQL liên kết tĩnh thường chạy nhanh hơn so với các câu lệnh liên kết động, chúng mang lại cho các ứng dụng SQLJ một lợi thế hiệu năng đáng kể so với các ứng dụng JDBC.
Trong phần này, bạn sẽ tìm hiểu làm thế nào để lập trình với API SQLJ bằng cách sử dụng bối cảnh kết nối, đưa ra các câu lệnh SQL trong các mệnh đề SQLJ có thể chạy được và phân tích cú pháp các bộ kết quả với các trình vòng lặp (iterator).
Các nhiệm vụ phát triển ứng dụng SQLJ
Khi bắt đầu một ứng dụng SQLJ, bạn cần phải nhập khẩu các gói Java có chứa các API JDBC và SQLJ:
import sqlj.runtime.*; import java.sql.*;
Các ứng dụng SQLJ sử dụng cùng các trình điều khiển JDBC được thảo luận trong phần JDBC drivers (các trình điều khiển JDBC).
Trước khi mã nguồn SQLJ có thể được biên dịch, nó cần phải được chuyển
thành mã Java để có thể được biên dịch bằng một trình biên dịch Java.
Lệnh
sqlj thực hiện phép chuyển đổi này và
cũng gọi trình biên dịch Java. Nếu bạn có các câu lệnh SQL trong tệp
tin nguồn SQLJ của bạn, một tệp tin với tên có phần cuối là
_SJProfile0.ser xuất hiện trong thư mục của
bạn cùng với tệp
class và tệp
sqlj.
Bạn có thể chạy mã nguồn của bạn một khi bạn đã dịch và đã biên dịch
nó. Tuy nhiên, các câu lệnh SQL trong ứng dụng của bạn sẽ không được
liên kết tĩnh, dẫn đến khả năng hiệu năng kém. Để liên kết tĩnh các
lệnh SQL trong ứng dụng của bạn, bạn cần phải thực hiện một tùy chỉnh
lược thảo của ứng dụng của bạn. Bạn có thể thực hiện tuỳ chỉnh này
bằng công cụ
db2sqljcustomize.
Để thực hiện việc tùy chỉnh lược thảo của một ứng dụng đã biên dịch, hãy thi hành lệnh sau đây:
db2sqljcustomize -url jdbc:db2://localhost:50000/sample -user uid -password pwd app_SJProfile0.ser
Trong lệnh này,
uid là mã nhận dạng ID của
người dùng của bạn,
pwd là mật khẩu của bạn
và
app là tên của ứng dụng của bạn.
Một số kết quả đầu ra mẫu từ việc chạy
db2sqljcustomize thành công được hiển thị bên dưới.
db2sqljcustomize -url jdbc:db2://localhost:50000/sample -user me -password mypwd DbApp_SJProfile0.ser [ibm][db2][jcc][sqlj] [ibm][db2][jcc][sqlj] Begin Customization [ibm][db2][jcc][sqlj] Loading profile: DbApp_SJProfile0 [ibm][db2][jcc][sqlj] Customization complete for profile DbApp_SJProfile0.ser [ibm][db2][jcc][sqlj] Begin Bind [ibm][db2][jcc][sqlj] Loading profile: DbApp_SJProfile0 [ibm][db2][jcc][sqlj] Driver defaults(user may override): BLOCKING ALL VALIDATE BIND STATICREADONLY YES [ibm][db2][jcc][sqlj] Fixed driver options: DATETIME ISO DYNAMICRULES BIND [ibm][db2][jcc][sqlj] Binding package DBAPP01 at isolation level UR [ibm][db2][jcc][sqlj] Binding package DBAPP02 at isolation level CS [ibm][db2][jcc][sqlj] Binding package DBAPP03 at isolation level RS [ibm][db2][jcc][sqlj] Binding package DBAPP04 at isolation level RR [ibm][db2][jcc][sqlj] Bind complete for DbApp_SJProfile0
Thiết lập một bối cảnh kết nối
Trong các ứng dụng SQLJ, các hoạt động SQL đòi hỏi một bối cảnh kết
nối thay cho một đối tượng
Connection JDBC.
Mỗi câu lệnh SQL được đưa ra thông qua các mệnh đề SQLJ
#sql và được gán rõ hoặc ngầm ẩn với một bối
cảnh kết nối. Việc gán một bối cảnh kết nối kết hợp câu lệnh với kết
nối cơ sở dữ liệu đã mở trước đó.
Trước khi thiết lập một kết nối cơ sở dữ liệu, đầu tiên bạn phải tạo
ra một lớp bối cảnh kết nối. Các dòng mã sau đây tạo ra một lớp bối
cảnh kết nối được đặt tên
Ctx:
#sql context Ctx;
Để thiết lập một kết nối cơ sở dữ liệu, hãy nạp một trình điều khiển
JDBC bằng cách sử dụng phương thức
Class.forName() và sau đó xây dựng một cá thể của lớp bối
cảnh mà bạn đã tạo ra trước đó. Ít nhất, bạn cần phải chuyển giao cho
hàm tạo bối cảnh URL của cơ sở dữ liệu và một giá trị kiểu boolean cho
biết bạn có muốn bật chế độ cam kết tự động hay không. Đoạn mã sau
thiết lập một kết nối cơ sở dữ liệu trong SQLJ:
String url = "jdbc:db2:sample"; Class.forName("com.ibm.db2.jcc.DB2Driver"); Ctx connCtx = new Ctx(url,true);
Trong bối cảnh kết nối ví dụ mẫu
connCtx
này, trình điều khiển IBM DB2 cho JDBC và SQLJ đang được sử dụng để
kết nối với cơ sở dữ liệu mẫu trên một máy chủ DB2 và chế độ cam kết
tự động được bật.
Đưa ra các câu lệnh SQL
Một lợi thế đáng kể của SQLJ so với nhiều API cơ sở dữ liệu khác (bao
gồm JDBC) là tính đơn giản và sức mạnh cú pháp của SQLJ. Ví dụ mã sau
giải thích một câu lệnh
UPDATE có sử dụng
một biến chủ:
String staffJob = "Sales"; #sql [connCtx] {UPDATE STAFF SET COMM=400 WHERE JOB = :staffJob};
Để viết các câu lệnh SQL trả về các bộ kết quả, bạn sẽ cần phải sử dụng iterators (các trình vòng lặp). Các trình vòng lặp được thảo luận sau này trong phần Use iterators (Sử dụng các trình vòng lặp).
Ứng dụng SQLJ cơ sở: Mã mẫu
Ứng dụng dưới đây giải thích tất cả những khái niệm được thảo luận cho đến nay trong phần này:
- Nhập khẩu các gói Java có chứa các API JDBC và SQLJ.
- Nạp Trình điều khiển IBM DB2 cho JDBC và SQLJ.
- Tạo một bối cảnh kết nối.
- Thi hành một lệnh SQL với một biến chủ.
Trong ứng dụng này, một câu lệnh
SELECT được
thi hành và kết quả vô hướng sẽ được chuyển tới một biến chủ có tên là
stname.
//DbApp.sqlj import sqlj.runtime.*; import java.sql.*; #sql context Ctx; class DbApp { public static void main(String[] argv) { String url = "jdbc:db2:sample"; String stname; try { Class.forName("com.ibm.db2.jcc.DB2Driver"); Ctx connCtx = new Ctx(url,true); #sql [connCtx] {SELECT NAME INTO :stname FROM STAFF WHERE ID=10}; System.out.println("The name of employee #10 is: " + stname); connCtx.close(); } catch (ClassNotFoundException drvEx) { System.err.println("Could not load JDBC driver"); System.out.println("Exception: " + drvEx); drvEx.printStackTrace(); } catch(SQLException sqlEx) { while(sqlEx != null) { System.err.println("SQLException information"); System.err.println("Error msg: " + sqlEx.getMessage()); System.err.println("SQLSTATE: " + sqlEx.getSQLState()); System.err.println("Error code: " + sqlEx.getErrorCode()); sqlEx.printStackTrace(); sqlEx=sqlEx.getNextException(); } } } }
Để dịch và biên dịch các tệp tin trên (có tên là DbApp.sqlj), hãy thi hành lệnh sau đây:
sqlj DbApp.sqlj
Để thực hiện một tùy chỉnh lược thảo của ứng dụng đã biên dịch này, hãy thi hành lệnh sau đây:
db2sqljcustomize -url jdbc:db2://localhost:50000/sample -user uid -password pwd DbApp_SJProfile0.ser
Trong lệnh này,
uid là ID của người dùng của
bạn
pwd là mật khẩu của bạn.
Để chạy các ứng dụng đã biên dịch, thi hành lệnh sau đây:
java DbApp
Kết quả đầu ra của ứng dụng này trông giống như sau:
The name of employee #10 is: Sanders
Sử dụng các trình vòng lặp
Để phân tích cú pháp các bộ kết quả trong các ứng dụng SQLJ, bạn cần phải sử dụng các trình vòng lặp. Các trình vòng lặp là phiên bản SQLJ của các con trỏ SQL. Có hai loại các trình vòng lặp chính mà bạn có thể sử dụng trong SQLJ: trình vòng lặp có tên và trình vòng lặp vị trí.
Các trình vòng lặp có tên
Các trình vòng lặp có tên được khai báo với các tên và các kiểu dữ liệu
của các cột trong tập kết quả. Với các trình vòng lặp có tên, thứ tự
các cột không quan trọng. Trước khi bạn có thể sử dụng một trình vòng
lặp có tên trong ứng dụng của bạn, bạn phải tạo ra một lớp trình vòng
lặp, lưu tâm đến bản chất của tập kết quả mà bạn muốn phân tích cú
pháp. Đoạn mã sau đây tạo ra một lớp trình vòng lặp có tên gọi là
NameIter; lớp trình vòng lặp có hai
cột.
#sql iterator NameIter(String Name, int Id);
Khi đưa ra một truy vấn SQL, bạn cần phải chuyển tập kết quả tới một cá thể của lớp trình vòng lặp mà bạn đã tạo ra. Ví dụ:
NameIter nIter; #sql [connCtx] nIter = {SELECT ID, NAME FROM STAFF WHERE DEPT = 20};
Để lấy ra các giá trị cột từ một trình vòng lặp có tên, bạn có thể sử
dụng các phương thức của trình vòng lặp được đặt tên theo các tên cột
trong tập kết quả. Để phân tích cú pháp trình vòng lặp có tên, bạn sử
dụng một cấu trúc vòng lặp; trước mỗi chu kỳ vòng lặp, hãy đi đến hàng
kế tiếp bằng cách chạy phương thức
iterator.next(). Đoạn mã sau phân tích cú pháp một cá thể
của một trình vòng lặp có tên là
NameIter.
while (nIter.next()) { System.out.println(nIter.Name() + ", ID #" + nIter.Id()); }
Các trình vòng lặp vị trí
Các trình vòng lặp vị trí chỉ được khai báo với các kiểu dữ liệu của
các cột trong tập kết quả. Với các trình vòng lặp vị trí, thứ tự các
cột rất quan trọng. Trước khi bạn có thể sử dụng một trình vòng lặp vị
trí trong ứng dụng của bạn, bạn phải tạo ra một lớp trình vòng lặp,
lưu tâm đến bản chất của tập kết quả mà bạn muốn phân tích cú pháp.
Đoạn mã sau đây tạo ra một lớp trình vòng lặp vị trí được gọi là
PosIter; lớp trình vòng lặp có hai cột.
#sql iterator PosIter(String, int);
Khi đưa ra một truy vấn SQL, hãy chuyển tập kết quả tới một cá thể của lớp trình vòng lặp mà bạn tạo ra. Ví dụ:
PosIter pIter; #sql [connCtx] pIter = {SELECT ID, NAME FROM STAFF WHERE DEPT = 20};
Để lấy ra các giá trị cột từ một trình vòng lặp vị trí, bạn cần phải
tìm nạp các giá trị đó vào các biến chủ. Sử dụng phương thức
iterator.endFetch() để xác định xem còn có
các hàng bổ sung để tìm nạp không. Đoạn mã sau phân tích cú pháp một
cá thể của trình vòng lặp vị trí
PosIter.
#sql {FETCH :pIter INTO :nameHv, :idHv }; while (!pIter.endFetch()) { System.out.println(nameHv + ", ID #" + idHv); #sql {FETCH :pIter INTO :nameHv, :idHv }; }
Các trình vòng lặp có tên và trình vòng lặp vị trí: Mã mẫu
Ứng dụng dưới đây giải thích tất cả những khái niệm được thảo luận trong phần trên:
- Tạo một trình vòng lặp có tên.
- Tạo một trình vòng lặp vị trí.
- Phân tích cú pháp một tập kết quả sử dụng một trình vòng lặp có tên.
- Phân tích cú pháp một tập kết quả sử dụng một trình vòng lặp vị trí.
Trong ứng dụng này, một câu lệnh
SELECT được
thực hiện hai lần. Tập kết quả từ lần thực hiện đầu tiên được phân
tích cú pháp với một trình vòng lặp có tên được gọi là
nIter. Tập kết quả từ lần thực hiện thứ hai
được phân tích cú pháp với một trình vòng lặp vị trí được gọi là
pIter.
//Iter.sqlj import sqlj.runtime.*; import java.sql.*; #sql context Ctx; #sql iterator NameIter(String Name, int Id); #sql iterator PosIter(String, int); class Iter { public static void main(String[] argv) { String url = "jdbc:db2:sample"; String nameHv = null; int idHv = 0; NameIter nIter; PosIter pIter; try { Class.forName("com.ibm.db2.jcc.DB2Driver"); Ctx connCtx = new Ctx(url,true); System.out.println("\nResult set from named iterator:"); #sql [connCtx] nIter = {SELECT ID, NAME FROM STAFF WHERE DEPT = 20}; while (nIter.next()) { System.out.println(nIter.Name() + ", ID #" + nIter.Id()); } nIter.close(); System.out.println("\nResult set from positional iterator:"); #sql [connCtx] pIter = {SELECT NAME, ID FROM STAFF WHERE DEPT = 20}; #sql {FETCH :pIter INTO :nameHv, :idHv }; while (!pIter.endFetch()) { System.out.println(nameHv + ", ID #" + idHv); #sql {FETCH :pIter INTO :nameHv, :idHv }; } pIter.close(); connCtx.close(); } catch (ClassNotFoundException drvEx) { System.err.println("Could not load JDBC driver"); System.out.println("Exception: " + drvEx); drvEx.printStackTrace(); } catch(SQLException sqlEx) { while(sqlEx != null) { System.err.println("SQLException information"); System.err.println("Error msg: " + sqlEx.getMessage()); System.err.println("SQLSTATE: " + sqlEx.getSQLState()); System.err.println("Error code: " + sqlEx.getErrorCode()); sqlEx.printStackTrace(); sqlEx=sqlEx.getNextException(); } } } }
Để dịch và biên dịch các tệp tin trên (có tên là Iter.sqlj), hãy thi hành lệnh sau đây:
sqlj Iter.sqlj
Để thực hiện một tùy chỉnh lược thảo của ứng dụng đã biên dịch này, hãy thi hành lệnh sau đây:
db2sqljcustomize -url jdbc:db2://localhost:50000/sample -user uid -password pwd Iter.ser
Trong lệnh này,
uid là mã nhận dạng ID của
người sử dụng của bạn và
pwd là mật khẩu
của bạn.
Để chạy ứng dụng đã biên dịch, hãy thi hành lệnh sau đây:
java Iter
Kết quả đầu ra của ứng dụng này sẽ giống như thế này:
Result set from named iterator: Sanders, ID #10 Pernal, ID #20 James, ID #80 Sneider, ID #190 Result set from positional iterator: Sanders, ID #10 Pernal, ID #20 James, ID #80 Sneider, ID #190
Xử lý lỗi
Tổng quan
Trong phần này, bạn học cách làm thế nào để sử dụng các công cụ xử lý lỗi có sẵn cho các ứng dụng JDBC. Bạn sẽ tìm thấy các thông tin sau:
- Xem xét cách làm thực tế để xử lý và báo lỗi cơ sở bằng cách
sử dụng các đối tượng
SQLException
- Sử dụng tiện ích lần theo vết JDBC.
- Thảo luận về bản ghi nhật ký lỗi của JDBC.
Việc xử lý lỗi
Để theo các cách làm thực tế để xử lý lỗi đúng đắn trong các chương
trình Java của bạn, bạn bao bọc logic trong các ứng dụng JDBC của bạn
trong các khối
try/
catch. Khi một lỗi xuất hiện trong các phương thức JDBC,
chúng sẽ đưa ra các đối tượng
SQLException.
Do vậy, với mỗi khối
try có chứa một hoạt
động JDBC, khối
catch tương ứng sẽ chứa
logic để xử lý một đối tượng
SQLException.
Ví dụ sau mô tả một câu lệnh
SELECT với các
toán hạng không tương thích về kiểu trong mệnh đề
WHERE: cột
JOB của bảng
STAFF là kiểu dữ liệu
VARCHAR, không phải
INTEGER.
try { ... rs = stmt.executeQuery("SELECT ID, NAME FROM STAFF WHERE JOB = 99"); ... } catch(SQLException sqlEx) { while(sqlEx != null) { System.err.println("SQLException information"); System.err.println("Error msg: " + sqlEx.getMessage()); System.err.println("SQLSTATE: " + sqlEx.getSQLState()); System.err.println("Error code: " + sqlEx.getErrorCode()); sqlEx=sqlEx.getNextException(); } }
Khối
catch có chứa một vòng lặp
while, nó tạo điều kiện cho việc xử lý nhiều
trường hợp lỗi ngoại lệ. Ở cuối vòng lặp, có một lời gọi phương thức
SQLException.getNextException(), trong
đó trả về một lỗi ngoại lệ nếu có một lỗi ngoại lệ khác để bắt giữ,
hoặc trả về null nếu không có các lỗi ngoại lệ nào thêm.
Câu lệnh
SELECT với các toán hạng không
tương thích tạo ra các lỗi ngoại lệ sau đây:
SQLException information Error msg: DB2 SQL error: SQLCODE: -401, SQLSTATE: 42818, SQLERRMC: = SQLSTATE: 42818 Error code: -401 SQLException information Error msg: DB2 SQL error: SQLCODE: -727, SQLSTATE: 56098, SQLERRMC: 2;-401;42818;= SQLSTATE: 56098 Error code: -727
Kết quả đầu ra này khác nhau, tùy thuộc vào trình điều khiển JDBC bạn đang sử dụng. Kết quả đầu ra ở trên đã được tạo ra bởi một ứng dụng sử dụng trình điều khiển IBM DB2 cho JDBC và SQLJ.
Tất cả các mã mẫu hoàn chỉnh được trình bày trong hướng dẫn này có
chứa logic để xử lý các đối tượng
SQLException.
Tiện ích lần theo vết của trình điều khiển IBM DB2 cho JDBC và SQLJ
Để gỡ rối các ứng dụng JDBC và SQLJ của bạn, bạn có thể dùng tiện ích theo dõi của trình điều khiển IBM DB2 cho JDBC và SQLJ. Cách tiếp cận được khuyến cáo cho việc thu thập dữ liệu theo vết là kích hoạt tiện ích theo vết bên ngoài ứng dụng của bạn bằng cách chỉnh sửa các thuộc tính trong tệp tin thuộc tính cấu hình của trình điều khiển IBM DB2 cho JDBC và SQLJ. Tuy nhiên, bạn cũng có thể kích hoạt tiện ích lần theo vết từ bên trong ứng dụng của bạn. Bạn có thể bật cho phép lần theo vết trong suốt thời gian chạy ứng dụng bằng cách chỉ rõ các tùy chọn lần theo vết khi bạn nạp trình điều khiển hoặc bạn có thể gọi rõ phương thức lần theo vết để bật và tắt việc lần theo vết trong các phần khác nhau của ứng dụng của bạn.
Để sử dụng tiện ích lần theo vết của trình điều khiển IBM DB2 cho JDBC và SQLJ bên ngoài ứng dụng của bạn, hãy thêm các dòng sau vào một tệp tin thuộc tính:
db2.jcc.traceDirectory=Trace db2.jcc.traceFile=extTrace db2.jcc.traceFileAppend=true
Nhằm phục vụ hướng dẫn này, các dòng này được thêm vào một tệp tin có
tên là tut-trace.properties, nằm trong cùng thư mục như các tệp tin
lớp được thử nghiệm. Như thuộc tính
traceDirectory đã xác nhận, tất cả các tệp tin lần theo
vết được ghi vào một thư mục con có tên là trace. Thư mục này phải tồn
tại dành cho các tệp tin theo dõi được ghi. Bằng cách chỉ rõ tệp tin
các thuộc tính tut-trace.properties trong lệnh
java, tiện ích lần theo vết thu thập thông tin về lớp
ConnDb.
java -Ddb2.jcc.propertiesFile=tut-trace.properties ConnDb
Để cho phép lần theo vết từ trong một ứng dụng, bạn có thể gắn thêm
các thuộc tính đặc thù cho việc theo vết vào sau tham số
url mà bạn sử dụng để nhận được kết nối cơ sở
dữ liệu. Ví dụ:
String url = "jdbc:db2:sample:traceFile=Trace/intTrace.txt;traceLevel=" + (com.ibm.db2.jcc.DB2BaseDataSource.TRACE_DRDA_FLOWS | com.ibm.db2.jcc.DB2BaseDataSource.TRACE_CONNECTS) + ";";
Trong ví dụ này, thông tin theo vết được viết vào một tệp tin có tên là intTrace.txt trong thư mục con Trace.
Để bật và tắt việc theo vết trong một ứng dụng bằng cách sử dụng một
DriverManager, bạn chỉ rõ
traceLevel trong
tham số
url mà bạn sử dụng để nhận được một
kết nối cơ sở dữ liệu và tên tệp tin (filename) và đường dẫn trong
phương thức
DriverManager.setLogWriter. Ví
dụ:
... String url = "jdbc:db2:sample:traceLevel=" + (com.ibm.db2.jcc.DB2BaseDataSource.TRACE_DRDA_FLOWS | com.ibm.db2.jcc.DB2BaseDataSource.TRACE_CONNECTS) + ";"; ... //turn on trace ((com.ibm.db2.jcc.DB2Connection) con).setJccLogWriter(printWriter, com.ibm.db2.jcc.DB2BaseDataSource.TRACE_ALL); ... //database activity ... //turn off trace ((com.ibm.db2.jcc.DB2Connection) con).setJccLogWriter(null);
Giám sát hiệu năng
Trình điều khiển IBM DB2 cho JDBC và SQLJ bao gồm một giao diện
DB2SystemMonitor, nó cho phép bạn thu thập
thông tin sau đây về ứng dụng của bạn:
- Thời gian của trình điều khiển lõi: Tổng số thời gian của API được giám sát đã trôi qua.
- Thời gian I/O của mạng: Tổng số thời gian của I/O được giám sát đã trôi qua.
- Thời gian của máy chủ: Tổng số thời gian đã trôi qua của tất cả máy chủ DB2 được báo cáo.
- Thời gian ứng dụng: Tổng số thời gian đã trôi qua của máy chủ DB2, I/O của mạng, trình điều khiển JDBC và ứng dụng.
Tất cả thời gian đã thu thập được tính bằng microgiây.
Đoạn mã dưới đây giải thích cách để tạo ra một giao diện
DB2SystemMonitor và thu thập và lấy ra dữ
liệu giám sát về ứng dụng:
... com.ibm.db2.jcc.DB2SystemMonitor systemMonitor = ((com.ibm.db2.jcc.DB2Connection)con).getDB2SystemMonitor(); systemMonitor.enable(true); //reset all counters systemMonitor.start(com.ibm.db2.jcc.DB2SystemMonitor.RESET_TIMES); ... //database activity ... systemMonitor.stop(); System.out.println("Server elapsed time = " + systemMonitor.getServerTimeMicros());
Kết luận
Tóm tắt
Hướng dẫn này cung cấp một giới thiệu nhập môn về các khái niệm lập trình cơ sở dữ liệu Java mà bạn sẽ được kiểm tra trong kỳ thi lấy chứng chỉ phát triển ứng dụng Họ DB2 9 (kỳ thi 733). Để củng cố các ý tưởng được trình bày trong mỗi phần của hướng dẫn, hãy làm nhiều hơn là chỉ đơn giản biên dịch và chạy các mã ví dụ mẫu. Hãy thực hiện các sửa đổi và cải tiến riêng của bạn.
Để tập trung vào loạt bài này, hãy đánh dấu trang của loạt bài DB2 9 application development exam 733 prep tutorials (các hướng dẫn chuẩn bị cho kỳ thi 733 về phát triển ứng dụng DB2 9).
Tài nguyên
Học tập
- DB2 9 Application Development exam 733 prep tutorial series: Xem
các phần khác của loạt bài hướng dẫn này. Các hướng dẫn trong loạt này bao
gồm:
- Các đối tượng cơ sở dữ liệu và các phương pháp lập trình.
- Thao tác dữ liệu.
- Thao tác dữ liệu XML.
- Lập trình SQL nhúng.
- Lập trình ODBC/CLI.
- Lập trình .NET.
- Lập trình Java.
- Lập trình nâng cao.
- Các thường trình do người dùng định nghĩa.
- DB2 9 Fundamentals certification prep tutorial series: Trước khi
bạn tham dự kỳ thi lấy chứng chỉ Phát triển ứng dụng DB2 9 (kỳ thi 733),
bạn phải tham dự và vượt qua kỳ thi lấy chứng chỉ cơ sở DB2 9 (kỳ thi
730). Sử dụng loạt bài gồm bảy hướng dẫn này để chuẩn bị cho kỳ thi đó;
các chủ đề bao gồm:
- Lập kế hoạch DB2.
- An ninh DB2.
- Truy cập dữ liệu DB2.
- Làm việc với dữ liệu DB2.
- Làm việc với các đối tượng DB2.
- Tương tranh dữ liệu.
- Giới thiệu Xquery.
- developerWorks resource page for DB2 for Linux, UNIX, and Windows: Tìm các bài viết và các hướng dẫn và kết nối đến các tài nguyên khác để mở rộng các kỹ năng DB2 của bạn.
- Trung tâm Thông tin DB2 9: Tìm hiểu thêm về phát triển ứng dụng DB2.
- Để biết thêm thông tin về cấp chứng chỉ
phát triển ứng dụng DB2 9 cho Linux, UNIX và Windows (kỳ thi 733), hãy xem
các đường liên kết sau:
- Thông tin về đào tạo quản lý thông tin
- Thông tin chung về chứng chỉ: bao gồm đề xuất về sách, các mục tiêu của kỳ thi và các khóa học.
- Trang Web kỳ thi cấp chứng chỉ: Nhấn vào số hiệu bài thi để xem nhiều thông tin hơn về Các kỳ thi 730 và 731.
- Các liên kết sau đây cung cấp thêm thông tin về việc phát triển các ứng dụng Java cho các cơ sở dữ liệu DB2:
- Tìm hiểu về DB2 Express-C: phiên bản miễn phí của Ấn bản DB2 Express cho cộng đồng.
- Theo sát với các sự kiện kỹ thuật và Webcasts của developerWorks.
- developerWorks Information Management zone: Tìm hiểu thêm về DB2. Tìm kiếm tài liệu hướng dẫn kỹ thuật, các bài báo hướng dẫn, đào tạo, tải về, thông tin sản phẩm và nhiều hơn nữa.
Lấy sản phẩm và công nghệ
- Tải về một phiên bản dùng thử miễn phí DB2 Enterprise 9.
- DB2 Express-C: Bây giờ bạn có thể sử dụng DB2 miễn phí. Tải xuống phiên bản miễn phí của DB2 Express, Ấn bản cho cộng đồng có cung cấp cùng các tính năng cốt lõi như Ấn bản DB2 Express và cung cấp một cơ sở vững chắc để xây dựng và triển khai các ứng dụng.
- DB2 Developer Workbench: Tải về sản phẩm miễn phí này.
- Xây dựng dự án phát triển tiếp theo của bạn với Phần mềm dùng thử của IBM, có sẵn để tải về trực tiếp từ developerWorks.
Thảo luận
- Tham gia vào các blog của DeveloperWorks và dành hết tâm trí cho cộng đồng developerWorks.
Bình luận
-
Vùng dữ liệu trên developerWorks
Khám phá các bài viết xoay quanh lĩnh vực dữ liệu, Quản lý hệ thống thông tin
-
Vùng mã nguồn mở trên developerWorks
Xem các bài viết về HTML, CSS, JavaScript,...
-
Điện toán đám mây
Tìm hiểu về điện toán đám mây

markdown:
## Trước khi bạn bắt đầu
### Về loạt bài viết này
Chứng chỉ Nhà phát triển ứng dụng được IBM công nhận xác nhận với mọi người rằng bạn là một nhà phát triển ứng dụng DB2 cho Linux, UNIX và Windows mức trung cấp hoặc cao cấp và cho biết rằng bạn có các kỹ năng giỏi trong tất cả các công việc lập trình chung cũng như lập trình SQL nhúng, lập trình ODBC/CLI, lập trình .NET hoặc lập trình Java.
[Loạt bài gồm chín hướng dẫn miễn phí](http://www.ibm.com/developerworks/offers/lp/db2cert/db2-cert733.html?S_TACT=105AGX11&S_CMP=db2certseries) này được thiết kế để
giúp bạn chuẩn bị cho kỳ thi lấy chứng chỉ Phát triển ứng dụng DB2 9
cho Linux, UNIX và Windows (kỳ thi 733). Mỗi hướng dẫn bao gồm một
liên kết đến một bản tải về dùng thử miễn phí DB2 9 cho Linux, UNIX và
Windows. Các hướng dẫn này cung cấp một cơ sở vững chắc cho mỗi phần
của kỳ thi. Tuy nhiên, bạn không nên dựa vào các hướng dẫn này như là
sự chuẩn bị duy nhất của bạn cho kỳ thi này.
### Về hướng dẫn này
Trong hướng dẫn này, bạn sẽ tìm hiểu về cách viết mã Java có giao diện với các cơ sở dữ liệu DB2. Bạn sẽ thấy làm thế nào để:
- Kết nối với một cơ sở dữ liệu DB2 từ một ứng dụng Java.
- Sử dụng JDBC để đọc và cập nhật dữ liệu trong một cơ sở dữ liệu DB2.
- Sử dụng SQL với Java (SQLJ) để đọc và cập nhật dữ liệu trong một cơ sở dữ liệu DB2.
- Xử lý lỗi một ứng dụng Java DB2.
Hướng dẫn này cung cấp cho bạn những kỹ năng cơ bản cần thiết để phát triển các ứng dụng Java cho DB2.
### Các điều kiện cần trước
Để tham dự kỳ thi Phát triển ứng dụng Họ DB2 9, bạn đã phải vượt qua
được kỳ thi cơ bản về họ DB2 9 (kỳ thi 730). Bạn có thể sử dụng Loạt
bài hướng dẫn Cơ bản về họ DB2 (DB2 Family Fundamentals tutorial
series) (xem phần
[Tài nguyên](#resources)) để chuẩn bị
cho kỳ thi đó. Đây là một loạt hướng dẫn rất phổ biến đã giúp cho
nhiều người hiểu các vấn đề cơ bản về họ các sản phẩm DB2.
Mặc dù không phải tất cả các tư liệu được thảo luận trong loạt bài hướng dẫn Cơ bản về họ DB2 này là cần thiết để hiểu các khái niệm được mô tả trong hướng dẫn này, nhưng bạn cần phải có một kiến thức cơ sở về:
- Các cá thể DB2.
- Các cơ sở dữ liệu.
- Các đối tượng cơ sở dữ liệu.
- An ninh DB2.
Bạn cũng cần phải có kiến thức cơ sở về SQL và nền tảng Java trước khi bắt đầu tìm hiểu hướng dẫn này. Bạn có thể xem lại phần Tài nguyên ở phần cuối của hướng dẫn này để biết thêm thông tin.
### Các yêu cầu hệ thống
Bạn không cần một bản sao của DB2 để hoàn thành hướng dẫn này. Tuy
nhiên, bạn có thể tải về một bản DB2 Express-C miễn phí từ
[trang tải về DB2 Express-C](http://www.ibm.com/software/data/db2/express/download.html).
Nếu bạn có kế hoạch phát triển các ứng dụng Java cho DB2 hoặc bạn có kế hoạch tự mình thử nghiệm mã mẫu của hướng dẫn này, bạn cần phải hoàn thành nhiệm vụ sau:
- Cài đặt DB2 9 cho Linux, UNIX và Windows.
- Tạo cơ sở dữ liệu mẫu. Bạn có thể làm điều này từ trình đơn Các
bước đầu tiên tạo cơ sở dữ liệu (First Steps Database Creation)
hoặc bằng cách chạy
db2sampltừ trình xử lý dòng lệnh DB2 (CLP- Command Line Processor). Mã mẫu trong bài viết này đã được viết để làm việc với cơ sở dữ liệu ấy.
- Cài đặt Môi trường thời gian chạy chạy Java, Ấn bản công nghệ Java 2, Phiên bản 1.4.2 (Java Runtime Environment , Java 2 Technology Edition Version 1.4.2).
- Cập nhật biến môi trường PATH để chứa thư mục jdk\bin của Java SDK mà bạn đã cài đặt. Lưu ý rằng DB2 bao gồm Phiên bản 5 của SDK Java, trong thư mục $DB2PATH\sqllib\java\jdk\bin ($DB2PATH/sqllib/java/jdk/bin trong UNIX hoặc Linux).
## Các môi trường phát triển
### Tổng quan
Có nhiều môi trường ở đó bạn có thể phát triển các ứng dụng Java của bạn để sử dụng với các cơ sở dữ liệu DB2. DB2 9.1 cung cấp hai tùy chọn:
**Bàn làm việc của nhà phát triển DB2 (DB2 Developer Workbench)**: Một môi trường phát triển có tích hợp đồ họa. **Dòng lệnh DB2 (DB2 command line)**: Môi trường cốt lõi ở đó bạn có thể thi hành các lệnh hoặc các kịch bản lệnh để xây dựng và chạy các ứng dụng mà bạn đã viết bằng một trình soạn thảo văn bản.
### Bàn làm việc của nhà phát triển DB2
Bàn làm việc của nhà phát triển DB2 là một môi trường phát triển dựa trên Eclipse có cung cấp các khả năng sau đây, ngoài cơ sở hạ tầng phát triển ứng dụng Java của Eclipse :
- Duyệt và tạo ra các đối tượng cơ sở dữ liệu.
- Tạo, chỉnh sửa, gỡ rối, triển khai và thử nghiệm các thủ tục SQL lưu sẵn và các hàm do người dùng định nghĩa.
- Phát triển các ứng dụng SQLJ.
- Tạo, chỉnh sửa và chạy các câu lệnh SQL.
- Tạo, chỉnh sửa và chạy các biểu thức Xquery.
Bàn làm việc của nhà phát triển DB2 có sẵn dưới dạng một bản tải về
miễn phí (xem phần
[Tài nguyên](#resources)).
### Dòng lệnh DB2
Từ dòng lệnh DB2, bạn có thể xây dựng và chạy các ứng dụng cơ sở dữ
liệu Java của bạn bằng cách sử dụng các lệnh
javac,
java và
sqljcustomize. Các ví dụ trong hướng dẫn này
giải thích làm thế nào để xây dựng và chạy cả hai, các ứng dụng SQLJ
và các ứng dụng JDBC, từ dòng lệnh DB2.
## Kết nối đến một cơ sở dữ liệu
### Tổng quan
JDBC là một API Java mà thông qua nó các chương trình Java có thể kết nối với các cơ sở dữ liệu quan hệ và thi hành các câu lệnh SQL. Để cho phép các ứng dụng Java giao tiếp với các cơ sở dữ liệu của nó, DB2 có gồm chứa các trình điều khiển JDBC.
Trong phần này, bạn sẽ tìm hiểu làm thế nào để nạp các trình điều khiển JDBC thích hợp nhất cho ứng dụng của bạn và làm thế nào để kết nối với một cơ sở dữ liệu DB2.
### Các trình điều khiển JDBC
Một trình điều khiển JDBC hoạt động như một giao diện giữa một chương trình JDBC và cơ sở dữ liệu. DB2 bao gồm hai trình điều khiển JDBC: trình điều khiển JDBC DB2 Kiểu 2 và trình điều khiển IBM DB2 cho JDBC và SQLJ.
**Trình điều khiển JDBC DB2 Kiểu 2**: Còn được gọi là trình điều khiển ứng dụng ( *app driver*). Các ứng dụng Java sử dụng trình điều khiển này phải chạy trên một máy khách DB2, thông qua nó các yêu cầu JDBC chảy đến một máy chủ DB2. Trình điều khiển này đã lạc hậu và bị loại khỏi DB2 9.1, và các bản phát hành trong tương lai của DB2 sẽ không hỗ trợ hoặc gồm chứa trình điều khiển này nữa. Chúng tôi đề nghị bạn sử dụng trình điều khiển IBM DB2 cho JDBC và SQLJ thay cho Trình điều khiển JDBC DB2 Kiểu 2.
Để nạp Trình điều khiển JDBC DB2 Kiểu 2, hãy gọi phương thức
Class.forName()có đối số là
COM.ibm.db2.jdbc.app.DB2Driver.
**Trình điều khiển JDBC DB2 cho JDBC và SQLJ**: Nó cung cấp cả hai kết nối Kiểu 2 và Kiểu 4. Bạn có thể sử dụng trình điều khiển này cho cả applet lẫn các ứng dụng; nó được đề nghị là trình điều khiển cho cả hai.
Để nạp Trình điều khiển JDBC DB2 cho JDBC và SQLJ, hãy gọi phương thức
Class.forName()có đối số
com.ibm.db2.jcc.DB2Driver.
Để sử dụng một trong các trình điều khiển JDBC này trong ứng dụng của bạn, bạn cần phải nhập khẩu các gói Java có chứa API JDBC:
import java.sql.*;
Tải về mã và các ứng dụng mẫu trong hướng dẫn này đã được thử nghiệm để làm việc với các trình điều khiển JDBC DB2 cho JDBC và SQLJ.
### Tạo một kết nối cơ sở dữ liệu
Khi bạn đã nạp trình điều khiển JDBC thích hợp, bạn có thể kết nối với
một cơ sở dữ liệu từ ứng dụng JDBC của bạn. Trong các ứng dụng JDBC,
một đối tượng
Connection (kết nối) biểu
diễn một kết nối cơ sở dữ liệu. Từ một đối tượng
DriverManager (có sẵn để sử dụng sau khi trình điều khiển
JDBC đã được nạp), bạn có thể sử dụng phương thức
getConnection() để thu được một
Connection (kết nối). Trong ví dụ sau đây, Trình điều
khiển IBM DB2 cho JDBC và SQLJ được nạp và đối tượng
DriverManager tạo ra một kết nối cơ sở dữ
liệu Kiểu 2.
String url = "jdbc:db2:sample"; Class.forName("com.ibm.db2.jcc.DB2Driver"); Connection con = DriverManager.getConnection(url);
Với Trình điều khiển IBM DB2 cho JDBC và SQLJ, kiểu kết nối cơ sở dữ
liệu được xác định bởi URL được chuyển tới phương thức
DriverManager.getConnection(). Trong các URL
như dưới đây, có liệt kê một tên miền và số cổng của máy chủ cơ sở dữ
liệu, đối tượng
DriverManager tạo ra một
kết nối cơ sở dữ liệu Kiểu 4.
String url = "jdbc:db2:sample://localhost:5021";
Bạn cũng có thể tạo các đối tượng
Connection khi sử dụng giao diện
DataSource.Giao diện này được khuyến khích nếu bạn đang
viết mã sẽ được sử dụng với nhiều máy chủ cơ sở dữ liệu và các trình
điều khiển JDBC. Giao diện
DriverManager
không khả chuyển, vì nó đòi hỏi ứng dụng phải chỉ rõ URL của trình
điều khiển và tên lớp của trình điều khiển JDBC của một nhà cung cấp
cụ thể. Các đối tượng
DataSource có thể
được định nghĩa và được quản lý trên các hệ thống ở đó các ứng dụng
của bạn chạy, sử dụng một công cụ như WebSphere. Khi sử dụng một công
cụ như vậy, một quản trị viên gán tên lô gic cho các đối tượng
DataSource và đăng ký chúng trong một danh
mục của Java Naming and Directory Interface (JNDI - Giao diện thư mục
và đặt tên Java). Ứng dụng Java có sử dụng đối tượng
DataSource sau đó có thể gọi nó bằng tên
logic của nó và không cần bất kỳ thông tin nào về nguồn dữ liệu nằm
bên dưới.
### Kết nối cơ sở dữ liệu: Mã mẫu
Ứng dụng mẫu trong phần này giải thích các khái niệm sau đây:
- Nhập khẩu các gói Java có chứa API JDBC.
- Nạp Trình điều khiển IBM DB2 cho JDBC và SQLJ.
- Tạo một đối tượng
Connection.
- Sử dụng
DriverManagerđể mở một
Connection.
Ứng dụng này là một trình vỏ (shell) của một ứng dụng JDBC điển hình --
các gói JDBC được nhập khẩu, có một kết nối cơ sở dữ liệu và có logic
xử lý lỗi trong các khối
try/
catch (thử/bắt giữ). Để chứng tỏ rằng một kết
nối cơ sở dữ liệu là thực sự được thực hiện, đối tượng
Connection yêu cầu tên của trình điều khiển
JDBC đang được sử dụng bằng cách dùng các phương thức
Connection.getMetaData().getDriverName().
//ConnDb.java import java.sql.*; class ConnDb { public static void main(String[] argv) { String url = "jdbc:db2:sample"; Connection con; try { Class.forName("com.ibm.db2.jcc.DB2Driver"); con = DriverManager.getConnection (url); System.out.println("JDBC driver name: " + con.getMetaData().getDriverName()); con.close(); } catch (ClassNotFoundException drvEx) { System.err.println("Could not load JDBC driver"); System.out.println("Exception: " + drvEx); drvEx.printStackTrace(); } catch(SQLException sqlEx) { while(sqlEx != null) { System.err.println("SQLException information"); System.err.println("Error msg: " + sqlEx.getMessage()); System.err.println("SQLSTATE: " + sqlEx.getSQLState()); System.err.println("Error code: " + sqlEx.getErrorCode()); sqlEx.printStackTrace(); sqlEx=sqlEx.getNextException(); } } } }
Để biên dịch tệp tin trên (có tên là ConnDb.java), hãy thi hành lệnh sau đây:
javac ConnDb.java
Để chạy ứng dụng đã biên dịch, hãy thi hành lệnh sau đây:
java ConnDb
Kết quả đầu ra của ứng dụng sẽ trông như sau:
JDBC driver name: IBM DB2 JDBC Universal Driver Architecture
## Đọc và cập nhật dữ liệu với JDBC
### Tổng quan
Trong phần này, bạn sẽ học cách sử dụng các đối tượng JDBC
Statement và
PreparedStatement như thế nào để biểu diễn các câu lệnh
SQL trong JDBC. Bạn cũng sẽ học cách làm thế nào để sử dụng đối tượng
JDBC
ResultSet, được trả về bởi các đối
tượng
Statement và
PreparedStatement có chứa các truy vấn SQL.
### Đối tượng Statement
Các đối tượng
Statement được tạo ra bằng
cách sử dụng phương thức
Connection.createStatement(). Ví dụ:
Statement stmt; ... stmt = con.createStatement();
Để thi hành một câu lệnh
INSERT,
UPDATE hoặc
DELETE
từ một đối tượng
Statement, hãy chuyển một
chuỗi ký tự chứa câu lệnh đến phương thức
Statement.executeUpdate(). Ví dụ:
stmt.executeUpdate("DELETE FROM EMPLOYEE WHERE EMPNO = '000099'");
Để thi hành một truy vấn bằng cách sử dụng một đối tượng
Statement, hãy chuyển một chuỗi ký tự chứa
câu lệnh
SELECT đến phương thức
Statement.executeQuery() và lấy ra đối tượng
ResultSet. Ví dụ:
ResultSet rs; rs = stmt.executeQuery("SELECT EMPNO, LASTNAME FROM EMPLOYEE");
Để phân tích cú pháp một đối tượng
ResultSet, trước tiên bạn phải tìm nạp mỗi hàng bằng cách
sử dụng phương thức
ResultSet.next(). Sau
đó, sau mỗi lần tìm nạp, lấy ra các giá trị cột bằng cách sử dụng các
phương thức có thể áp dụng đối với kiểu dữ liệu tương ứng (ví dụ,
ResultSet.getInt()).
rs = stmt.executeQuery("SELECT LASTNAME, BIRTHDATE FROM EMPLOYEE"); while (rs.next()) { System.out.println(rs.getString(1) + ", " + rs.getDate(2)); }
### Đối tượng Statement: Mã mẫu
Ứng dụng sau đây giải thích tất cả các khái niệm được thảo luận trong phần trên:
- Tạo một đối tượng
Statement.
- Thực hiện một câu lệnh
INSERT,
UPDATEhoặc
DELETE.
- Thực hiện một truy vấn SQL.
- Phân tích cú pháp một đối tượng
ResultSet.
Ứng dụng này chèn một bản ghi nhân viên vào trong bảng Nhân viên (Employee) và sau đó chạy một truy vấn đối với bảng đó, yêu cầu mã số và tên họ nhân viên của mỗi bản ghi.
//StmtDb.java import java.sql.*; class StmtDb { public static void main(String[] argv) { String url = "jdbc:db2:sample"; Connection con; Statement stmt1, stmt2; ResultSet rs; String stmt1String = "INSERT INTO EMPLOYEE (EMPNO,FIRSTNME,MIDINIT,LASTNAME,EDLEVEL)" + " VALUES ('000099','MICHIEL','G','DEROOS',1)"; String stmt2String = "SELECT EMPNO, LASTNAME FROM EMPLOYEE"; try { Class.forName("com.ibm.db2.jcc.DB2Driver"); con = DriverManager.getConnection(url); con.setAutoCommit(true); stmt1 = con.createStatement(); stmt2 = con.createStatement(); stmt1.executeUpdate(stmt1String); rs = stmt2.executeQuery(stmt2String); System.out.println("Employee # Employee surname"); while (rs.next()) { System.out.println(rs.getString(1) + " " + rs.getString(2)); } rs.close(); stmt1.close(); stmt2.close(); con.close(); } catch (ClassNotFoundException drvEx) { System.err.println("Could not load JDBC driver"); System.out.println("Exception: " + drvEx); drvEx.printStackTrace(); } catch(SQLException sqlEx) { while(sqlEx != null) { System.err.println("SQLException information"); System.err.println("Error msg: " + sqlEx.getMessage()); System.err.println("SQLSTATE: " + sqlEx.getSQLState()); System.err.println("Error code: " + sqlEx.getErrorCode()); sqlEx.printStackTrace(); sqlEx=sqlEx.getNextException(); } } } }
Để biên dịch tệp tin trên (có tên là StmtDb.java), hãy thi hành lệnh sau đây:
javac StmtDb.java
Để chạy các ứng dụng đã biên dịch, hãy thi hành lệnh sau đây:
java StmtDb
Kết quả đầu ra của ứng dụng này trông giống như sau:
Employee # Employee surname 000010 HAAS 000020 THOMPSON 000030 KWAN 000050 GEYER 000060 STERN 000070 PULASKI 000090 HENDERSON 000100 SPENSER 000110 LUCCHESSI 000120 O'CONNELL 000130 QUINTANA 000140 NICHOLLS 000150 ADAMSON 000160 PIANKA 000170 YOSHIMURA 000180 SCOUTTEN 000190 WALKER 000200 BROWN 000210 JONES 000220 LUTZ 000230 JEFFERSON 000240 MARINO 000250 SMITH 000260 JOHNSON 000270 PEREZ 000280 SCHNEIDER 000290 PARKER 000300 SMITH 000310 SETRIGHT 000320 MEHTA 000330 LEE 000340 GOUNOT 200010 HEMMINGER 200120 ORLANDO 200140 NATZ 200170 YAMAMOTO 200220 JOHN 200240 MONTEVERDE 200280 SCHWARTZ 200310 SPRINGER 200330 WONG 200340 ALONZO 000099 DEROOS
### Đối tượng PreparedStatement
Các đối tượng
PreparedStatement được tạo ra
bằng cách sử dụng phương thức
Connection.prepareStatement(). Ví dụ:
PreparedStatement stmt; ... stmt = con.prepareStatement();
Với một đối tượng
PreparedStatement, bạn có
thể chuẩn bị và thi hành các câu lệnh SQL theo phương thức động. Bằng
cách liên kết lại các giá trị tới các dấu tham số trong các câu lệnh
SQL, bạn có thể thi hành cùng một câu lệnh nhiều lần bằng cách sử dụng
các giá trị khác nhau. (Một dấu tham số được biểu diễn bằng một dấu
hỏi
?, và hoạt động như một ký hiệu giữ chỗ
cho một giá trị sẽ được gán trong thời gian chạy). Ví dụ:
pStmt = con.prepareStatement("UPDATE STAFF SET COMM=? WHERE ID=?"); pStmt.setDouble(1,710.53); pStmt.setInt(2,350); pStmt.executeUpdate(); pStmt.setDouble(1,710.53); pStmt.setInt(2,350); pStmt.executeUpdate();
Để biết thêm về các dấu tham số, đọc bài viết thứ tám trong loạt bài
này (xem phần
[Tài nguyên](#resources)).
### Đối tượng PreparedStatement: Mã mẫu
Ứng dụng dưới đây giải thích tất cả các khái niệm được thảo luận trong phần trên:
- Tạo một đối tượng
PreparedStatement.
- Sử dụng dấu tham số để gán các giá trị trong các câu lệnh SQL theo phương thức động.
Ứng dụng này phân tích một mảng các tên và chức danh công việc. Ứng với mỗi mục trong mảng, nó chèn thêm một bản ghi vào bảng nhân viên.
//pStmtDb.java import java.sql.*; class pStmtDb { public static void main(String[] argv) { String url = "jdbc:db2:sample"; Connection con; PreparedStatement pStmt; Statement sStmt; ResultSet rs; String stmtString = "INSERT INTO STAFF (ID,NAME,DEPT,JOB) VALUES (?,?,99,?)"; String [][] staff = {{"Smyth","LW"},{"Hemsky","RW"},{"Horcoff","C"}}; try { Class.forName("com.ibm.db2.jcc.DB2Driver"); con = DriverManager.getConnection(url); con.setAutoCommit(false); pStmt = con.prepareStatement(stmtString); for (int i=0; i<3; i++) { pStmt.setInt(1,401+i); pStmt.setString(2,staff[i][0]); pStmt.setString(3,staff[i][1]); pStmt.executeUpdate(); } con.commit(); sStmt = con.createStatement(); rs = sStmt.executeQuery("SELECT ID, NAME FROM STAFF WHERE DEPT = 99"); System.out.println("Employee # Employee surname"); while (rs.next()) { System.out.println(rs.getString(1) + " " + rs.getString(2)); } rs.close(); pStmt.close(); sStmt.close(); con.commit(); con.close(); } catch (ClassNotFoundException drvEx) { System.err.println("Could not load JDBC driver"); System.out.println("Exception: " + drvEx); drvEx.printStackTrace(); } catch(SQLException sqlEx) { while(sqlEx != null) { System.err.println("SQLException information"); System.err.println("Error msg: " + sqlEx.getMessage()); System.err.println("SQLSTATE: " + sqlEx.getSQLState()); System.err.println("Error code: " + sqlEx.getErrorCode()); sqlEx.printStackTrace(); sqlEx=sqlEx.getNextException(); } } } }
Để biên dịch tệp tin trên (có tên là pStmtDb.java), hãy thi hành lệnh sau đây:
javac pStmtDb.java
Để chạy các ứng dụng đã biên dịch, hãy thi hành lệnh sau đây:
java pStmtDb
Kết quả đầu ra của ứng dụng này sẽ giống như sau:
Employee # Employee surname 401 Smyth 402 Hemsky 403 Horcoff
### Cam kết các giao dịch
Trong các mã ví dụ về
Statement và
PreparedStatement, hai cách tiếp cận khác
nhau để cam kết các giao dịch đã được sử dụng: cam kết tự động
(autocommit) và cam kết thủ công.
Cách tiếp cận được sử dụng trong ví dụ
Statement là cam kết tự động, ở đó mỗi câu lệnh đã được
cam kết tự động. Cam kết tự động được bật cho phép từ trong đối tượng
Connection, như sau:
con.setAutoCommit(true);
Không giống như các bản phát hành trước, ấn bản DB2 9 của trình điều
khiển IBM DB2 cho JDBC và SQLJ sẽ đưa ra một lỗi ngoại lệ nếu bạn thi
hành
Connection.Commit() hoặc
Connection.Rollback() khi chế độ tự động cam
kết được kích hoạt.
Cách tiếp cận được sử dụng trong ví dụ
PreparedStatement là cam kết thủ công. Với cách tiếp cận
này, từng câu lệnh hoặc là được cam kết thủ công hoặc được khôi phục
lại. Nếu khi kết thúc ứng dụng các câu lệnh không được giao kết, chúng
sẽ tự động khôi phục lại. Các hoạt động cam kết thủ công hoặc khôi
phục lại được thực hiện từ đối tượng
Connection, như sau:
con.commit(); ... con.rollback();
### Phát ra các giao dịch phân tán
Để phát ra các giao dịch phân tán từ các ứng dụng Java của bạn, bạn cần phải sử dụng API các giao dịch Java (JTA - Java Transaction API). (Các giao dịch phân tán, còn được gọi là các giao dịch cam kết hai giai đoạn, là các giao dịch cập nhật dữ liệu trong nhiều hơn một cơ sở dữ liệu). Đặc tả kỹ thuật JTA là thành phần quản lý giao dịch của tiêu chuẩn Nền tảng Java 2, Ấn bản Doanh nghiệp (J2EE - Java 2 Platform, Enterprise Edition).
Trong DB2, các giao dịch phân tán được quản lý thông qua lớp
DB2XADataSource, lớp này triển khai thực hiện
giao diện
XADataSource từ gói
javax.sql.
Đối với DB2 9, sự hỗ trợ JTA được cung cấp ở cả hai trình điều khiển
IBM DB2 cho JDBC và SQLJ và trình điều khiển JDBC DB2 Kiểu 2. Mã Java
dưới đây tạo ra một cá thể của lớp
DB2XADataSource sử dụng trình điều khiển IBM DB2 cho JDBC
và SQLJ:
DB2XADataSource db2ds = new com.ibm.db2.jcc.DB2XADataSource();
## Đọc và cập nhật dữ liệu với SQLJ
### Tổng quan
API SQLJ là một phần mở rộng của JDBC và nó hỗ trợ thi hành tĩnh câu lệnh SQL. Bởi vì DB2 hỗ trợ SQLJ, các nhà phát triển Java có thể khắc phục một hạn chế chính của JDBC, cụ thể là JDBC chỉ có thể thi hành các câu lệnh SQL theo phương thức động. Các câu lệnh SQL liên kết tĩnh thường chạy nhanh hơn so với các câu lệnh liên kết động, chúng mang lại cho các ứng dụng SQLJ một lợi thế hiệu năng đáng kể so với các ứng dụng JDBC.
Trong phần này, bạn sẽ tìm hiểu làm thế nào để lập trình với API SQLJ bằng cách sử dụng bối cảnh kết nối, đưa ra các câu lệnh SQL trong các mệnh đề SQLJ có thể chạy được và phân tích cú pháp các bộ kết quả với các trình vòng lặp (iterator).
### Các nhiệm vụ phát triển ứng dụng SQLJ
Khi bắt đầu một ứng dụng SQLJ, bạn cần phải nhập khẩu các gói Java có chứa các API JDBC và SQLJ:
import sqlj.runtime.*; import java.sql.*;
Các ứng dụng SQLJ sử dụng cùng các trình điều khiển JDBC được thảo luận
trong phần
[JDBC drivers](#jdbcdrivers) (các
trình điều khiển JDBC).
Trước khi mã nguồn SQLJ có thể được biên dịch, nó cần phải được chuyển
thành mã Java để có thể được biên dịch bằng một trình biên dịch Java.
Lệnh
sqlj thực hiện phép chuyển đổi này và
cũng gọi trình biên dịch Java. Nếu bạn có các câu lệnh SQL trong tệp
tin nguồn SQLJ của bạn, một tệp tin với tên có phần cuối là
_SJProfile0.ser xuất hiện trong thư mục của
bạn cùng với tệp
class và tệp
sqlj.
Bạn có thể chạy mã nguồn của bạn một khi bạn đã dịch và đã biên dịch
nó. Tuy nhiên, các câu lệnh SQL trong ứng dụng của bạn sẽ không được
liên kết tĩnh, dẫn đến khả năng hiệu năng kém. Để liên kết tĩnh các
lệnh SQL trong ứng dụng của bạn, bạn cần phải thực hiện một tùy chỉnh
lược thảo của ứng dụng của bạn. Bạn có thể thực hiện tuỳ chỉnh này
bằng công cụ
db2sqljcustomize.
Để thực hiện việc tùy chỉnh lược thảo của một ứng dụng đã biên dịch, hãy thi hành lệnh sau đây:
db2sqljcustomize -url jdbc:db2://localhost:50000/sample -user uid -password pwd app_SJProfile0.ser
Trong lệnh này,
uid là mã nhận dạng ID của
người dùng của bạn,
pwd là mật khẩu của bạn
và
app là tên của ứng dụng của bạn.
Một số kết quả đầu ra mẫu từ việc chạy
db2sqljcustomize thành công được hiển thị bên dưới.
db2sqljcustomize -url jdbc:db2://localhost:50000/sample -user me -password mypwd DbApp_SJProfile0.ser [ibm][db2][jcc][sqlj] [ibm][db2][jcc][sqlj] Begin Customization [ibm][db2][jcc][sqlj] Loading profile: DbApp_SJProfile0 [ibm][db2][jcc][sqlj] Customization complete for profile DbApp_SJProfile0.ser [ibm][db2][jcc][sqlj] Begin Bind [ibm][db2][jcc][sqlj] Loading profile: DbApp_SJProfile0 [ibm][db2][jcc][sqlj] Driver defaults(user may override): BLOCKING ALL VALIDATE BIND STATICREADONLY YES [ibm][db2][jcc][sqlj] Fixed driver options: DATETIME ISO DYNAMICRULES BIND [ibm][db2][jcc][sqlj] Binding package DBAPP01 at isolation level UR [ibm][db2][jcc][sqlj] Binding package DBAPP02 at isolation level CS [ibm][db2][jcc][sqlj] Binding package DBAPP03 at isolation level RS [ibm][db2][jcc][sqlj] Binding package DBAPP04 at isolation level RR [ibm][db2][jcc][sqlj] Bind complete for DbApp_SJProfile0
### Thiết lập một bối cảnh kết nối
Trong các ứng dụng SQLJ, các hoạt động SQL đòi hỏi một bối cảnh kết
nối thay cho một đối tượng
Connection JDBC.
Mỗi câu lệnh SQL được đưa ra thông qua các mệnh đề SQLJ
#sql và được gán rõ hoặc ngầm ẩn với một bối
cảnh kết nối. Việc gán một bối cảnh kết nối kết hợp câu lệnh với kết
nối cơ sở dữ liệu đã mở trước đó.
Trước khi thiết lập một kết nối cơ sở dữ liệu, đầu tiên bạn phải tạo
ra một lớp bối cảnh kết nối. Các dòng mã sau đây tạo ra một lớp bối
cảnh kết nối được đặt tên
Ctx:
#sql context Ctx;
Để thiết lập một kết nối cơ sở dữ liệu, hãy nạp một trình điều khiển
JDBC bằng cách sử dụng phương thức
Class.forName() và sau đó xây dựng một cá thể của lớp bối
cảnh mà bạn đã tạo ra trước đó. Ít nhất, bạn cần phải chuyển giao cho
hàm tạo bối cảnh URL của cơ sở dữ liệu và một giá trị kiểu boolean cho
biết bạn có muốn bật chế độ cam kết tự động hay không. Đoạn mã sau
thiết lập một kết nối cơ sở dữ liệu trong SQLJ:
String url = "jdbc:db2:sample"; Class.forName("com.ibm.db2.jcc.DB2Driver"); Ctx connCtx = new Ctx(url,true);
Trong bối cảnh kết nối ví dụ mẫu
connCtx
này, trình điều khiển IBM DB2 cho JDBC và SQLJ đang được sử dụng để
kết nối với cơ sở dữ liệu mẫu trên một máy chủ DB2 và chế độ cam kết
tự động được bật.
### Đưa ra các câu lệnh SQL
Một lợi thế đáng kể của SQLJ so với nhiều API cơ sở dữ liệu khác (bao
gồm JDBC) là tính đơn giản và sức mạnh cú pháp của SQLJ. Ví dụ mã sau
giải thích một câu lệnh
UPDATE có sử dụng
một biến chủ:
String staffJob = "Sales"; #sql [connCtx] {UPDATE STAFF SET COMM=400 WHERE JOB = :staffJob};
Để viết các câu lệnh SQL trả về các bộ kết quả, bạn sẽ cần phải sử dụng
*iterators* (các trình vòng lặp). Các trình vòng lặp được
thảo luận sau này trong phần [Use iterators](#iterators)
(Sử dụng các trình vòng lặp).
### Ứng dụng SQLJ cơ sở: Mã mẫu
Ứng dụng dưới đây giải thích tất cả những khái niệm được thảo luận cho đến nay trong phần này:
- Nhập khẩu các gói Java có chứa các API JDBC và SQLJ.
- Nạp Trình điều khiển IBM DB2 cho JDBC và SQLJ.
- Tạo một bối cảnh kết nối.
- Thi hành một lệnh SQL với một biến chủ.
Trong ứng dụng này, một câu lệnh
SELECT được
thi hành và kết quả vô hướng sẽ được chuyển tới một biến chủ có tên là
stname.
//DbApp.sqlj import sqlj.runtime.*; import java.sql.*; #sql context Ctx; class DbApp { public static void main(String[] argv) { String url = "jdbc:db2:sample"; String stname; try { Class.forName("com.ibm.db2.jcc.DB2Driver"); Ctx connCtx = new Ctx(url,true); #sql [connCtx] {SELECT NAME INTO :stname FROM STAFF WHERE ID=10}; System.out.println("The name of employee #10 is: " + stname); connCtx.close(); } catch (ClassNotFoundException drvEx) { System.err.println("Could not load JDBC driver"); System.out.println("Exception: " + drvEx); drvEx.printStackTrace(); } catch(SQLException sqlEx) { while(sqlEx != null) { System.err.println("SQLException information"); System.err.println("Error msg: " + sqlEx.getMessage()); System.err.println("SQLSTATE: " + sqlEx.getSQLState()); System.err.println("Error code: " + sqlEx.getErrorCode()); sqlEx.printStackTrace(); sqlEx=sqlEx.getNextException(); } } } }
Để dịch và biên dịch các tệp tin trên (có tên là DbApp.sqlj), hãy thi hành lệnh sau đây:
sqlj DbApp.sqlj
Để thực hiện một tùy chỉnh lược thảo của ứng dụng đã biên dịch này, hãy thi hành lệnh sau đây:
db2sqljcustomize -url jdbc:db2://localhost:50000/sample -user uid -password pwd DbApp_SJProfile0.ser
Trong lệnh này,
uid là ID của người dùng của
bạn
pwd là mật khẩu của bạn.
Để chạy các ứng dụng đã biên dịch, thi hành lệnh sau đây:
java DbApp
Kết quả đầu ra của ứng dụng này trông giống như sau:
The name of employee #10 is: Sanders
### Sử dụng các trình vòng lặp
Để phân tích cú pháp các bộ kết quả trong các ứng dụng SQLJ, bạn cần phải sử dụng các trình vòng lặp. Các trình vòng lặp là phiên bản SQLJ của các con trỏ SQL. Có hai loại các trình vòng lặp chính mà bạn có thể sử dụng trong SQLJ: trình vòng lặp có tên và trình vòng lặp vị trí.
#### Các trình vòng lặp có tên
Các trình vòng lặp có tên được khai báo với các tên và các kiểu dữ liệu
của các cột trong tập kết quả. Với các trình vòng lặp có tên, thứ tự
các cột không quan trọng. Trước khi bạn có thể sử dụng một trình vòng
lặp có tên trong ứng dụng của bạn, bạn phải tạo ra một lớp trình vòng
lặp, lưu tâm đến bản chất của tập kết quả mà bạn muốn phân tích cú
pháp. Đoạn mã sau đây tạo ra một lớp trình vòng lặp có tên gọi là
NameIter; lớp trình vòng lặp có hai
cột.
#sql iterator NameIter(String Name, int Id);
Khi đưa ra một truy vấn SQL, bạn cần phải chuyển tập kết quả tới một cá thể của lớp trình vòng lặp mà bạn đã tạo ra. Ví dụ:
NameIter nIter; #sql [connCtx] nIter = {SELECT ID, NAME FROM STAFF WHERE DEPT = 20};
Để lấy ra các giá trị cột từ một trình vòng lặp có tên, bạn có thể sử
dụng các phương thức của trình vòng lặp được đặt tên theo các tên cột
trong tập kết quả. Để phân tích cú pháp trình vòng lặp có tên, bạn sử
dụng một cấu trúc vòng lặp; trước mỗi chu kỳ vòng lặp, hãy đi đến hàng
kế tiếp bằng cách chạy phương thức
iterator.next(). Đoạn mã sau phân tích cú pháp một cá thể
của một trình vòng lặp có tên là
NameIter.
while (nIter.next()) { System.out.println(nIter.Name() + ", ID #" + nIter.Id()); }
#### Các trình vòng lặp vị trí
Các trình vòng lặp vị trí chỉ được khai báo với các kiểu dữ liệu của
các cột trong tập kết quả. Với các trình vòng lặp vị trí, thứ tự các
cột rất quan trọng. Trước khi bạn có thể sử dụng một trình vòng lặp vị
trí trong ứng dụng của bạn, bạn phải tạo ra một lớp trình vòng lặp,
lưu tâm đến bản chất của tập kết quả mà bạn muốn phân tích cú pháp.
Đoạn mã sau đây tạo ra một lớp trình vòng lặp vị trí được gọi là
PosIter; lớp trình vòng lặp có hai cột.
#sql iterator PosIter(String, int);
Khi đưa ra một truy vấn SQL, hãy chuyển tập kết quả tới một cá thể của lớp trình vòng lặp mà bạn tạo ra. Ví dụ:
PosIter pIter; #sql [connCtx] pIter = {SELECT ID, NAME FROM STAFF WHERE DEPT = 20};
Để lấy ra các giá trị cột từ một trình vòng lặp vị trí, bạn cần phải
tìm nạp các giá trị đó vào các biến chủ. Sử dụng phương thức
iterator.endFetch() để xác định xem còn có
các hàng bổ sung để tìm nạp không. Đoạn mã sau phân tích cú pháp một
cá thể của trình vòng lặp vị trí
PosIter.
#sql {FETCH :pIter INTO :nameHv, :idHv }; while (!pIter.endFetch()) { System.out.println(nameHv + ", ID #" + idHv); #sql {FETCH :pIter INTO :nameHv, :idHv }; }
### Các trình vòng lặp có tên và trình vòng lặp vị trí: Mã mẫu
Ứng dụng dưới đây giải thích tất cả những khái niệm được thảo luận trong phần trên:
- Tạo một trình vòng lặp có tên.
- Tạo một trình vòng lặp vị trí.
- Phân tích cú pháp một tập kết quả sử dụng một trình vòng lặp có tên.
- Phân tích cú pháp một tập kết quả sử dụng một trình vòng lặp vị trí.
Trong ứng dụng này, một câu lệnh
SELECT được
thực hiện hai lần. Tập kết quả từ lần thực hiện đầu tiên được phân
tích cú pháp với một trình vòng lặp có tên được gọi là
nIter. Tập kết quả từ lần thực hiện thứ hai
được phân tích cú pháp với một trình vòng lặp vị trí được gọi là
pIter.
//Iter.sqlj import sqlj.runtime.*; import java.sql.*; #sql context Ctx; #sql iterator NameIter(String Name, int Id); #sql iterator PosIter(String, int); class Iter { public static void main(String[] argv) { String url = "jdbc:db2:sample"; String nameHv = null; int idHv = 0; NameIter nIter; PosIter pIter; try { Class.forName("com.ibm.db2.jcc.DB2Driver"); Ctx connCtx = new Ctx(url,true); System.out.println("\nResult set from named iterator:"); #sql [connCtx] nIter = {SELECT ID, NAME FROM STAFF WHERE DEPT = 20}; while (nIter.next()) { System.out.println(nIter.Name() + ", ID #" + nIter.Id()); } nIter.close(); System.out.println("\nResult set from positional iterator:"); #sql [connCtx] pIter = {SELECT NAME, ID FROM STAFF WHERE DEPT = 20}; #sql {FETCH :pIter INTO :nameHv, :idHv }; while (!pIter.endFetch()) { System.out.println(nameHv + ", ID #" + idHv); #sql {FETCH :pIter INTO :nameHv, :idHv }; } pIter.close(); connCtx.close(); } catch (ClassNotFoundException drvEx) { System.err.println("Could not load JDBC driver"); System.out.println("Exception: " + drvEx); drvEx.printStackTrace(); } catch(SQLException sqlEx) { while(sqlEx != null) { System.err.println("SQLException information"); System.err.println("Error msg: " + sqlEx.getMessage()); System.err.println("SQLSTATE: " + sqlEx.getSQLState()); System.err.println("Error code: " + sqlEx.getErrorCode()); sqlEx.printStackTrace(); sqlEx=sqlEx.getNextException(); } } } }
Để dịch và biên dịch các tệp tin trên (có tên là Iter.sqlj), hãy thi hành lệnh sau đây:
sqlj Iter.sqlj
Để thực hiện một tùy chỉnh lược thảo của ứng dụng đã biên dịch này, hãy thi hành lệnh sau đây:
db2sqljcustomize -url jdbc:db2://localhost:50000/sample -user uid -password pwd Iter.ser
Trong lệnh này,
uid là mã nhận dạng ID của
người sử dụng của bạn và
pwd là mật khẩu
của bạn.
Để chạy ứng dụng đã biên dịch, hãy thi hành lệnh sau đây:
java Iter
Kết quả đầu ra của ứng dụng này sẽ giống như thế này:
Result set from named iterator: Sanders, ID #10 Pernal, ID #20 James, ID #80 Sneider, ID #190 Result set from positional iterator: Sanders, ID #10 Pernal, ID #20 James, ID #80 Sneider, ID #190
## Xử lý lỗi
### Tổng quan
Trong phần này, bạn học cách làm thế nào để sử dụng các công cụ xử lý lỗi có sẵn cho các ứng dụng JDBC. Bạn sẽ tìm thấy các thông tin sau:
- Xem xét cách làm thực tế để xử lý và báo lỗi cơ sở bằng cách
sử dụng các đối tượng
SQLException
- Sử dụng tiện ích lần theo vết JDBC.
- Thảo luận về bản ghi nhật ký lỗi của JDBC.
### Việc xử lý lỗi
Để theo các cách làm thực tế để xử lý lỗi đúng đắn trong các chương
trình Java của bạn, bạn bao bọc logic trong các ứng dụng JDBC của bạn
trong các khối
try/
catch. Khi một lỗi xuất hiện trong các phương thức JDBC,
chúng sẽ đưa ra các đối tượng
SQLException.
Do vậy, với mỗi khối
try có chứa một hoạt
động JDBC, khối
catch tương ứng sẽ chứa
logic để xử lý một đối tượng
SQLException.
Ví dụ sau mô tả một câu lệnh
SELECT với các
toán hạng không tương thích về kiểu trong mệnh đề
WHERE: cột
JOB của bảng
STAFF là kiểu dữ liệu
VARCHAR, không phải
INTEGER.
try { ... rs = stmt.executeQuery("SELECT ID, NAME FROM STAFF WHERE JOB = 99"); ... } catch(SQLException sqlEx) { while(sqlEx != null) { System.err.println("SQLException information"); System.err.println("Error msg: " + sqlEx.getMessage()); System.err.println("SQLSTATE: " + sqlEx.getSQLState()); System.err.println("Error code: " + sqlEx.getErrorCode()); sqlEx=sqlEx.getNextException(); } }
Khối
catch có chứa một vòng lặp
while, nó tạo điều kiện cho việc xử lý nhiều
trường hợp lỗi ngoại lệ. Ở cuối vòng lặp, có một lời gọi phương thức
SQLException.getNextException(), trong
đó trả về một lỗi ngoại lệ nếu có một lỗi ngoại lệ khác để bắt giữ,
hoặc trả về null nếu không có các lỗi ngoại lệ nào thêm.
Câu lệnh
SELECT với các toán hạng không
tương thích tạo ra các lỗi ngoại lệ sau đây:
SQLException information Error msg: DB2 SQL error: SQLCODE: -401, SQLSTATE: 42818, SQLERRMC: = SQLSTATE: 42818 Error code: -401 SQLException information Error msg: DB2 SQL error: SQLCODE: -727, SQLSTATE: 56098, SQLERRMC: 2;-401;42818;= SQLSTATE: 56098 Error code: -727
Kết quả đầu ra này khác nhau, tùy thuộc vào trình điều khiển JDBC bạn đang sử dụng. Kết quả đầu ra ở trên đã được tạo ra bởi một ứng dụng sử dụng trình điều khiển IBM DB2 cho JDBC và SQLJ.
Tất cả các mã mẫu hoàn chỉnh được trình bày trong hướng dẫn này có
chứa logic để xử lý các đối tượng
SQLException.
### Tiện ích lần theo vết của trình điều khiển IBM DB2 cho JDBC và SQLJ
Để gỡ rối các ứng dụng JDBC và SQLJ của bạn, bạn có thể dùng tiện ích theo dõi của trình điều khiển IBM DB2 cho JDBC và SQLJ. Cách tiếp cận được khuyến cáo cho việc thu thập dữ liệu theo vết là kích hoạt tiện ích theo vết bên ngoài ứng dụng của bạn bằng cách chỉnh sửa các thuộc tính trong tệp tin thuộc tính cấu hình của trình điều khiển IBM DB2 cho JDBC và SQLJ. Tuy nhiên, bạn cũng có thể kích hoạt tiện ích lần theo vết từ bên trong ứng dụng của bạn. Bạn có thể bật cho phép lần theo vết trong suốt thời gian chạy ứng dụng bằng cách chỉ rõ các tùy chọn lần theo vết khi bạn nạp trình điều khiển hoặc bạn có thể gọi rõ phương thức lần theo vết để bật và tắt việc lần theo vết trong các phần khác nhau của ứng dụng của bạn.
Để sử dụng tiện ích lần theo vết của trình điều khiển IBM DB2 cho JDBC và SQLJ bên ngoài ứng dụng của bạn, hãy thêm các dòng sau vào một tệp tin thuộc tính:
db2.jcc.traceDirectory=Trace db2.jcc.traceFile=extTrace db2.jcc.traceFileAppend=true
Nhằm phục vụ hướng dẫn này, các dòng này được thêm vào một tệp tin có
tên là tut-trace.properties, nằm trong cùng thư mục như các tệp tin
lớp được thử nghiệm. Như thuộc tính
traceDirectory đã xác nhận, tất cả các tệp tin lần theo
vết được ghi vào một thư mục con có tên là trace. Thư mục này phải tồn
tại dành cho các tệp tin theo dõi được ghi. Bằng cách chỉ rõ tệp tin
các thuộc tính tut-trace.properties trong lệnh
java, tiện ích lần theo vết thu thập thông tin về lớp
ConnDb.
java -Ddb2.jcc.propertiesFile=tut-trace.properties ConnDb
Để cho phép lần theo vết từ trong một ứng dụng, bạn có thể gắn thêm
các thuộc tính đặc thù cho việc theo vết vào sau tham số
url mà bạn sử dụng để nhận được kết nối cơ sở
dữ liệu. Ví dụ:
String url = "jdbc:db2:sample:traceFile=Trace/intTrace.txt;traceLevel=" + (com.ibm.db2.jcc.DB2BaseDataSource.TRACE_DRDA_FLOWS | com.ibm.db2.jcc.DB2BaseDataSource.TRACE_CONNECTS) + ";";
Trong ví dụ này, thông tin theo vết được viết vào một tệp tin có tên là intTrace.txt trong thư mục con Trace.
Để bật và tắt việc theo vết trong một ứng dụng bằng cách sử dụng một
DriverManager, bạn chỉ rõ
traceLevel trong
tham số
url mà bạn sử dụng để nhận được một
kết nối cơ sở dữ liệu và tên tệp tin (filename) và đường dẫn trong
phương thức
DriverManager.setLogWriter. Ví
dụ:
... String url = "jdbc:db2:sample:traceLevel=" + (com.ibm.db2.jcc.DB2BaseDataSource.TRACE_DRDA_FLOWS | com.ibm.db2.jcc.DB2BaseDataSource.TRACE_CONNECTS) + ";"; ... //turn on trace ((com.ibm.db2.jcc.DB2Connection) con).setJccLogWriter(printWriter, com.ibm.db2.jcc.DB2BaseDataSource.TRACE_ALL); ... //database activity ... //turn off trace ((com.ibm.db2.jcc.DB2Connection) con).setJccLogWriter(null);
### Giám sát hiệu năng
Trình điều khiển IBM DB2 cho JDBC và SQLJ bao gồm một giao diện
DB2SystemMonitor, nó cho phép bạn thu thập
thông tin sau đây về ứng dụng của bạn:
**Thời gian của trình điều khiển lõi**: Tổng số thời gian của API được giám sát đã trôi qua. **Thời gian I/O của mạng**: Tổng số thời gian của I/O được giám sát đã trôi qua. **Thời gian của máy chủ**: Tổng số thời gian đã trôi qua của tất cả máy chủ DB2 được báo cáo. **Thời gian ứng dụng**: Tổng số thời gian đã trôi qua của máy chủ DB2, I/O của mạng, trình điều khiển JDBC và ứng dụng.
Tất cả thời gian đã thu thập được tính bằng microgiây.
Đoạn mã dưới đây giải thích cách để tạo ra một giao diện
DB2SystemMonitor và thu thập và lấy ra dữ
liệu giám sát về ứng dụng:
... com.ibm.db2.jcc.DB2SystemMonitor systemMonitor = ((com.ibm.db2.jcc.DB2Connection)con).getDB2SystemMonitor(); systemMonitor.enable(true); //reset all counters systemMonitor.start(com.ibm.db2.jcc.DB2SystemMonitor.RESET_TIMES); ... //database activity ... systemMonitor.stop(); System.out.println("Server elapsed time = " + systemMonitor.getServerTimeMicros());
## Kết luận
### Tóm tắt
Hướng dẫn này cung cấp một giới thiệu nhập môn về các khái niệm lập trình cơ sở dữ liệu Java mà bạn sẽ được kiểm tra trong kỳ thi lấy chứng chỉ phát triển ứng dụng Họ DB2 9 (kỳ thi 733). Để củng cố các ý tưởng được trình bày trong mỗi phần của hướng dẫn, hãy làm nhiều hơn là chỉ đơn giản biên dịch và chạy các mã ví dụ mẫu. Hãy thực hiện các sửa đổi và cải tiến riêng của bạn.
Để tập trung vào loạt bài này, hãy đánh dấu trang của loạt bài
[DB2 9 application development exam 733 prep tutorials](http://www.ibm.com/developerworks/vn/views/data/libraryview.jsp?search_by=Chuẩn+bị+cho+kỳ+thi+733+về+Phát+triển+ứng+dụng+DB2+9) (các
hướng dẫn chuẩn bị cho kỳ thi 733 về phát triển ứng dụng DB2 9).
## Tài nguyên
### Học tập
[DB2 9 Application Development exam 733 prep tutorial series](http://www.ibm.com/developerworks/vn/views/data/libraryview.jsp?search_by=Chuẩn+bị+cho+kỳ+thi+733+về+Phát+triển+ứng+dụng+DB2+9): Xem các phần khác của loạt bài hướng dẫn này. Các hướng dẫn trong loạt này bao gồm:
- Các đối tượng cơ sở dữ liệu và các phương pháp lập trình.
- Thao tác dữ liệu.
- Thao tác dữ liệu XML.
- Lập trình SQL nhúng.
- Lập trình ODBC/CLI.
- Lập trình .NET.
- Lập trình Java.
- Lập trình nâng cao.
- Các thường trình do người dùng định nghĩa.
[DB2 9 Fundamentals certification prep tutorial series](http://www.ibm.com/developerworks/vn/views/data/libraryview.jsp?search_by=Chuẩn+bị+cho+kỳ+thi+730+cơ+bản+về+DB2+9): Trước khi bạn tham dự kỳ thi lấy chứng chỉ Phát triển ứng dụng DB2 9 (kỳ thi 733), bạn phải tham dự và vượt qua kỳ thi lấy chứng chỉ cơ sở DB2 9 (kỳ thi 730). Sử dụng loạt bài gồm bảy hướng dẫn này để chuẩn bị cho kỳ thi đó; các chủ đề bao gồm:
- Lập kế hoạch DB2.
- An ninh DB2.
- Truy cập dữ liệu DB2.
- Làm việc với dữ liệu DB2.
- Làm việc với các đối tượng DB2.
- Tương tranh dữ liệu.
- Giới thiệu Xquery.
[developerWorks resource page for DB2 for Linux, UNIX, and Windows](http://www.ibm.com/developerworks/db2/zones/db2udb?S_TACT=105AGY75): Tìm các bài viết và các hướng dẫn và kết nối đến các tài nguyên khác để mở rộng các kỹ năng DB2 của bạn. [Trung tâm Thông tin DB2 9](http://publib.boulder.ibm.com/infocenter/db2luw/v9/): Tìm hiểu thêm về phát triển ứng dụng DB2.
- Để biết thêm thông tin về cấp chứng chỉ
phát triển ứng dụng DB2 9 cho Linux, UNIX và Windows (kỳ thi 733), hãy xem
các đường liên kết sau:
[Thông tin về đào tạo quản lý thông tin](http://www-4.ibm.com/software/data/db2/skills/) [Thông tin chung về chứng chỉ](http://www-4.ibm.com/software/data/db2/skills/cert.html): bao gồm đề xuất về sách, các mục tiêu của kỳ thi và các khóa học. [Trang Web kỳ thi cấp chứng chỉ](http://www-03.ibm.com/certify/tests/test_index.shtml): Nhấn vào số hiệu bài thi để xem nhiều thông tin hơn về Các kỳ thi 730 và 731.
- Các liên kết sau đây cung cấp thêm thông tin về việc phát triển các ứng dụng Java cho các cơ sở dữ liệu DB2:
- Tìm hiểu về
[DB2 Express-C](http://www.ibm.com/software/data/db2/udb/db2express/): phiên bản miễn phí của Ấn bản DB2 Express cho cộng đồng.
- Theo sát với
[các sự kiện kỹ thuật và Webcasts của developerWorks](http://www.ibm.com/developerworks/offers/techbriefings/?S_TACT=105AGY75). [developerWorks Information Management zone](http://www.ibm.com/developerworks/db2/?S_TACT=105AGY75): Tìm hiểu thêm về DB2. Tìm kiếm tài liệu hướng dẫn kỹ thuật, các bài báo hướng dẫn, đào tạo, tải về, thông tin sản phẩm và nhiều hơn nữa.
### Lấy sản phẩm và công nghệ
- Tải về một phiên
bản dùng thử miễn phí
[DB2 Enterprise 9](http://www.ibm.com/developerworks/downloads/im/udb/index.html?S_TACT=105AGY75). [DB2 Express-C](http://www.ibm.com/developerworks/downloads/im/udbexp/index.html?S_TACT=105AGY75): Bây giờ bạn có thể sử dụng DB2 miễn phí. Tải xuống phiên bản miễn phí của DB2 Express, Ấn bản cho cộng đồng có cung cấp cùng các tính năng cốt lõi như Ấn bản DB2 Express và cung cấp một cơ sở vững chắc để xây dựng và triển khai các ứng dụng. [DB2 Developer Workbench](http://www-306.ibm.com/software/data/db2/express/download.html): Tải về sản phẩm miễn phí này.
- Xây dựng dự án
phát triển tiếp theo của bạn với
[Phần mềm dùng thử của IBM](http://www.ibm.com/developerworks/downloads?S_TACT=105AGY75), có sẵn để tải về trực tiếp từ developerWorks.
### Thảo luận
- Tham gia vào
[các blog của DeveloperWorks](http://www.ibm.com/developerworks/blogs/?S_TACT=105AGY75)và dành hết tâm trí cho cộng đồng developerWorks.
## Bình luận
[Vùng dữ liệu trên developerWorks](http://www.ibm.com/developerworks/vn/views/data/libraryview.jsp)
Khám phá các bài viết xoay quanh lĩnh vực dữ liệu, Quản lý hệ thống thông tin
[Vùng mã nguồn mở trên developerWorks](http://www.ibm.com/developerworks/vn/views/opensource/libraryview.jsp)
Xem các bài viết về HTML, CSS, JavaScript,...
[Điện toán đám mây](http://www.ibm.com/developerworks/vn/views/cloud/libraryview.jsp)
Tìm hiểu về điện toán đám mây

Content-Language: en-US

Kp-eeAlive: timeout=10, max=46

Vary: Accept-Encoding


text:
Từ một nhà máy sản xuất chỉ 50 tấn/ngày với 500 lao động, đến nay Công ty cổ phần Hùng Vương đã có 5 nhà máy chế biến thủy hải sản trực thuộc, với công suất 50.000 tấn/năm và trên 4.500 lao động. Đây là một trong những nỗ lực của một doanh nghiệp chỉ mới thành lập trong một thời gian ngắn. Ông Dương Ngọc Minh, Chủ tịch HĐQT Công ty cổ phần Hùng Vương cho biết, được thành lập và đi vào hoạt động từ năm 2003, với tên gọi Công ty TNHH Hùng Vương, tọa lạc tại Khu công nghiệp Mỹ Tho, tỉnh Tiền Giang, với chức năng chế biến cá tra fillet đông lạnh xuất khẩu. Từ đầu năm 2007, với xu thế hội nhập kinh tế quốc tế và nhu cầu phát triển của công ty, Hùng Vương đã chuyển đổi mô hình hoạt động thành công ty cổ phần, mô hình hoạt động mới này đã giúp công ty huy động được nguồn vốn, đẩy mạnh đầu tư cho sản xuất.
Phân xưởng sản xuất cá tra xuất khẩu của Công ty cổ phần Hùng Vương. Ảnh: P.N.
Việt Nam đã là thành viên của Tổ chức Thương mại thế giới (WTO), ngành thủy sản của Việt Nam phải đối mặt với xu thế và yêu cầu khắt khe của thị trường thế giới về chất lượng và an toàn vệ sinh thực phẩm, nguồn gốc nguyên liệu… Ngoài ra, các doanh nghiệp thủy sản trong nước phải cạnh tranh với các doanh nghiệp nước ngoài đầu tư vào Việt Nam. Đây chính là lợi thế của Hùng Vương khi đã chủ động được nguồn nguyên liệu và nhất là vùng nguyên liệu này do chính công ty làm chủ đầu tư.Theo ông Minh, Hùng Vương hiện là một trong những doanh nghiệp xuất khẩu cá tra fillet đông lạnh lớn vào thị trường châu Âu và Trung Mỹ, hệ thống nuôi trồng thủy sản của công ty đã được công nhận hợp chuẩn các hệ thống quản lý chất lượng Safe Quality Food 1000 (SQF 1000) và được người tiêu dùng bình chọn là Hàng Việt Nam chất lượng cao trong nhiều năm liền. Hiện nay, các sản phẩm của công ty được xuất khẩu vào nhiều nước trên thị trường EU, Hoa Kỳ, Úc…Trong xu thế thương mại toàn cầu, việc phát triển các mặt hàng mang tính độc quyền như sản phẩm cá tra rất cần thiết, vì hiện nay, Việt Nam là một trong những nước có một lợi thế rất lớn nhờ vào hệ thống sông ngòi thích hợp cho việc phát triển nuôi trồng thủy sản. Bên cạnh đó, nhu cầu về tiêu thụ thủy sản chế biến trên thế giới ngày càng tăng, nhất là đối với sản phẩm cá tra, cá basa, do các sản phẩm này có thể thay thế cá thịt trắng có nguồn gốc từ vùng biển nhờ vào giá thành tương đối thấp, chất lượng ngon, sản lượng dồi dào và ổn định.Với những lợi thế trên, trong năm 2007, Hùng Vương đang tập trung đầu tư xây dựng nhằm năng cao hiệu quả kinh doanh. Trong đó, tập trung vào việc nuôi trồng thủy sản, công ty đang đầu tư gần 80 tỷ đồng để mở rộng hệ thống nuôi trồng thủy sản theo mô hình “nuôi cá tra công nghiệp”, nâng diện tích nuôi trồng từ 80 ha hiện nay lên 200 ha vào thời gian tới, đáp ứng 30%-40% nhu cầu nguyên liệu của công ty. Hiện nay, công ty đã thực hiện nhiều biện pháp, trong đó liên kết với các hộ nông dân có nguồn vốn ít nhưng có ao nước, có nguồn lao động, Hùng Vương sẽ đầu tư từ nguồn giống, thức ăn cho cá, thuốc, đến kỹ thuật nuôi trồng và thỏa thuận hỗ trợ bao tiêu hết sản phẩm cho hộ nuôi. Ngoài ra, Hùng Vương còn liên kết với các hộ nuôi theo dạng công ty đầu tư 60% nguồn vốn, còn lại 40% sẽ do hộ nuôi trồng đóng góp và cuối vụ sẽ chia tỷ lệ lãi suất theo phương thức Hùng Vương 40%, hộ nông dân 60%. Đây là một chiến lược táo bạo của Hùng Vương trong việc phát triển nguồn nguyên liệu, giúp nông dân yên tâm gắn bó và có trách nhiệm với công ty trong việc cung ứng nguyên liệu theo hợp đồng.Ông Minh cho biết: “Để phục vụ sản xuất đáp ứng nhu cầu lưu trữ hàng hóa của công ty, nhất là trong lúc nguồn nguyên liệu không ổn định hoặc thị trường tiêu thụ có biến động và nhu cầu thuê kho của các doanh nghiệp hoạt động trong lĩnh vực xuất khẩu thủy sản, nông sản… công ty đang đầu tư xây dựng thêm một kho lạnh có công xuất 30.000 tấn tại Khu công nghiệp Tân Tạo và tiếp tục xây dựng nhà máy sản xuất với công suất 100 tấn/ngày tại Vĩnh Long, dự kiến đi vào hoạt động vào tháng 8-2007”.
PHƯỚC NGỌC

WARC-Type: response

Content-Type: application/http; msgtype=response

Content-Type: text/html

Accept-Ranges: bytes

Connection: close


text:
- Phim sex phụ đề tiếng việt, phim sex, Phim sex phụ đề tiếng việt, phim sex phu de, phim sex online nhanh nhat, xem phim sex online nhanh nhat voi nhieu the loai phim hay va phim cap ba hap dan va phim sex nhat ban. Chúc các bạn xem phim sex thật vui vẻ tại Phimsextructuyen.net nhé!
- Lauxanh.us, lauxanh. us, phim sex lau xanh, lauxanh.us, lauxanh. us, phim sex lau xanh, lầu xanh, lau xanh .us, dien dan lau xanh, phim cap 3 lau xanh, phim sex lầu xanh, Xem phim cấp ba online với nhiều thể loại phim cap ba việt, hàn quốc, nhật bản và các loại phim cap 3 phu de khác.
- Phim xet yen vi, sex yến vy, phim xet yen vi, sex yến vy, phim sex tụt tuần là sướng gây cảm hứng mạnh nhất, phim sex hay nhat viet nam hiện nay, xem phim ngoai tinh, tâm lý ngoại tình, phim ngoại tình cánh đàn ông, phim ngoại tình hay, phim địt nhau hấp dẫn của giới trẻ hiện nay với.
- Phim vung trom, phim sex vungtrom, phim sex viet nam, phim phá trinh, phim cưỡng bức, girl xinh, phim hoạt hình, phim sex châu á, phim sex nhật bản, phim hoạt hình 3d, phim sex trẻ đẹp, phim cấp 3, sinh viên làm tình, sinh viên, đồng tính nứ, đồng tính nam, phim trung quốc, sex việt nam, hàng khủng, vú to, phim sex tra tấn, hiếp dâm, phim sex hàn quốc, phim thủ dâm, em xinh trẻ đẹp.
5 scandal tình dục tai tiếng nhất của 'sao' châu Á
Theo bình chọn của trang Cnngo, clip giường chiếu của ca sĩ Hoàng Thùy Linh lọt vào top 5 sự kiện gây chấn động làng giải trí châu Á trong những năm gần đây.
1. Katrina Halili - diễn viên Philippines
Katrina Halili từng 2 lần được tạp chí FHM bình chọn là mỹ nhân gợi cảm nhất Philippines vào các năm 2006 và 2007.
Cuối năm 2008, một số đoạn clip sex ghi lại hình ảnh nóng bỏng giữa cô và bác sĩ phẫu thuật thẩm mỹ Hayden Kho bị tung lên mạng, rồi bị in ra đĩa DVD và bán tràn lan trên thị trường.
Người đẹp khẳng định, cô không hề biết đến sự tồn tại của những clip sex này. Sai lầm duy nhất của cô là đã cả tin, đem lòng yêu Hayden Kho.
Vụ việc ảnh hưởng xấu đến cả hai nhân vật chính. Katrina Halili bị hủy bỏ nhiều hợp đồng đóng phim và trình diễn thời trang, còn Hayden Kho bị tước giấy phép hành nghề. Đến nay, cảnh sát Philippines vẫn chưa tìm ra được thủ phạm phát tán clip sex này.
2. Nghi án liên quan đến Hoa hậu Nhật Bản Hiroko Mima
Hiroko Mima sinh năm 1986, đăng quang Hoa hậu Hoàn vũ Nhật Bản năm 2008. Cô từng sang Việt Nam tham dự Miss Universe 2008.
Tháng 11/2009, một đoạn băng sex bị tung lên mạng, trong đó, hai người đẹp - được cho là giống với Hoa hậu Nhật Bản Hiroko Mima và Hoa hậu Trinidad & Tobago Anya Ayoung Chee - đang cùng diễn cảnh giường chiếu với Wyatt Gallery - bạn trai của Ayoung-Chee.
Báo chí Nhật Bản được dịp xôn xao. Dư luận nước này gay gắt đòi tước vương miện của Hiroko Mima. Sự việc chỉ lắng xuống sau khi Gallery lên tiếng khẳng định, chỉ có Anya Ayoung Chee có mặt trong băng sex, còn nhân vật nữ kia là một người có ngoại hình giống Mima.
Tuy được minh oan, nhưng hình ảnh của Hiroko Mima bị ảnh hưởng nghiêm trọng. Một thời gian sau, cô trao lại vương miện cho người kế nhiệm là Hoa hậu Emiri Miyasaka.
3. Hoàng Thùy Linh - Vàng Anh gây sốc
Sinh năm 1988, Hoàng Thùy Linh từng là một hot girl, diễn viên, ca sĩ được yêu thích tại Việt Nam.
Năm 2007, một số đoạn clip ghi lại cảnh giường chiếu giữa cô và bạn trai cũ bị phát tán trên mạng. Thời điểm đó, Thùy Linh đang là diễn viên chính trong serie phim truyền hình Nhật ký Vàng Anh - một bộ phim đề cập đến tuổi học trò trong sáng.
Theo Cnngo, đến nay, clip sex của Hoàng Thùy Linh vẫn là scandal tai tiếng nhất trong lịch sử showbiz Việt Nam. Bị chỉ trích từ nhiều phía, Hoàng Thùy Linh đã gửi lời xin lỗi đến người thân, bạn bè và các fan trong một chương trình truyền hình do VTV tổ chức.
Bị so sánh với những clip nóng của Paris Hilton và Kim Kardashian, nhưng đoạn băng đã không dập tắt được sự nghiệp của Hoàng Thùy Linh. Tờ New York Times nhận xét, sự việc này thậm chí còn là một cơ hội để cô phát triển, gây dựng lại danh tiếng cho mình.
Hiện Hoàng Thùy Linh từng bước khẳng định tên tuổi và hình ảnh của mình trong làng giải trí Việt Nam.
4. Trần Quán Hy và loạt ảnh nóng với các ngôi sao gốc Hoa
Là một tài tử điện ảnh đẹp trai, nổi tiếng, Trần Quán Hy có hàng tá cuộc tình với các mỹ nhân của làng showbiz Trung Quốc, Hong Kong, Đài Loan.
Năm 2008, khoảng 1.300 bức ảnh nóng bị phát tán trên mạng, ghi lại hình ảnh nóng bỏng của Quán Hy với những ngôi sao nữ nổi tiếng như Chung Hân Đồng, Trương Bá Chi, Trần Văn Viên, Dương Vĩnh Tình…
Sự việc gây chấn động cả châu Á. Quán Hy phải ra nước ngoài một thời gian dài để trốn tránh dư luận. Những người đẹp từng thân mật với anh cũng phải chịu không biết bao hệ lụy. Mới đây, anh trở về Hong Kong để tham gia bộ phim "The Sniper".
5. MC Cừ Mỹ Phượng lộ phim sex với người tình
Cừ Mỹ Phượng (Chu Mei-feng) vốn là một chính trị gia, một người dẫn chương trình khá nổi tiếng ở Đài Loan.
Năm 2001, một người bạn xấu của Mỹ Phượng lén lắp camera trong phòng ngủ của cô, ghi lại toàn bộ chuyện giường chiếu giữa cô và người tình - một người đàn ông đã có vợ. Đoạn băng sau đó được gửi cho một tờ báo lá cải nước này. Nó nhanh chóng bị phát tán là làm chấn động cả châu Á. Vụ việc được đồn đoán có liên quan đến một âm mưu chính trị nhằm hạ thấp uy tín của Mỹ Phượng. Ngay sau khi sự việc xảy ra, Mỹ Phượng đã phải từ bỏ chức vụ và sống ẩn dật một thời gian dài. Phim sex online, phim con heo online, phim xxx online, phim tâm lý online, phim cấp ba online, phim người lớn miễn phí. Chúc các bạn xem phim sex thật vui vẻ tại phim sex and zen 3d, phim nhục bồ đoàn, phim extreme ecstasy 2011, phim cảm xúc thăng hoa nhé!
Post a Comment

markdown:
**Phim Tâm Lý Tình Cảm Xã Hội 18+** **Maiko Inoue** **Natsuki Ikeda, Sayuri Ootomo, Kaikawa Hitomi, Mikie Hara, Rina Akiyama** **Phim Cấp 3 ( 18+ )** **Japanese Sexy Gravure Idol Production** **Nhật Bản** **150 Phút** **2011**
- Phim sex phụ đề tiếng việt, phim sex, Phim sex phụ đề tiếng việt, phim sex phu de, phim sex online nhanh nhat, xem phim sex online nhanh nhat voi nhieu the loai phim hay va phim cap ba hap dan va phim sex nhat ban. Chúc các bạn xem phim sex thật vui vẻ tại Phimsextructuyen.net nhé!
- Lauxanh.us, lauxanh. us, phim sex lau xanh, lauxanh.us, lauxanh. us, phim sex lau xanh, lầu xanh, lau xanh .us, dien dan lau xanh, phim cap 3 lau xanh, phim sex lầu xanh, Xem phim cấp ba online với nhiều thể loại phim cap ba việt, hàn quốc, nhật bản và các loại phim cap 3 phu de khác.
- Phim xet yen vi, sex yến vy, phim xet yen vi, sex yến vy, phim sex tụt tuần là sướng gây cảm hứng mạnh nhất, phim sex hay nhat viet nam hiện nay, xem phim ngoai tinh, tâm lý ngoại tình, phim ngoại tình cánh đàn ông, phim ngoại tình hay, phim địt nhau hấp dẫn của giới trẻ hiện nay với.
- Phim vung trom, phim sex vungtrom, phim sex viet nam, phim phá trinh, phim cưỡng bức, girl xinh, phim hoạt hình, phim sex châu á, phim sex nhật bản, phim hoạt hình 3d, phim sex trẻ đẹp, phim cấp 3, sinh viên làm tình, sinh viên, đồng tính nứ, đồng tính nam, phim trung quốc, sex việt nam, hàng khủng, vú to, phim sex tra tấn, hiếp dâm, phim sex hàn quốc, phim thủ dâm, em xinh trẻ đẹp.
5 scandal tình dục tai tiếng nhất của 'sao' châu Á
Theo bình chọn của trang Cnngo, clip giường chiếu của ca sĩ Hoàng Thùy Linh lọt vào top 5 sự kiện gây chấn động làng giải trí châu Á trong những năm gần đây.
1. Katrina Halili - diễn viên Philippines
Katrina Halili từng 2 lần được tạp chí FHM bình chọn là mỹ nhân gợi cảm nhất Philippines vào các năm 2006 và 2007.
Cuối năm 2008, một số đoạn clip sex ghi lại hình ảnh nóng bỏng giữa cô và bác sĩ phẫu thuật thẩm mỹ Hayden Kho bị tung lên mạng, rồi bị in ra đĩa DVD và bán tràn lan trên thị trường.
Người đẹp khẳng định, cô không hề biết đến sự tồn tại của những clip sex này. Sai lầm duy nhất của cô là đã cả tin, đem lòng yêu Hayden Kho.
Vụ việc ảnh hưởng xấu đến cả hai nhân vật chính. Katrina Halili bị hủy bỏ nhiều hợp đồng đóng phim và trình diễn thời trang, còn Hayden Kho bị tước giấy phép hành nghề. Đến nay, cảnh sát Philippines vẫn chưa tìm ra được thủ phạm phát tán clip sex này.
2. Nghi án liên quan đến Hoa hậu Nhật Bản Hiroko Mima
Hiroko Mima sinh năm 1986, đăng quang Hoa hậu Hoàn vũ Nhật Bản năm 2008. Cô từng sang Việt Nam tham dự Miss Universe 2008.
Tháng 11/2009, một đoạn băng sex bị tung lên mạng, trong đó, hai người đẹp - được cho là giống với Hoa hậu Nhật Bản Hiroko Mima và Hoa hậu Trinidad & Tobago Anya Ayoung Chee - đang cùng diễn cảnh giường chiếu với Wyatt Gallery - bạn trai của Ayoung-Chee.
Báo chí Nhật Bản được dịp xôn xao. Dư luận nước này gay gắt đòi tước vương miện của Hiroko Mima. Sự việc chỉ lắng xuống sau khi Gallery lên tiếng khẳng định, chỉ có Anya Ayoung Chee có mặt trong băng sex, còn nhân vật nữ kia là một người có ngoại hình giống Mima.
Tuy được minh oan, nhưng hình ảnh của Hiroko Mima bị ảnh hưởng nghiêm trọng. Một thời gian sau, cô trao lại vương miện cho người kế nhiệm là Hoa hậu Emiri Miyasaka.
3. Hoàng Thùy Linh - Vàng Anh gây sốc
Sinh năm 1988, Hoàng Thùy Linh từng là một hot girl, diễn viên, ca sĩ được yêu thích tại Việt Nam.
Năm 2007, một số đoạn clip ghi lại cảnh giường chiếu giữa cô và bạn trai cũ bị phát tán trên mạng. Thời điểm đó, Thùy Linh đang là diễn viên chính trong serie phim truyền hình Nhật ký Vàng Anh - một bộ phim đề cập đến tuổi học trò trong sáng.
Theo Cnngo, đến nay, clip sex của Hoàng Thùy Linh vẫn là scandal tai tiếng nhất trong lịch sử showbiz Việt Nam. Bị chỉ trích từ nhiều phía, Hoàng Thùy Linh đã gửi lời xin lỗi đến người thân, bạn bè và các fan trong một chương trình truyền hình do VTV tổ chức.
Bị so sánh với những clip nóng của Paris Hilton và Kim Kardashian, nhưng đoạn băng đã không dập tắt được sự nghiệp của Hoàng Thùy Linh. Tờ New York Times nhận xét, sự việc này thậm chí còn là một cơ hội để cô phát triển, gây dựng lại danh tiếng cho mình.
Hiện Hoàng Thùy Linh từng bước khẳng định tên tuổi và hình ảnh của mình trong làng giải trí Việt Nam.
4. Trần Quán Hy và loạt ảnh nóng với các ngôi sao gốc Hoa
Là một tài tử điện ảnh đẹp trai, nổi tiếng, Trần Quán Hy có hàng tá cuộc tình với các mỹ nhân của làng showbiz Trung Quốc, Hong Kong, Đài Loan.
Năm 2008, khoảng 1.300 bức ảnh nóng bị phát tán trên mạng, ghi lại hình ảnh nóng bỏng của Quán Hy với những ngôi sao nữ nổi tiếng như Chung Hân Đồng, Trương Bá Chi, Trần Văn Viên, Dương Vĩnh Tình…
Sự việc gây chấn động cả châu Á. Quán Hy phải ra nước ngoài một thời gian dài để trốn tránh dư luận. Những người đẹp từng thân mật với anh cũng phải chịu không biết bao hệ lụy. Mới đây, anh trở về Hong Kong để tham gia bộ phim "The Sniper".
5. MC Cừ Mỹ Phượng lộ phim sex với người tình
Cừ Mỹ Phượng (Chu Mei-feng) vốn là một chính trị gia, một người dẫn chương trình khá nổi tiếng ở Đài Loan.
Năm 2001, một người bạn xấu của Mỹ Phượng lén lắp camera trong phòng ngủ của cô, ghi lại toàn bộ chuyện giường chiếu giữa cô và người tình - một người đàn ông đã có vợ. Đoạn băng sau đó được gửi cho một tờ báo lá cải nước này. Nó nhanh chóng bị phát tán là làm chấn động cả châu Á. Vụ việc được đồn đoán có liên quan đến một âm mưu chính trị nhằm hạ thấp uy tín của Mỹ Phượng. Ngay sau khi sự việc xảy ra, Mỹ Phượng đã phải từ bỏ chức vụ và sống ẩn dật một thời gian dài. Phim sex online, phim con heo online, phim xxx online, phim tâm lý online, phim cấp ba online, phim người lớn miễn phí. Chúc các bạn xem phim sex thật vui vẻ tại
[phim sex and zen 3d](http://www.thevoiceviet.info/), [phim nhục bồ đoàn](http://www.thevoiceviet.info/), [phim extreme ecstasy 2011](http://www.thevoiceviet.info/), [phim cảm xúc thăng hoa](http://www.thevoiceviet.info/)nhé!
## Post a Comment

WARC-Truncated: length

Content-Type: text/html; charset=UTF-8

Cache-Control: private, max-age=0

X-Content-Type-Options: nosniff

X-XSS-Protection: 1; mode=block

Server: GSE