Đây không phải là một hoạt động khá đơn giản? Tuy nhiên, tôi thấy có phải là một size()
hay length()
phương pháp.
Đây không phải là một hoạt động khá đơn giản? Tuy nhiên, tôi thấy có phải là một size()
hay length()
phương pháp.
Câu trả lời:
Thực hiện một SELECT COUNT(*) FROM ...
truy vấn thay thế.
HOẶC LÀ
int size =0;
if (rs != null)
{
rs.last(); // moves cursor to the last row
size = rs.getRow(); // get row id
}
Trong cả hai trường hợp, bạn sẽ không phải lặp lại toàn bộ dữ liệu.
select count
?
ResultSet#last()
không hoạt động trên tất cả các loại ResultSet
đối tượng, bạn cần đảm bảo rằng bạn sử dụng một trong hai ResultSet.TYPE_SCROLL_INSENSITIVE
hoặcResultSet.TYPE_SCROLL_SENSITIVE
ResultSet rs = ps.executeQuery();
int rowcount = 0;
if (rs.last()) {
rowcount = rs.getRow();
rs.beforeFirst(); // not rs.first() because the rs.next() below will move on, missing the first element
}
while (rs.next()) {
// do your standard per row stuff
}
getRow()
hoạt động cho các Kết quả TYPE_FORWARD_ONLY
và beforeFirst()
đưa ra các lỗi cho những kết quả đó. Không phải câu trả lời này là sai rồi sao?
ps=conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
Chà, nếu bạn có một ResultSet
loại ResultSet.TYPE_FORWARD_ONLY
bạn muốn giữ nó theo cách đó (và không chuyển sang một ResultSet.TYPE_SCROLL_INSENSITIVE
hoặc ResultSet.TYPE_SCROLL_INSENSITIVE
để có thể sử dụng .last()
).
Tôi đề nghị một hack rất hay và hiệu quả, trong đó bạn thêm một hàng giả / giả mạo đầu tiên ở đầu chứa số lượng hàng.
Thí dụ
Giả sử truy vấn của bạn là như sau
select MYBOOL,MYINT,MYCHAR,MYSMALLINT,MYVARCHAR
from MYTABLE
where ...blahblah...
và đầu ra của bạn trông giống như
true 65537 "Hey" -32768 "The quick brown fox"
false 123456 "Sup" 300 "The lazy dog"
false -123123 "Yo" 0 "Go ahead and jump"
false 3 "EVH" 456 "Might as well jump"
...
[1000 total rows]
Đơn giản chỉ cần cấu trúc lại mã của bạn thành một cái gì đó như thế này:
Statement s=myConnection.createStatement(ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
String from_where="FROM myTable WHERE ...blahblah... ";
//h4x
ResultSet rs=s.executeQuery("select count(*)as RECORDCOUNT,"
+ "cast(null as boolean)as MYBOOL,"
+ "cast(null as int)as MYINT,"
+ "cast(null as char(1))as MYCHAR,"
+ "cast(null as smallint)as MYSMALLINT,"
+ "cast(null as varchar(1))as MYVARCHAR "
+from_where
+"UNION ALL "//the "ALL" part prevents internal re-sorting to prevent duplicates (and we do not want that)
+"select cast(null as int)as RECORDCOUNT,"
+ "MYBOOL,MYINT,MYCHAR,MYSMALLINT,MYVARCHAR "
+from_where);
Đầu ra truy vấn của bạn sẽ giống như
1000 null null null null null
null true 65537 "Hey" -32768 "The quick brown fox"
null false 123456 "Sup" 300 "The lazy dog"
null false -123123 "Yo" 0 "Go ahead and jump"
null false 3 "EVH" 456 "Might as well jump"
...
[1001 total rows]
Vì vậy, bạn chỉ cần phải
if(rs.next())
System.out.println("Recordcount: "+rs.getInt("RECORDCOUNT"));//hack: first record contains the record count
while(rs.next())
//do your stuff
ResultSet.TYPE_FORWARD_ONLY
)
int i = 0;
while(rs.next()) {
i++;
}
Tôi có một ngoại lệ khi sử dụng rs.last()
if(rs.last()){
rowCount = rs.getRow();
rs.beforeFirst();
}
:
java.sql.SQLException: Invalid operation for forward only resultset
Theo mặc định ResultSet.TYPE_FORWARD_ONLY
, đó là do bạn chỉ có thể sử dụngrs.next()
giải pháp là:
stmt=conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet.TYPE_FORWARD_ONLY
để ResultSet.TYPE_SCROLL_INSENSITIVE
thường phải gánh chịu trong một khổng lồ hình phạt hiệu quả.
SELECT COUNT(*) FROM default_tbl
trước SELECT COUNT(*) FROM default_tbl
đó, nó chỉ mất chưa đến 1,5 giây. Tôi đã thử nghiệm trên cơ sở dữ liệu derby nhúng 10.11.1.1
[Xem xét tốc độ]
Rất nhiều ppl ở đây gợi ý ResultSet.last()
nhưng đối với điều đó, bạn sẽ cần phải mở kết nối vì ResultSet.TYPE_SCROLL_INSENSITIVE
cơ sở dữ liệu nhúng của Derby gấp 10 lần SLOWER so vớiResultSet.TYPE_FORWARD_ONLY
.
Theo các bài kiểm tra vi mô của tôi đối với cơ sở dữ liệu Derby và H2 được nhúng, việc gọi nhanh hơn đáng kể SELECT COUNT(*)
trước CHỌN của bạn .
Đây là một cách đơn giản để đếm hàng.
ResultSet rs = job.getSearchedResult(stmt);
int rsCount = 0;
//but notice that you'll only get correct ResultSet size after end of the while loop
while(rs.next())
{
//do your other per row stuff
rsCount = rsCount + 1;
}//end while
String sql = "select count(*) from message";
ps = cn.prepareStatement(sql);
rs = ps.executeQuery();
int rowCount = 0;
while(rs.next()) {
rowCount = Integer.parseInt(rs.getString("count(*)"));
System.out.println(Integer.parseInt(rs.getString("count(*)")));
}
System.out.println("Count : " + rowCount);
Tôi đã kiểm tra các giá trị thời gian chạy của ResultSet giao diện và phát hiện ra nó đã được khá nhiều một ResultSetImpl tất cả các thời gian. ResultInImpl có một phương thức gọi là getUpdateCount()
trả về giá trị mà bạn đang tìm kiếm.
Mẫu mã này phải đủ:
ResultSet resultSet = executeQuery(sqlQuery);
double rowCount = ((ResultSetImpl)resultSet).getUpdateCount()
Tôi nhận ra rằng downcasting nói chung là một quy trình không an toàn nhưng phương pháp này vẫn chưa làm tôi thất bại.
java.lang.ClassCastException: org.apache.tomcat.dbcp.dbcp.DelegatingResultSet cannot be cast to com.mysql.jdbc.ResultSetImpl
Hôm nay, tôi đã sử dụng logic này tại sao tôi không biết việc đếm RS.
int chkSize = 0;
if (rs.next()) {
do { ..... blah blah
enter code here for each rs.
chkSize++;
} while (rs.next());
} else {
enter code here for rs size = 0
}
// good luck to u.
theStatement=theConnection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet theResult=theStatement.executeQuery(query);
//Get the size of the data returned
theResult.last();
int size = theResult.getRow() * theResult.getMetaData().getColumnCount();
theResult.beforeFirst();
Tôi đã có cùng một vấn đề. Sử dụng ResultSet.first()
theo cách này ngay sau khi thực hiện đã giải quyết nó:
if(rs.first()){
// Do your job
} else {
// No rows take some actions
}
Tài liệu ( liên kết ):
boolean first() throws SQLException
Di chuyển con trỏ đến hàng đầu tiên trong
ResultSet
đối tượng này .Trả về:
true
nếu con trỏ ở trên một hàng hợp lệ;false
nếu không có hàng trong tập kết quảNém:
SQLException
- nếu xảy ra lỗi truy cập cơ sở dữ liệu; phương thức này được gọi trên tập kết quả đóng hoặc kiểu tập kết quả làTYPE_FORWARD_ONLY
SQLFeatureNotSupportedException
- nếu trình điều khiển JDBC không hỗ trợ phương thức nàyTừ:
1.2
Cách tiếp cận dễ nhất, truy vấn Run Count (*), thực hiện resultset.next () để trỏ đến hàng đầu tiên và sau đó chỉ cần thực hiện resultset.getString (1) để lấy số đếm. Mã số:
ResultSet rs = statement.executeQuery("Select Count(*) from your_db");
if(rs.next()) {
int count = rs.getString(1).toInt()
}
Đặt tên cho cột ..
String query = "SELECT COUNT(*) as count FROM
Tham chiếu cột đó từ đối tượng result Set thành một int và thực hiện logic của bạn từ đó ..
PreparedStatement statement = connection.prepareStatement(query);
statement.setString(1, item.getProductId());
ResultSet resultSet = statement.executeQuery();
while (resultSet.next()) {
int count = resultSet.getInt("count");
if (count >= 1) {
System.out.println("Product ID already exists.");
} else {
System.out.println("New Product ID.");
}
}