Tải bản đầy đủ (.doc) (14 trang)

giáo trình java tóm tắt - jdbc

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (333.1 KB, 14 trang )

Giáo trình Java tóm tắt JDBC
JDBC
JDBC 1
1. Giới thiệu JDBC 1
2. Kiến trúc JDBC 1
3. DriverManager 2
4. Connection 5
5. Statement 6
6. ResultSet 8
7. Java và Oracle – OJDBC 9
1. Giới thiệu JDBC
JDBC là chữ viết tắt của "Java DataBase Connectivity", là một chuẩn truy xuất cơ sở dữ
liệu trên môi trường Java do Sun MicroSystem đề xuất và phát triển.
Thực chất, JDBC là một API (Application Programming Interface) bao gồm các class,
interface và exception theo cùng một đặc tả mà từ đó, các công ty sản xuất JDBC driver
cũng như các nhà phát triển JDBC đều phải tuân thủ khi phát triển ứng dụng.
2. Kiến trúc JDBC
Trong JDBC có 2 loại class chính để tạo kết nối đến một cơ sở dữ liệu: Driver Manager
và JDBC Driver, được cung cấp trong 2 package java.sql và javax.sql.
2.1. Driver Manager
Là một class thực sự do JDBC API cung cấp. Driver Manager chịu trách nhiệm quản lý
các driver đã đăng ký, mà thực chất là là trừu tượng hóa các chi tiết về việc sử dụng một
driver, cho nên lập trình viên không cần phải làm việc trực tiếp với driver đó.
2.2. JDBC Drivers
Các class này này được cung cấp bởi các nhà sản xuất phần mềm độc lập. Các class
JDBC Driver có chức năng tạo ra kết nối tới một cơ sở dữ liệu và xử lý tất cả các thao tác
giao tiếp với cơ sở dữ liệu đó.
2.3. Package java.sql
Dưới đây là các class và interface chính của package java.sql.
a. Class DriverManager
Có chức năng nạp các JDBC Driver vào bộ nhớ. Có thể sử dụng nó để mở các kết nối tới


một nguồn dữ liệu.
b. Interface Connection
Biểu thị một kết nối đến một nguồn dữ liệu. Được dùng để tạo ra các đối tượng
Statement, PreparedStatement và CallableStatement.
Châu Hải Duy 1/14
Giáo trình Java tóm tắt JDBC
c. Interface Statement
Chứa một câu lệnh SQL tĩnh, kết quả thực thi nó sẽ là một ResultSet.
d. Interface PreparedStatement
Chứa một câu lệnh SQL đã được dịch, dùng để tăng tốc độ khi cần thực thi nhiều lần
cùng một câu lệnh SQL.
e. Interface CallableStatement
Dùng để biểu diễn các thủ tục SQL. Chỉ dùng được với hệ quản trị cơ sở dữ liệu có hỗ trợ
thủ tục (như Oracle).
f. Interface ResultSet
Dùng để chứa kết quả trả về khi truy vấn dữ liệu.
g. Exception SQLException
Được phát sinh khi có lỗi xảy ra trong quá trình truy cập cơ sở dữ liệu.
2.4. Package javax.sql
Được bổ sung từ phiên bản JDK 1.4, còn có tên là JDBC 2.0 Standard Extension API,
package này bổ sung các chứng năng mới vào JDBC để hỗ trợ cho các chức năng đã có
trong package java.sql.
Dưới đây là các class và interface chính của package javax.sql.
a. Interface DataSource
Mô tả một nguồn dữ liệu. Các đối tượng thuộc interface này có thể được dùng thay cho
DriverManager để tạo ra các kết nối tới cơ sở dữ liệu.
b. Interface XADataSource và XAConnection
Cung cấp khả năng truy cập tới cơ sở dữ liệu được lưu trữ trên nhiều server chỉ trong một
transaction.
c. Interface RowSet

