Thiết lập kết nối JDBC

Một phần của tài liệu Tài liệu JDBC Java JDBC cần dùng (Trang 22 - 46)

Kiểu 4: JDBC kết nối qua các trình điều khiển đặc thù ở xa JDBC kết nối qua các trình điều khiển đặc thù ở xa

1.4 Thiết lập kết nối JDBC

 Nạp trình điều khiểnNạp trình điều khiển

• DriverManager DriverManager

 Tạo đối tượng kết nốiTạo đối tượng kết nối

• Connection Connection

 Tạo đối tượng thực thi câu lệnhTạo đối tượng thực thi câu lệnh

• Statement Statement

 PreparedStatement PreparedStatement

• CallableStatement CallableStatement

1.4 Thiết lập kết nối JDBC 1.4 Thiết lập kết nối JDBC

Nạp trình điều khiển Nạp trình điều khiển

 Cấu trúc Cấu trúc

Class.forName(<driverName>).newInstance();

Class.forName(<driverName>).newInstance();

Với cầu nối JDBC-ODBC, trình điều khiển là: Với cầu nối JDBC-ODBC, trình điều khiển là:

sun.jdbc.odbc.JdbcOdbcDriver sun.jdbc.odbc.JdbcOdbcDriver

 Với các trình điểu khiển khác ta sẽ có một Với các trình điểu khiển khác ta sẽ có một driverName tương ứng:

driverName tương ứng:

• COM.cloudscape.core.RmiJdbcDriver

• oracle.jdbc.driver.OracleDriver…oracle.jdbc.driver.OracleDriver…

 Ví dụ: Ví dụ:

String DBDriver = sun.jdbc.odbc.JdbcOdbcDriver;

String DBDriver = sun.jdbc.odbc.JdbcOdbcDriver;

try{ Class.forName(DBDriver).newInstance();

try{ Class.forName(DBDriver).newInstance();

}catch(Exception ex){ex.printStackTrace();}

}catch(Exception ex){ex.printStackTrace();}

1.4 Thiết lập kết nối JDBC 1.4 Thiết lập kết nối JDBC

Tạo đối tượng kết nối Tạo đối tượng kết nối

 Cấu trúc Cấu trúc

Connection <objectNameCONN> = Connection <objectNameCONN> =

DriverManager.getConnection(<url>, DriverManager.getConnection(<url>,

<user>, <pass>);

<user>, <pass>);

 Trong đó: Trong đó:

• objectNameCONN: tên đối tượng kết nốiobjectNameCONN: tên đối tượng kết nối

• url = jdbc:<subProtocol>:<subName>url = jdbc:<subProtocol>:<subName>

 subProtocol: giao thức con tương ứng với loại cơ sở dữ liệusubProtocol: giao thức con tương ứng với loại cơ sở dữ liệu

 subName: tên của cơ sở dữ liệusubName: tên của cơ sở dữ liệu

• user, pass: tên và mật khẩu người dùng khi đăng nhập user, pass: tên và mật khẩu người dùng khi đăng nhập vào cơ sở dữ liệu

vào cơ sở dữ liệu

 Ví dụ: Ví dụ:

Ví dụ tạo đối tượng kết nối Ví dụ tạo đối tượng kết nối

//tao chuoi ket noi //tao chuoi ket noi static final String static final String

ConUrl="jdbc:odbc:ShoppingCart";

ConUrl="jdbc:odbc:ShoppingCart";

//mat khau va ten su dung co the trong //mat khau va ten su dung co the trong static final String userName="";

static final String userName="";

static final String passWord="";

static final String passWord="";

//tao doi tuong ket noi thong qua trinh dieu //tao doi tuong ket noi thong qua trinh dieu

khien da dang ky voi DriverManager khien da dang ky voi DriverManager

Connection conn = DriverManager.getConnection Connection conn = DriverManager.getConnection

(ConUrl,userName,passWord);

(ConUrl,userName,passWord);

1.4 Thiết lập kết nối JDBC 1.4 Thiết lập kết nối JDBC

Tạo đối tượng thực thi Tạo đối tượng thực thi

 Sau khi hoàn tất việc nạp trình điều khiển và tạo đối Sau khi hoàn tất việc nạp trình điều khiển và tạo đối tượng kết nối

tượng kết nối

 Có 3 cách:Có 3 cách:

