Quản lý dòng hiện tại

Chúng tôi đã viết chương trình đầu tiên và nó hoạt động hoàn hảo. Chúng tôi đã viết một truy vấn, thực thi nó và kết quả là phương thức execQuery() đã trả về một đối tượng cho chúng tôitập hợp kết quảMột chứa tất cả các kết quả của truy vấn. Và bây giờ chúng tôi sẽ cố gắng tìm ra cách để có được những kết quả này từ nó.

Kết quả truy vấn có thể chứa hàng nghìn hàng và hàng trăm cột thuộc nhiều loại khác nhau, vì vậy đây không phải là một nhiệm vụ tầm thường như bạn nghĩ. Ví dụ: ảnh có thể được lưu trữ trong cơ sở dữ liệu, sau đó bạn có thể lấy ảnh dưới dạng tập hợp byte hoặc InputStream để tải xuống.

Nhưng chúng ta sẽ bắt đầu với cách đơn giản nhất - với khái niệm “ dòng kết quả hiện tại ”. Vì kết quả thường có rất nhiều hàng nên đối tượngtập hợp kết quảcó một con trỏ tới dòng hiện tại bên trong. Và tuần tự chuyển các dòng để đọc chúng bằng phương thức next() .

Cách tiếp cận này chủ yếu được thực hiện để tối ưu hóa. Trình điều khiển JDBC có thể không tải các chuỗi từ cơ sở dữ liệu cho đến khi bạn đọc chúng một cách tuần tự. Bạn cũng đọc FileInputStream tuần tự từ đầu đến cuối. Vì vậy, cách tiếp cận này nên quen thuộc và dễ hiểu đối với bạn.

Tuy nhiên, nếu bạn thực sự cần, thì các tệp có thể được đọc ở bất kỳ đâu bằng cách sử dụng lớp RandomAccessFile .

Lớp ResultSet cũng cho phép điều gì đó tương tự và cho phép bạn di chuyển hàng hiện tại dọc theo kết quả đến bất kỳ đâu. Để làm điều này, nó có các phương pháp sau:

Phương pháp Sự miêu tả
1 Kế tiếp() Chuyển sang dòng tiếp theo
2 trước() Chuyển sang dòng trước
3 Là đầu tiên() Dòng hiện tại đầu tiên?
4 is BeforeFirst() Có phải chúng ta đang ở phía trước của dòng đầu tiên?
5 isLast() Dòng hiện tại có phải là dòng cuối cùng không?
6 isafterLast() Có phải chúng ta sau thời hạn?
7 tuyệt đối (int n) Làm cho dòng thứ N hiện tại
số 8 tương đối (int n) Di chuyển dòng hiện tại N vị trí về phía trước. N có thể <0
9 getRow() Trả về số dòng

Các phương pháp khá đơn giản, nhưng cần phải thực hiện hai cách giải thích. Các kết quả dường như được đóng khung bởi các dòng trống ở cả hai bên. Do đó, ban đầu dòng hiện tại nằm trước dòng đầu tiên của kết quả. Và để lấy hàng đầu tiên, bạn cần gọi phương thức next() ít nhất một lần .

Nếu bạn đã gọi phương thức next() ở hàng cuối cùng thì bạn đã di chuyển đến dòng sau hàng cuối cùng . Bạn không thể đọc dữ liệu từ nó, nhưng sẽ không có lỗi xảy ra. Ở đây, phương thức isAfterLast() sẽ khai báo kết quả là true.

Ví dụ:

Statement statement = connection.createStatement();
ResultSet results = statement.executeQuery("SELECT * FROM user");

System.out.println( results.getRow() );        	// 0
System.out.println( results.isBeforeFirst() );  // true
System.out.println( results.isFirst() );          	// false

results.next();

System.out.println( results.getRow() );        	// 1
System.out.println( results.isBeforeFirst() );  // false
System.out.println( results.isFirst() );          	// true

results.next();

System.out.println( results.getRow() );        	// 2
System.out.println( results.isBeforeFirst() );  // false
System.out.println( results.isFirst() );          	// false

Lấy dữ liệu từ hàng hiện tại