Là sự cải tiến của interface ResultSet (implement từ ResultSet), cung cấp khả năng hỗ
trợ JavaBeans. Một RowSet có thể được dùng như một thành phần JavaBeans trong môi
trường Bean, có thể được tạo ra lúc lập trình và sử dụng lúc chạy ứng dụng.
3. DriverManager
3.1. Giới thiệu
Chức năng chính: nạp các JDBC Driver vào bộ nhớ, mở kết nối tới nguồn dữ liệu.
Class DriverManager thuộc lớp quản lý của JDBC, hoạt động ở giữangười dùng và các
driver. Nó quản lý các driver đang có, điều khiển sự thiết lập kết nối giữa cơ sở dữ liệu và
driver. Thêm vào đó, DriverManager còn có một số chức năng khác như giới hạn thời
gian login của driver, xuất ra các file log và theo dõi các thông điệp.
Châu Hải Duy 2/14
Giáo trình Java tóm tắt JDBC
Từ JDBC 2.0 (javax.sql), DriverManager được nâng cấp thành DataSource với một số
chức năng bổ sung như cho phép một transaction truy cập các cơ sở dữ liệu trên các
server riêng biệt, cơ chế pooling, hỗ trợ môi trường Bean.
3.2. Các phương thức chính
Tất cả các phương thức của DriverManager đều là tĩnh (static) nên ta không cần tạo ra
đối tượng DriverManager. Do đó, DriverManager cũng không có constructor.
Phương thức Ý nghĩa
void deregisterDriver(Driver driver)
Xóa bỏ một driver khỏi danh sách của
DriverManager
Connection getConnection(String url)
Tạo một kết nối tới cơ sở dữ liệu
Connection getConnection(String url,
String user, String password)
Tạo một kết nối tới nguồn dữ liệu,
username và password đăng nhập được
tách khỏi URL
Driver getDriver(String url)

Trả về một driver đã đăng ký
Enumeration<Driver> getDrivers()
Trả về một Enumerator chứa tất cả driver
đã đăng ký
int getLoginTimeout()
Trả về thời gian tối đa mà driver có thể chờ
khi cố gắng kết nối tới cơ sở dữ liệu
PrintWriter getLogWriter()
Trả về đối tượng đảm nhận việc ghi log của
DriverManager và các driver
void println(String message)
In một thông điệp vào log stream hiện hành
void registerDriver(Driver driver)
Đăng ký một driver mới
void setLoginTimeout(int seconds)
Thiết lập thời gian tối đa mà driver có thể
chờ khi cố gắng kết nối tới cơ sở dữ liệu
void setLogWriter(PrintWriter out)
Thiết đặt đối tượng đảm nhận việc ghi log
của DriverManager và các driver
3.3. Cách sử dụng
Trong các ứng dụng đơn giản, thông thường ta chỉ cần dùng phương thức
getConnection() của DriverManager. Phương thức này dùng để tạo ra một kết nối tới
cơ sở dữ liệu. Ngoài ra, ta có thể dùng các phương thức registerDriver() để đang ký
một driver mới, getDriver() để lấy thông tin về một driver đã có,
Châu Hải Duy 3/14
Giáo trình Java tóm tắt JDBC
3.3.1. Đăng ký một JDBC Driver
Một JDBC Driver thực chất là một class do nhà sản xuất phần mềm cung cấp để kết nối
tới một cơ sở dữ liệu cụ thể nào đó. Class này phải tuân theo những quy định của JDBC

do Sun đặt ra. Để dùng một driver chưa có trong DriverManager thì ta phải đăng ký nó.
Để đăng ký một JDBC Driver ta có ba cách:
 Đăng ký nó như là một class bình thường bằng phương thức tĩnh
Class.forName().
// Nạp và đăng ký lớp HocSinh trong package hocsinh
// sau đó trả về một đối tượng Class kiểu HocSinh
Class.forName("hocsinh.HocSinh");
 Đăng ký nó như là một JDBC Driver bằng phương thức tĩnh
DriverManager.registerDriver().
// Đăng ký lớp myDriver trong package myjdbc
DriverManager.registerDriver(new mykdbc.myDriver());
 Đăng ký nó với thuộc tính jdbc.drivers của lớp java.lang.System. Khi chạy