Statement <objectNameSTMT> = Statement <objectNameSTMT> =

<objectNameCONN>.

<objectNameCONN>.createStatement();createStatement();

PreparedStatement <objectNamePRESTMT> = PreparedStatement <objectNamePRESTMT> =

<objectNameCONN>.

<objectNameCONN>.prepareStatement();prepareStatement();

CallableStatement <objectNameCALLSTMT> = CallableStatement <objectNameCALLSTMT> =

<objectNameCONN>.

<objectNameCONN>.prepareCall();prepareCall();

  Ngoài cách gọi phương thức đơn giản như Ngoài cách gọi phương thức đơn giản như trên, tương ứng còn có các phương thức có trên, tương ứng còn có các phương thức có

tham số.

tham số.

Cách tạo đối tượng với Statement Cách tạo đối tượng với Statement

 Phương thức Phương thức

• createStatement()createStatement()

• createStatement(int resultSetTypecreateStatement(int resultSetType, int , int resultSetConcurrencyresultSetConcurrency))

• createStatement(int resultSetTypecreateStatement(int resultSetType, int , int resultSetConcurrency,resultSetConcurrency, int resultSetHoldabilityint resultSetHoldability))

 Ý nghĩa: Ý nghĩa:

resultSetTyperesultSetType: cho biết kiểu ResultSet có cuộn được : cho biết kiểu ResultSet có cuộn được không?

không?

resultSetConcurrency: cho biết ResultSet có cập nhật resultSetConcurrency: cho biết ResultSet có cập nhật được hay không?

được hay không?

resultSetHoldabilityresultSetHoldability: cho biết ResultSet có khả năng đi : cho biết ResultSet có khả năng đi tiếp được hay không?

tiếp được hay không?

 Khi thực thi câu lệnh SQL ta sẽ nhận được Khi thực thi câu lệnh SQL ta sẽ nhận được một tập kết quả (ResultSet) – NGHIÊN CỨU một tập kết quả (ResultSet) – NGHIÊN CỨU SAU SAU

Ví dụ với Statement Ví dụ với Statement

//Tập kết quả ResultSet không cuộn được //Tập kết quả ResultSet không cuộn được

Statement stmt = conn.createStatement();

Statement stmt = conn.createStatement();

//Tập kết quả ResultSet có cuộn được //Tập kết quả ResultSet có cuộn được

Statement stmt = conn.createStatement Statement stmt = conn.createStatement (ResultSet.TYPE_SCROLL_SENSITIVE, (ResultSet.TYPE_SCROLL_SENSITIVE,

ResultSet.CONCUR_UPDATABLE);

ResultSet.CONCUR_UPDATABLE);

Cách tạo đối tượng với PreparedStatement Cách tạo đối tượng với PreparedStatement

 PreparedStatement (con của Statement) thay PreparedStatement (con của Statement) thay thế khá hiệu quả cho Statement với những thế khá hiệu quả cho Statement với những

lý do sau:

lý do sau:

• Câu lệnh SQL trong PreparedStatement được biên dịch Câu lệnh SQL trong PreparedStatement được biên dịch trước và chỉ một lần, Statement thì ngược lại

trước và chỉ một lần, Statement thì ngược lại  hiệu quả hiệu quả về mặt thời gian!

về mặt thời gian!

• Câu lệnh SQL sử dụng trong PreparedStatement có tham Câu lệnh SQL sử dụng trong PreparedStatement có tham số, nên sẽ mềm dẻo trong truy vấn CSDL hơn.

số, nên sẽ mềm dẻo trong truy vấn CSDL hơn.

 Phương thức: Phương thức:

• prepareStatement(String sqlprepareStatement(String sql))

• prepareStatement(String sqlprepareStatement(String sql, int , int resultSetTyperesultSetType, int , int

resultSetConcurrency resultSetConcurrency))

• prepareStatement(String sql, int prepareStatement(String sql, int resultSetType, int resultSetType, int resultSetConcurrency,

resultSetConcurrency, int int resultSetHoldabilityresultSetHoldability))

Cách tạo đối tượng với PreparedStatement Cách tạo đối tượng với PreparedStatement

(tiếp..) (tiếp..)

 Ví dụ: Ví dụ:

String strSQL = “UPDATE tblStudent SET

String strSQL = “UPDATE tblStudent SET fullName=?fullName=?

