2.2.1 使用executeQuery查询数据
executeQuery方法用于执行产生单个结果集的SQL语句,如SELECT语句。executeQuery方法不能执行INSERT、UPDATE、DELETE以及DDL语句,如果执行这些语句,executeQuery将抛出SQLException异常。executeQuery方法的定义如下:
ResultSet executeQuery(String sql) throws SQLException;
从executeQuery方法的定义上可看出,executeQuery方法返回了一个ResultSet对象,可以通过这个对象来访问查询结果集。对结果集最常用的操作就是扫描结果集。可以使用ResultSet的next方法完成这个任务。next方法做了如下两件事:
1. 判断是否还有下一条记录。如果还有下一条记录,返回true,否则返回false。
2. 如果有下一条记录,将当前记录指针向后移一个位置。
下面的代码演示了如何使用next方法来扫描查询结果集:
...
// 获得Connection对象
Connection conn = DriverManager.getConnection(url, "user", "password");
Statement stmt = conn.createStatement();
// 执行SQL语句(必须是SELECT语句),并返回ResultSet对象
ResultSet rs = stmt.executeQuery(sql);
// 通过next方法对记录集中每一条记录进行扫描
while(rs.next())
{
// 处理当前行记录
}
stmt.close();
conn.close();
...
在读取数据时可以根据列索引和列名来定义字段。读数据的方法的一般形似为getXxx。getXxx方法可以在读取数据时将数据转换为其他的数据类型。通过列索引读取数据的getXxx方法定义如下:
String getString(int columnIndex);
boolean getBoolean(int columnIndex);
byte getByte(int columnIndex);
short getShort(int columnIndex);
int getInt(int columnIndex);
long getLong(int columnIndex);
float getFloat(int columnIndex);
double getDouble(int columnIndex);
byte[] getBytes(int columnIndex);
java.sql.Date getDate(int columnIndex);
java.sql.Date getDate(int columnIndex, java.util.Calendar cal);
java.sql.Time getTime(int columnIndex);
java.sql.Timestamp getTimestamp(int columnIndex);
java.sql.Timestamp getTimestamp(int columnIndex, java.util.Calendar cal);
java.io.InputStream getAsciiStream(int columnIndex);
java.io.InputStream getBinaryStream(int columnIndex);
Object getObject(int columnIndex);
Object getObject(int columnIndex, java.util.Map map);
java.sql.Array getArray(int columnIndex);
java.math.BigDecimal getBigDecimal(int columnIndex);
java.sql.Blob getBlob(int columnIndex);
java.sql.Clob getClob(int columnIndex);
java.io.Reader getCharacterStream(int columnIndex);
java.sql.Ref getRef(int columnIndex);
java.net.URL getURL(int columnIndex);
通过列名读取数据的getXxx方法定义如下:
String getString(String columnName);
boolean getBoolean(String columnName);
byte getByte(String columnName);
short getShort(String columnName);
int getInt(String columnName);
long getLong(String columnName);
float getFloat(String columnName);
double getDouble(String columnName);
byte[] getBytes(String columnName);
java.sql.Date getDate(String columnName);
java.sql.Date getDate(String columnName, java.util.Calendar cal);
java.sql.Time getTime(String columnName);
java.sql.Timestamp getTimestamp(String columnName);
java.sql.Timestamp getTimestamp(String columnName, java.util.Calendar cal);
java.io.InputStream getAsciiStream(String columnName);
java.io.InputStream getBinaryStream(String columnName);
Object getObject(String columnName);
Object getObject(String columnName, java.util.Map map);
java.sql.Array getArray(String columnName);
java.math.BigDecimal getBigDecimal(String columnName);
java.sql.Blob getBlob(String columnName);
java.sql.Clob getClob(String columnName);
java.io.Reader getCharacterStream(String columnName);
java.sql.Ref getRef(String columnName);
java.net.URL getURL(String columnName);
下面的代码演示了如何使用getXxx方法来获得字段的值:
...
Connection conn = DriverManager.getConnection(url, "user", "password");
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
while(rs.next())
{
System.out.print(rs.getString("id")); // 根据列id获得字段的值
System.out.print(rs.getInt(1)); // 取当前记录的第1个字段的值
System.out.println(rs.getDate(2)); // 取当前记录的第2个字段的值
}
stmt.close();
conn.close();
...
在使用getXxx方法时应注意如下三点:
1. 列索引从1开始,也就是说,第一列的索引为1。在通过列索引读取数据时要注意这一点。
2. 可以在读取数据时进行类型转换。如字段类型是String,在读取时可以使用getInt或其他的getXxx方法。但字段值的前面部分必须是合法的整型或其他类型的值。如一个String类型的字段值是123abc,调用getInt()后,将返回123。如果类型不合法,将抛出java.sql.SQLException异常。
3. 并不是每个getXxx方法都被当前的JDBC驱动程序支持。因此,在调用getXxx方法前需要确认当前的JDBC驱动程序是否实现了该getXxx方法,如果当前的JDBC驱动程序未实现某个getXxx方法,那么调用这个getXxx方法就会抛出一个异常(对于MySQL来说,将抛出com.mysql.jdbc.NotImplemented异常)。
在某些情况下并不需要得到全部的查询结果。这时可以使用Statement接口的setMaxRows方法限制返回的记录数。还可以使用getMaxRows()方法获得最大返回记录数。这两个方法的定义如下:
void setMaxRows(int max) throws SQLException;
int getMaxRows() throws SQLException;
其中max参数表示最大返回记录数。如果max的值大于等于实际查询到的记录数,则按实际查询到的记录数返回,如果max的值小于实际查询到的记录数,则返回的记录数为max。
ResultSet类还有一些其他的功能,如下面两个方法分别用来判断字段值是否为NULL和确定某一列是否存在:
1. wasNull方法
这个方法用于判断最后一次使用getXxx方法读出的字段值是否为NULL。假设name字段的值为NULL,则下面的代码将输出true:
ResultSet rs = stmt.executeQuery(sql);
rs.getString("name");
System.out.println(rs.wasNull());
2. findColumn方法
如果要知道某个列名在列集合中的位置,那么ResultSet接口的findColumn方法正好派上用场。findColumn方法的定义如下:
int findColumn(String columnName) throws SQLException;