chương trình, DriverManager sẽ tự nạp các driver trong thuộc tính này.
Thông thường, ta dùng hai cách đầu tiên vì chúng an toàn hơn.
3.3.2. Tạo kết nối tới cơ sở dữ liệu
Sau khi đã nạp và đăng ký JDBC Driver, ta có thể tạo kết nối tới cơ sở dữ liệu bằng
phương thức DriverManager.getConnection().
Khi phương thức getConnection() được gọi, DriverManager sẽ kiểm tra lần lượt các
driver đã đăng ký xem driver nào có thể tạo kết nối tới cơ sở dữ liệu được mô tả trong
chuỗi đầu vào của phương thức.
Nếu được thực thi thành công, kết quả trả về của phương thức getConnection() sẽ là
một đối tượng thuộc interface Connection.
Connection cn = DriverManager.getConnection("url","usrname","passwd");
Đôi khi với cùng một cơ sở dũ liệu, ta có nhiều driver thích hợp để tạo kết nối. Khi đó thì
thứ tự driver là quan trọng, vì DriverManager sẽ lấy driver phù hợp đầu tiên mà nó tìm
thấy trong danh sách driver để sử dụng.
Cơ chế hoạt động của việc tạo kết nối như sau:
 Để tìm driver phù hợp, DriverManager sẽ dùng thử các driver đã biết theo thứ tự
đăng ký theo nguyên tắc driver đăng ký trước sẽ được thử trước  các driver lưu
trong thuộc tính jdbc.drivers sẽ được thử đầu tiên. DriverManager sẽ không

dùng các driver chứa những đoạn mã mà nó xem là đáng tin cậy, trừ khi driver đó
được nạp trong cùng đoạn mã chương trình với câu lệnh tạo kết nối.
 Với mỗi driver trong danh sách, DriverManager sẽ kiểm tra bằng cách gọi
phương thức Driver.connect(). Driver đầu tiên nhận diện được đoạn URL
trong phương thức getConnection() sẽ được sử dụng.
Châu Hải Duy 4/14
Giáo trình Java tóm tắt JDBC
4. Connection
4.1. Giới thiệu
Một đối tượng Connection là một kết nối (hoặc một phiên làm việc) tới một cơ sở dữ
liệu cụ thể nào đó. Đối tượng Connection dùng để gởi câu lệnh SQL tới cơ sở dữ liệu và
nhận kết quả thực thi câu lệnh SQL đó từ cơ sở dữ liệu.
Mặc định, các đối tượng Connection sẽ hoạt động ở chế độ tự động commit, có nghĩa là
các câu lệnh SQL sẽ được commit tự động sau khi thực thi xong. Nếu không dùng chế độ
tự động commit, ta phải tự gọi phương thức commit() để bảo đảm việc thay đổi trên cơ
sở dữ liệu là có hiệu lực.
Từ JBDC 2.1, mỗi đối tượng Connection sẽ có một đối tượng Map (java.util.Map) bên
trong để ánh xạ các kiểu dữ liệu của cơ sở dữ liệu thành các class của Java. Chi tiết xin
xem trong Java API Documents.
4.2. Các phương thức chính
Phương thức Ý nghĩa
void clearWarnings()
Đóng một kết nối tới cơ sở dữ liệu và giải
phóng các tài nguyên ứng với kết nối đó
void commit()
Ghi thẳng những thay đổi xuống cơ sở dữ
liệu (với hệ quản trị cơ sở dữ liệu dùng cơ
chế commit / rollback như Oracle)
Statement createStatement()
Tạo ra đối tượng Statement để chứa câu