Bạn đã học cách quản lý thuần thục dòng hiện tại. Bây giờ hãy tìm cách lấy dữ liệu từ nó. Đối với điều này, đối tượngtập hợp kết quảcó những phương pháp đặc biệt mà tất cả có thể được mô tả bằng một mẫu:

getType(numberColumns)

Tuy nhiên, nếu cột có tên, thì bạn cũng có thể lấy theo tên cột:

getType(nameColumns)

Ví dụ:

while (results.next()) {
        	Integer id = results.getInt(“id”);
        	String name = results.getString(“name”);
        	System.out.println(results.getRow() + ". " + id + "\t"+ name);
}

Dưới đây tôi sẽ cung cấp một bảng giúp bạn liên kết các kiểu dữ liệu SQL và các phương thức của Bộ kết quả:

kiểu dữ liệu SQL Phương thức getXXX()
CHAR getString()
VARCHAR getString()
INT getInt()
TRÔI NỔI getDouble()
CLOB getClob()
BÃI getBlob()
NGÀY hẹn gặp()
THỜI GIAN dành thời gian()
DẤU THỜI GIAN lấy Dấu thời gian()

Vấn đề là, tôi nghĩ bạn hiểu rồi.

Nhận dữ liệu khác nhau về ResultSet

Chúng tôi đã tìm ra cách đọc dữ liệu từ dòng hiện tại: cả theo số cột và theo tên của nó. Nhân tiện, làm thế nào tôi có thể tìm ra tên cột theo số của nó? Hoặc số cột trong kết quả?

Mặt khác, nếu bạn viết một yêu cầu, thì bạn dường như phải biết tất cả những điều này. Mặt khác, chúng ta có thể viết một chương trình hiển thị kết quả của một truy vấn trên màn hình: truy vấn được chuyển cho chúng ta và chúng ta chỉ muốn hiển thị trên màn hình (trong bảng điều khiển, trang web) mọi thứ mà máy chủ SQL trả về cho chúng tôi.

JDBC có một đối tượng đặc biệt cho việc này, giao diện ResultSetMetaData . Lấy một đối tượng kiểu này khá đơn giản:

Statement statement = connection.createStatement();
ResultSet results = statement.executeQuery("SELECT * FROM user");
ResultSetMetaData resultSetMetaData = results.getMetaData();

Giao diện ResultSetMetaData có một số phương thức rất thú vị. Dưới đây là những cái phổ biến nhất:

1 getColumnCount() Trả về số cột kết quả
2 getColumnName(int cột) Trả về tên cột
3 getColumnLabel(int cột) Trả về mô tả của cột
4 getColumnType() Trả về loại cột: số (mã đặc biệt)
5 getColumnTypeName() Trả về loại cột: chuỗi
6 getColumnClassName() Trả về tên lớp java cho loại cột
7 getTableName() Trả về tên bảng
số 8 getCatalogName() Trả về tên thư mục của cột
9 getSchemaName() Trả về tên lược đồ của cơ sở dữ liệu
10 isAutoIncrement(int cột) Cột có hỗ trợ TĂNG TỐC TỰ ĐỘNG không?
mười một isNullable() Một cột có thể chứa NULL không?

Hãy sử dụng nó để tìm hiểu một chút về bảng của chúng tôi:

ResultSetMetaData metaData = results.getMetaData();
int columnCount = metaData.getColumnCount();
for (int column = 1; column <= columnCount; column++)
{
        	String name = metaData.getColumnName(column);
        	String className = metaData.getColumnClassName(column);
        	String typeName = metaData.getColumnTypeName(column);
        	int type = metaData.getColumnType(column);

        	System.out.println(name + "\t" + className + "\t" + typeName + "\t" + type);
}

Quan trọng! Hãy chú ý rằng các cột được đánh số từ 1. Nhân tiện, các hàng cũng vậy. Làm thế nào là bất thường đó, phải không?

Và đây là kết quả mình nhận được sau khi chạy chương trình:

"C:\Tệp chương trình\Java\jdk-17.0.3.1\bin\java.exe...
nhận dạng java.lang.Integer INT 4
tên java.lang.string VARCHAR 12
mức độ java.lang.Integer INT 4
ngày tạo ra java.sql.date NGÀY 91
Quá trình kết thúc với mã thoát 0