WHERE

WHERE id=?id=?”;”;

PreparedStatement preStmt = PreparedStatement preStmt =

PRECONN.prepareStatement(strSQL) PRECONN.prepareStatement(strSQL)

 Gán giá trị cho các tham số, sử dụng Gán giá trị cho các tham số, sử dụng phương thức của đối tượng

phương thức của đối tượng PreparedStatement

PreparedStatement

• Cấu trúc: setXXXCấu trúc: setXXX(<STT>,<Giá trị>)(<STT>,<Giá trị>)

• Trong đó:Trong đó:

 XXX là kiểu dữ liệu của tham số cần gán, XXX là kiểu dữ liệu của tham số cần gán,

 STT là số thứ tự của tham số (bắt đầu từ 1…)STT là số thứ tự của tham số (bắt đầu từ 1…)

 Giá trị mà tham số nhậnGiá trị mà tham số nhận

• VD: VD: preStmt.setString(1, “Tran Quoc Tuan”);preStmt.setString(1, “Tran Quoc Tuan”);

preStmt.setInt(2,28);

preStmt.setInt(2,28);

So sánh sử dụng Statement với So sánh sử dụng Statement với

PreparedStatement PreparedStatement

String sql= “UPDATE tblStudent SET fullName=

String sql= “UPDATE tblStudent SET fullName=

‘Tran Quoc Tuan’ WHERE Tran Quoc Tuan’ WHERE id=28id=28”;”;

stmt.executeUpdate(sql);

stmt.executeUpdate(sql);

String sql= “UPDATE tblStudent SET fullName=

String sql= “UPDATE tblStudent SET fullName=

‘Tran Quoc Tuan’ WHERE Tran Quoc Tuan’ WHERE id=72id=72”;”;

stmt.executeUpdate(sql);

stmt.executeUpdate(sql);

String sql= “UPDATE tblStudent SET

String sql= “UPDATE tblStudent SET fullName=?fullName=?

WHERE WHERE id=?id=?”;”;

PreparedStatement preStmt = conn.prepareStatement(sql);

PreparedStatement preStmt = conn.prepareStatement(sql);

preStmt.setString(1, ‘Tran Quoc Tuan’);

preStmt.setString(1, ‘Tran Quoc Tuan’);

preStmt.setInt(2, 28);

preStmt.setInt(2, 28);

preStmt.executeUpdate();

preStmt.executeUpdate();

preStmt.setInt(2,72);

preStmt.setInt(2,72);

Cách tạo đối tượng với CallableStatement Cách tạo đối tượng với CallableStatement

 Lớp con của PreparedStatement Lớp con của PreparedStatement

 Phương thức: Phương thức:

• prepareCall(String prepareCall(String sqlsql))

• prepareCall(String prepareCall(String sqlsql, int , int resultSetTyperesultSetType, int , int

resultSetConcurrency resultSetConcurrency))

• prepareCall(String sql, int prepareCall(String sql, int resultSetTyperesultSetType, int, int resultSetConcurrency,

resultSetConcurrency, int int resultSetHoldabilityresultSetHoldability))

 Ý nghĩa: Ý nghĩa:

• sql: tập lệnh SQL được sắp xếp trong một đơn sql: tập lệnh SQL được sắp xếp trong một đơn vị logic để thực hiện một nhiệm vụ riêng biệt - vị logic để thực hiện một nhiệm vụ riêng biệt - thủ tục lưu trữ sẵn (stored procedures)

thủ tục lưu trữ sẵn (stored procedures)

• Các tham số còn lại tương tự Statement Các tham số còn lại tương tự Statement

Cách tạo đối tượng với CallableStatement Cách tạo đối tượng với CallableStatement

(tiếp..) (tiếp..)

 Tạo thủ tục lưu trữ sẵn để sử dụng cho Tạo thủ tục lưu trữ sẵn để sử dụng cho tham số sql trong prepareCall()

tham số sql trong prepareCall()

 Khi đó đối tượng được khai báo như sau Khi đó đối tượng được khai báo như sau

CallableStatement callStmt = CallableStatement callStmt = CALLCONN.prepareCall(“{call CALLCONN.prepareCall(“{call

MARK_STUDENT

MARK_STUDENT }”) }”)

String strProcedure = “create procedure MARK_STUDENT”+