lệnh SQL
Statement createStatement(int
resultSetType, int
resultSetConcurrency)
Tạo ra đối tượng Statement, và
Statement này sẽ sinh ra các đối tượng
ResultSet theo quy định trong các tham
số.
boolean getAutoCommit()
Trả về chế độ tự động commit
boolean isClosed()
Cho biết Connection được đóng hay chưa
boolean isReadOnly()
Cho biết Connection có thuộc dạng read-
only (chỉ cho phép truy vấn) hay không
CallableStatement prepareCall(String
sql)
Tạo ra đối tượng CallableStatament để chứa
thủ tục SQL lưu trong tham số sql
PreparedStatement
prepareStatement(String sql)
Tạo ra đối tượng PreparedStatament để chứa
câu lệnh SQL lưu trong tham số sql
void rollback()
Hủy bỏ những thay đổi của câu lệnh SQL
void rollback(Savepoint savepoint)
Quay lại một mốc phục hồi đã tạo từ trước
Châu Hải Duy 5/14
Giáo trình Java tóm tắt JDBC
void setAutoCommit(boolean

autoCommit)
Thiết đặt bật/tắt chế độ tự động commit
void setReadOnly(boolean readOnly)
Thiết đặt bật/tắt chế độ read-only (chỉ cho
phép truy vấn)
Savepoint setSavepoint(String name)
Thiết đặt một cột mốc phục hồi
4.3. Cách sử dụng
Sau khi đã tạo ra đối tượng Connection từ DriverManager (bằng phương thức
DriverManager.getConnection() đã nói ở trên). Khi đã có đối tượng Connection, ta
dùng nó để tạo ra các đối tượng Statament lưu các câu lệnh SQL.
Phương thức thường dùng: createStatement(int resultSetType, int
resultSetConcurrency)
Statement sm = cn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
5. Statement
5.1. Giới thiệu
Interface Statement đưa ra các quy định cơ bản mà class Statement (do các nhà sản
xuất phần mềm cung cấp) phải tuân theo.
Các đối tượng Statement được dùng để gởi một câu lệnh SQL tĩnh tới hệ quản trị cơ sở
dữ liệu. Có 3 loại Statement là Statement, PreparedStatement (kế thừa từ
Statement) và CallableStatement (kế thừa từ PreparedStatement). Chức năng cụ
thể của từng loại Statement như sau:
 Đối tượng Statement được dùng để thực thi một câu SQL đơn giản, không có
tham số.
 Đối tượng PreparedStatement được dùng để thực thu một câu lệnh SQL đã
được dịch, có thể có tham số dạng IN.
 Đối tượng CallableStatement được dùng để thực thi một thủ tục SQL trong cơ
sở dữ liệu (chỉ dùng được với hệ quản trị cơ sở dữ liệu có hỗ trợ việc tạo và thực
thi thủ tục – như Oracle).

5.2. Các phương thức chính
Phương thức Ý nghĩa
void addBatch(String sql)
Thêm một câu lệnh SQL vào danh sách lệnh
của Statement, dùng khi cần chạy nhiều câu
lệnh SQL
void cancel()
Hủy bỏ câu lệnh SQL, chỉ dùng được với hệ
Châu Hải Duy 6/14
Giáo trình Java tóm tắt JDBC
quản trị có hỗ trợ chức năng này
void clearBatch()
Xóa danh sách lệnh của Statement
void close()
Đóng đối tượng Statement
boolean execute(String sql)
Thực thi câu lệnh SQL, có thể trả về nhiều kết
quả  dùng getResultSet(),
getUpdateCount() và getMoreResults()
để lấy lần lượt các kết quả
int[] executeBatch()
Thực thi một danh sách lệnh SQL
ResultSet executeQuery(String sql)
Thực thi câu truy vấn và trả về kết quả trong
ResultSet
int executeUpdate(String sql)
Thực thi câu lệnh có thay đổi dữ liệu (insert,
update, delete)
boolean getMoreResults()
Dịch chuyển tới kết quả kế tiếp, trả về true

nếu kết quả là một ResultSet
ResultSet getResultSet()
Lấy kết quả lưu trong ResultSet của câu
lệnh SQL
Ngoài ra còn rất nhiều phương thức khác, chi tiết xin xem trong Java API Documents.
5.3. Cách sử dụng
5.3.1. Tạo câu lệnh
Khi tạo xong kết nối tới cơ sở dữ liệu, ta sẽ dùng kết nối đó để gởi các câu lệnh SQL. Đối
tượng Statement được dùng để lưu câu lệnh SQL cần thực thi, được tạo ra từ phương
thức createStatement() của đối tượng Connection.
Statement stmt = con.createStatement();
5.3.2. Thực thi câu lệnh
Thực thi câu lệnh với đối tượng Statement: bằng các phương thức execute(),
executeBatch(), executeQuery() và executeUpdate().
ResultSet rs = sm.executeQuery("select * from jobs");
5.3.3. Hoàn tất câu lệnh
Khi chạy xong câu lệnh có thay đổi dữ liệu (executeUpdate()), nếu không bật chế độ tự
động commit thì ta phải gọi commit để ghi thẳng các thay đổi xuống cơ sở dữ liệu.
Một số hệ quản trị cơ sở dữ liệu xem thủ thục như là một tập hợp các lệnh riêng biệt, một
số hệ khác thì xem thủ tục là một câu lệnh phức. Do đó cần lưu ý chế độ tự động commit
khi chạy thủ tục vì nó ảnh hưởng tới lời gọi phương thức commit(). Trong trường hợp
Châu Hải Duy 7/14
Giáo trình Java tóm tắt JDBC
đầu tiên, từng câu lệnh sẽ được commit riêng biệt, trong trường hợp sau, các câu lệnh sẽ
được commit cùng lúc.
5.3.4. Đóng đối tượng Statement
Đối tượng Statement sẽ được garbage collection đóng, tuy nhiên ta nên đóng nó khi
không cần dùng nữa để giải phóng tài nguyên càng sớm càng tốt, và giúp chương trình an
toàn hơn bằng phương thức close().
sm.close();

6. ResultSet
6.1. Giới thiệu
Trong Java, ResultSet là đối tượng chứa kết quả thực thi một câu truy vấn SQL. Nói cách
khác, nó chứa các dòng thỏa điều kiện truy vấn. Thông thường, dữ liệu lưu trong
ResultSet được lấy ra bằng các phương thức getXXX() và next().
Thực chất, ResultSet sẽ nắm giữ một cursor chỉ tới các dòng của tập dữ liệu truy vấn
được. Ban đầu, cursor chỉ tới vị trí liền trước dòng đầu tiên của kết quả truy vấn. Sau mỗi
lời gọi next(), cursor sẽ dịch chuyển sang dòng tiếp theo  lần gọi next() đầu tiên sẽ
làm cho cursor chỉ tới dòng đầu tiên.
Nếu driver được implement từ JDBC 1.0 API, ResultSet sẽ chỉ có thể di chuyển về
trước nên sẽ thuộc loại ResultSet.TYPE_FORWARD_ONLY.
Nếu driver được implement từ JDBC 2.0 API, ResultSet sẽ có khả năng "cuộn", có
nghĩa là nó cho phép dịch chuyển hai chiều.
6.2. Cách sử dụng
Tạo đối tượng ResultSet từ việc thực thi câu truy vấn trong đối tượng Statement:
ResultSet rs=sm.executeQuery("select * from jobs");
Chuyển đến dòng đầu tiên bằng phương thức next():
rs.next();
Những lần gọi phương thức next() sau đó sẽ chuyển đến dòng kế tiếp, và phương thức
này sẽ trả về false nếu hết dòng.
Lấy dữ liệu: mỗi dòng có nhiều cột, để lấy dữ liệu từ một dòng ta sẽ lấy lần lượt dữ liệu
trong các cột của dòng đó bằng phương thức getXXX() (với XXX là kiểu dữ liệu). Khi lấy
dữ liệu từ cột, ta truyền vào tham số là tên cột hoặc số thứ tự của cột.
System.out.println(rs.getString("JOB_ID"));
Có rất nhiều phương thức getXXX() như getString(), getFloat(), getInt(), chi
tiết xin xem trong Java API Documents.
Châu Hải Duy 8/14
Giáo trình Java tóm tắt JDBC
6.3. Các ví dụ
6.3.1. Ví dụ cơ bản

Giả sử ta có bảng Table1 với 3 cột a, b, c. Khi thực thi cấu truy vấn "SELECT a, b, c
FROM Table1", dữ liệu truy vấn được sẽ như sau:
a b c