“as select STUDENT.NAME, MARK.VALUE “+

“from STUDENT, MARK “+

“where STUDENT.ID = 2008 order by NAME”;

Statement stmt = conn.createStatement();

stmt.executeUpdate(strProcedure);

Nghiên cứu Transaction Nghiên cứu Transaction

Tạo Connection

Chấm dứt Auto commit Các câu lệnh SQL (INSERT

UPDATE, DELETE,…)

Thực thi commit Thực thi commit

Các câu lệnh SQL (INSERT UPDATE, DELETE,…)

Transaction

Transaction

Nghiên cứu Transaction Nghiên cứu Transaction

 Một transaction: Một transaction:

• Gọi conn.setAutoCommit(false)Gọi conn.setAutoCommit(false)

• Mọi câu lệnh SQL không được xác lập thực thi, được lưu Mọi câu lệnh SQL không được xác lập thực thi, được lưu trữ trong vùng rollback của CSDL

trữ trong vùng rollback của CSDL

• Khi có lời gọi conn.commit() Khi có lời gọi conn.commit()  các câu lệnh được thực các câu lệnh được thực thi đồng loạt

thi đồng loạt

• Nếu không muốn thực thi cập nhật có thể gọi Nếu không muốn thực thi cập nhật có thể gọi conn.rollback()

conn.rollback()

 Phương thức rollback() dùng để loại bỏ mọi Phương thức rollback() dùng để loại bỏ mọi tác dụng của một transaction lúc chưa thực tác dụng của một transaction lúc chưa thực

hiện commit() hiện commit()

• Giá trị sẽ hoàn lại là các giá trị của transaction đã Giá trị sẽ hoàn lại là các giá trị của transaction đã commit trước đó.

commit trước đó.

Nghiên cứu về ResultSet Nghiên cứu về ResultSet

 ResultSet là tập kết quả nhận được sau khi thực ResultSet là tập kết quả nhận được sau khi thực thi truy vấn câu lệnh SQL vào CSDL.

thi truy vấn câu lệnh SQL vào CSDL.

 ResultSet có khả năng cuộn được hay không phụ ResultSet có khả năng cuộn được hay không phụ thuộc vào đối tượng thực thi tạo ra.

thuộc vào đối tượng thực thi tạo ra.

 Các giá trị hằng của ResultSet sau sẽ được sử dụng Các giá trị hằng của ResultSet sau sẽ được sử dụng khi tạo đối tượng thực thi

khi tạo đối tượng thực thi

• Kiểu ResultSet (resultSetType)Kiểu ResultSet (resultSetType)

TYPE_FORWARD_ONLYTYPE_FORWARD_ONLY: ResultSet nhận được chỉ có thể duyệt : ResultSet nhận được chỉ có thể duyệt một chiều từ BOF

một chiều từ BOF  EOF EOF

TYPE_SCROLL_INSENSITIVE: duyệt được 2 chiều nhưng không TYPE_SCROLL_INSENSITIVE: duyệt được 2 chiều nhưng không cảm nhận được sự thay đổi số liệu trong nó.

cảm nhận được sự thay đổi số liệu trong nó.

TYPE_SCROLL_SENSITIVE: duyệt hai chiều và cảm nhận được sự TYPE_SCROLL_SENSITIVE: duyệt hai chiều và cảm nhận được sự thay đổi số liệu.

thay đổi số liệu.

• Kiểu ConcurrencyKiểu Concurrency

CONCUR_READ_ONLY: ResultSet là không cập nhậtCONCUR_READ_ONLY: ResultSet là không cập nhật

CONCUR_UPDATABLE: ResultSet là có thể cập nhậtCONCUR_UPDATABLE: ResultSet là có thể cập nhật

Nghiên cứu về ResultSet Nghiên cứu về ResultSet

Các vị trí đặc biệt trong ResultSet Các vị trí đặc biệt trong ResultSet

 Vị trí đầu ResultSet ( Vị trí đầu ResultSet ( beforeFirst beforeFirst ) )

• không chứa record, thường được coi là BOFkhông chứa record, thường được coi là BOF

• Kiểm tra bằng phương thức isBeforeFirst()Kiểm tra bằng phương thức isBeforeFirst()

 Vị trí cuối ResultSet ( Vị trí cuối ResultSet ( afterLast afterLast ) )