12345 Cupertino 2459723.495
83472 Redmond 1.0
83492 Boston 35069473.43
Đoạn mã sau sẽ lấy kết quả trong ResultSet và đưa ra màn hình:
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table1");
while (rs.next())
{
// Lấy và in giá trị của dòng hiện hành
int i = rs.getInt("a");
String s = rs.getString("b");
float f = rs.getFloat("c");
System.out.println("ROW = " + i + "\t" + s + "\t" + f);
}
6.3.2. Ví dụ về sự dịch chuyển cursor
Đoạn mã sau sẽ minh họa cách dịch chuyển cursor của ResultSet tên là rs theo thứ tự
từ đầu tới cuối:
rs.beforeFirst(); // Đưa cursor về vị trí trước dòng đầu
while (rs.next()) // Dịch chuyển tới dòng kế, trả về false nếu hết dòng
{
System.out.print (rs.getString("EMP_NO") + "\t");
System.out.println(rs.getFloat("SALARY");
}
Đoạn mã sau sẽ minh họa cách dịch chuyển cursor của ResultSet tên là rs theo thứ tự
từ cuối lên đầu:
rs.afterLast(); // Đưa cursor về vị trí sau dòng cuối

while (rs.previous()) // Chuyển tới dòng trước, trả về false nếu hết
{
System.out.print (rs.getString("EMP_NO") + "\t");
System.out.println(rs.getFloat("SALARY");
}
7. Java và Oracle – OJDBC
Trong phần trước ta đã điểm qua các chứng năng tổng quát của JDBC, phần này sẽ trình
bày cụ thề về cách dùng JDBC với hệ quản trị CSDL Oracle.
Châu Hải Duy 9/14
Giáo trình Java tóm tắt JDBC
7.1. Bổ sung các thư viện mô tả các class của OJBDC
Ta phải thêm các tập tin chứa các lớp thư viện JDBC do Oracle cung cấp, các lớp này
nằm trong hai tập tin là ojdbc14dms.jar và dms.jar.
Trươc hết, copy các file .jar như trên về máy mình.
7.1.1. Dùng JCreator
Vào menu "Project"  "Project Properties ". Trong hộp thoại vừa mở ra, chọn thẻ
"Required Libraries".
Nhấn nút "New ", chọn "Add"  "Add Archive ".
Châu Hải Duy 10/14
Giáo trình Java tóm tắt JDBC
Chọn các file jar cần thêm, gõ tên vào mục "Name" rồi OK
Check vào thư viện vừa thêm, nhấn "OK" là xong.
Châu Hải Duy 11/14
Giáo trình Java tóm tắt JDBC
7.1.2. Dùng NetBean
Trong khung bên trái, vào mục "Libraries", chọn "Add JAR/Folder ":
Chỉ tới 2 tập tin .jar như yêu cầu, nhấn OK:
Châu Hải Duy 12/14
Giáo trình Java tóm tắt JDBC
7.2. Đăng ký Driver

Dùng một trong hai cách: gọi Class.forName() hoặc
DriverManager.registerDriver().
Dùng Class.forName():
Class.forName("oracle.jdbc.driver.OracleDriver");
Dùng DriverManager.registerDriver():
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
7.3. Tạo Connection
Dùng phương thức DriverManager.getConnection() để tạo một kết nối tới cơ sở dữ
liệu Oracle. trong ví dụ là dùng cơ sở dữ liệu mặc định (db) với username là hr và
password là hr, cơ sở dữ liệu này lưu trên máy có IP address là 172.29.8.11.
Connection cn = DriverManager.getConnection
("jdbc:oracle:thin:@172.29.8.11:1521:db",
"hr",
"hr"
);
7.4. Tạo Statement
Dùng phương thức createStatement() của đối tượng Connection để tạo ra đối tượng
Statement chứa câu lệnh SQL:
Statement sm = cn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
7.5. Thực thi câu lệnh SQL
Dùng phương thức executeXXX() của đối tượng Statement để thực thi các câu lệnh
SQL. Ở đây trình bày ví dụ về câu lệnh truy vấn từ bảng JOBS của schema hr:
Châu Hải Duy 13/14
Giáo trình Java tóm tắt JDBC
ResultSet rs=sm.executeQuery("select * from jobs");
Kết quả truy vấn lưu trong đối tượng ResultSet tên là rs.
7.6. Xuất kết quả ra màn hình console
Có vài cách xuất: truy cập dòng trực tiếp theo chỉ số (bắt đầu từ 1) hoặc tuần tự. Ở đây
trình bày cách xuất dữ liệu từ việc truy vấn bảng JOBS của schema hr.

Theo chỉ số:
int i=1;
while (rs.absolute(i++))
System.out.println(rs.getString("JOB_ID") + " " +
rs.getString("JOB_TITLE"));
Tuần tự:
while (rs.next())
System.out.println(rs.getString("JOB_ID") + " " +
rs.getString("JOB_TITLE"));
Châu Hải Duy 14/14

×