• không chứa record, thường được coi là EOFkhông chứa record, thường được coi là EOF

• Kiểm tra bằng phương thức isAfterLast()Kiểm tra bằng phương thức isAfterLast()

 Vị trí đầu ( Vị trí đầu ( First) First )

• bản ghi đầu tiên của ResultSetbản ghi đầu tiên của ResultSet

• Kiểm tra bằng phương thức isFirst()Kiểm tra bằng phương thức isFirst()

 Vị trí cuối ( Vị trí cuối ( Last Last ) )

• bản ghi cuối cùng của ResultSetbản ghi cuối cùng của ResultSet

• Kiểm tra bằng phương thức isLast()Kiểm tra bằng phương thức isLast()

Nghiên cứu về ResultSet Nghiên cứu về ResultSet

Các phương thức di chuyển trong ResultSet Các phương thức di chuyển trong ResultSet

 next() next()

 di chuyển sang bản ghi kế tiếp, giá trị nhận về false di chuyển sang bản ghi kế tiếp, giá trị nhận về false nếu không còn bản ghi để di chuyển.

nếu không còn bản ghi để di chuyển.

 previous() previous()

 di chuyển về bản ghi trước đó.di chuyển về bản ghi trước đó.

 absolute(int lnumber) absolute(int lnumber)

 di chuyển đến bản ghi có số thứ tự là lnumberdi chuyển đến bản ghi có số thứ tự là lnumber

• Nếu lnumber > 0 thì số thứ tự được tính từ FirstNếu lnumber > 0 thì số thứ tự được tính từ First

• Nếu lnumber < 0 thì số thứ tự được tính từ LastNếu lnumber < 0 thì số thứ tự được tính từ Last

 relative(int lnumber) relative(int lnumber)

 di chuyển sang bản ghi có vị trí tương đối so với bản di chuyển sang bản ghi có vị trí tương đối so với bản ghi hiện hành.

ghi hiện hành.

Nghiên cứu về ResultSet Nghiên cứu về ResultSet

Ví dụ: Duyệt tập kết quả nhận được Ví dụ: Duyệt tập kết quả nhận được

String strSelect = “SELECT fullName, birthDay FROM String strSelect = “SELECT fullName, birthDay FROM

tblStudent WHERE (id>=28) AND (id<=100)”;

tblStudent WHERE (id>=28) AND (id<=100)”;

//Doi tuong thuc thi nhan ve ResultSet cuon duoc //Doi tuong thuc thi nhan ve ResultSet cuon duoc Statement stmt = conn.createStatement

Statement stmt = conn.createStatement

(ResultSet.TYPE_SCROLL_SENSITIVE, (ResultSet.TYPE_SCROLL_SENSITIVE,

ResultSet.CONCUR_UPDATABLE);

ResultSet.CONCUR_UPDATABLE);

//Nhan ve tap ket qua //Nhan ve tap ket qua

ResultSet rs = stmt.executeQuery(strSelect);

ResultSet rs = stmt.executeQuery(strSelect);

//di chuyen den ban ghi thu 6 //di chuyen den ban ghi thu 6 rs.absolute(6);

rs.absolute(6);

//di chuyen nguoc lai 4 ban ghi //di chuyen nguoc lai 4 ban ghi rs.relative(-4);

rs.relative(-4);

//di chuyen xuong cuoi ResultSet (afterLast) //di chuyen xuong cuoi ResultSet (afterLast) rs.afterLast();

rs.afterLast();

//Duyet nguoc lai tu EOF

//Duyet nguoc lai tu EOF  BOF BOF while(rs.previous()){//Khoi lenh}

while(rs.previous()){//Khoi lenh}

Nghiên cứu về ResultSet Nghiên cứu về ResultSet

Cập nhật cho ResultSet Cập nhật cho ResultSet

 Sử dụng: Sử dụng:

• updateXXX(<tên trường>,<giá trị mới>)updateXXX(<tên trường>,<giá trị mới>)

• Cập nhật một trường cho bản ghi hiện hành, XXX là loại Cập nhật một trường cho bản ghi hiện hành, XXX là loại dữ liệu được cập nhật

dữ liệu được cập nhật

• Ví dụ:Ví dụ:

 updateFloat()updateFloat()

 updateString()…updateString()…

 Ghi nhận sự cập nhật: Ghi nhận sự cập nhật:

• updateRow()updateRow()

• Mọi thay đổi trong ResultSet sẽ được chép lại vào trong Mọi thay đổi trong ResultSet sẽ được chép lại vào trong CSDLCSDL

 Huỷ bỏ thay đổi đã xác lập bởi updateXXX() Huỷ bỏ thay đổi đã xác lập bởi updateXXX()

• sử dụng phương thức: sử dụng phương thức: cancelRowUpdatescancelRowUpdates()()

Ví dụ về cập nhật cho ResultSet Ví dụ về cập nhật cho ResultSet

//xuong ban ghi thu 50 //xuong ban ghi thu 50 rs.absolute(50);

rs.absolute(50);

//Cap nhat lai ngay sinh //Cap nhat lai ngay sinh

rs.updateString(“birthDay”, “20/07/1948”);

rs.updateString(“birthDay”, “20/07/1948”);

//Huy bo cap nhat nay //Huy bo cap nhat nay rs.cancelRowUpdates();

rs.cancelRowUpdates();

//Cap nhat lai gia tri //Cap nhat lai gia tri

rs.updateString(“birthDay”, “24/07/1984”);

rs.updateString(“birthDay”, “24/07/1984”);

//Xac nhan sau cung su thay doi //Xac nhan sau cung su thay doi rs.updateRow();

rs.updateRow();

Nghiên cứu về ResultSet Nghiên cứu về ResultSet

Thêm bản ghi cho ResultSet Thêm bản ghi cho ResultSet

 Một ResultSet cập nhật luôn tồn tại một Một ResultSet cập nhật luôn tồn tại một bản ghi đặc biệt insertRow dùng cho việc bản ghi đặc biệt insertRow dùng cho việc

thêm mới.

thêm mới.

 Các bước: Các bước:

• sử dụng moveToInsertRowsử dụng moveToInsertRow() để di chuyển đến vị trí () để di chuyển đến vị trí insertRow

insertRow

• thực hiện điền các giá trị cho từng trường bằng cách gọi thực hiện điền các giá trị cho từng trường bằng cách gọi updateXXX

updateXXX()()

• Xác nhận lại giá trị và gọi phương thức Xác nhận lại giá trị và gọi phương thức insertRowinsertRow() để () để đưa bản ghi này vào CSDL, đồng thời đưa vào ResultSet đưa bản ghi này vào CSDL, đồng thời đưa vào ResultSet

 Nếu không muốn thêm bản ghi mới ta trở lại Nếu không muốn thêm bản ghi mới ta trở lại vị trí hiện hành trong ResultSet bằng

vị trí hiện hành trong ResultSet bằng phương thức

phương thức moveToCurrentRow moveToCurrentRow () ()

Ví dụ thêm bản ghi cho ResultSet Ví dụ thêm bản ghi cho ResultSet

//Dich chuyen den vi tri can them ban ghi moi //Dich chuyen den vi tri can them ban ghi moi rs.moveToInsertRow();

rs.moveToInsertRow();

//Them thong tin //Them thong tin

//Co the dung chi so cua cot de thuc hien //Co the dung chi so cua cot de thuc hien rs.updateString(“fullName”, “Tran Manh”);

rs.updateString(“fullName”, “Tran Manh”);

rs.updateString(“birthDay”, “23/02/1999”);

rs.updateString(“birthDay”, “23/02/1999”);

//Dua vao CSDL va ResultSet //Dua vao CSDL va ResultSet rs.insertRow();

rs.insertRow();

Nghiên cứu về ResultSet Nghiên cứu về ResultSet

Xoá bản ghi trong ResultSet Xoá bản ghi trong ResultSet

 Sử dụng absolute() để di chuyển đến vị trí cần xoáSử dụng absolute() để di chuyển đến vị trí cần xoá

 Gọi deleteRow()Gọi deleteRow()

 Ví dụ:Ví dụ:

//di chuyen den vi tri 32 de xoa ban ghi nay //di chuyen den vi tri 32 de xoa ban ghi nay rs.absolute(32);

rs.absolute(32);

//thuc hien xoa //thuc hien xoa rs.deleteRow();

rs.deleteRow();

Một phần của tài liệu Tài liệu JDBC Java JDBC cần dùng (Trang 22 - 46)

Tải bản đầy đủ (PPT)

(49 trang)