在任何你想向数据库运行一个SQL语句的时候, 你都需要一个Statement 或 PreparedStatement 实例。 一旦你拥有了一个Statement 或 PreparedStatement,你就可以发出一个查询。 这样将返回一个ResultSet 实例, 在其内部包含整个结果。Example 31-1 演示了这个过程。
Example 31-1. 在 JDBC 里处理一个简单的查询
这个例子将发出一个简单的查询然后用一个 Statement 打印出每行的第一个字段。
Statement st = db.createStatement(); ResultSet rs = st.executeQuery("SELECT * FROM mytable WHERE columnfoo = 500"); while (rs.next()) { System.out.print("Column 1 returned "); System.out.println(rs.getString(1)); } rs.close(); st.close();
这个例子将使用 PreparedStatement 发出和前面一样的查询,并且在查询中绑定数值。
int foovalue = 500; PreparedStatement st = db.prepareStatement("SELECT * FROM mytable WHERE columnfoo = ?"); st.setInt(1, foovalue); ResultSet rs = st.executeQuery(); while (rs.next()) { System.out.print("Column 1 returned "); System.out.println(rs.getString(1)); } rs.close(); st.close();
缺省时,驱动程序一次从查询里获取所有的结果。这样可能对于大的数据集来说是不方便的, 因此 JDBC 驱动提供了一个方法从一个数据库游标伤抽取少数几行的 ResultSet 的方法。
在链接的客户端这边缓冲了一小部分数据行,并且在用尽之后, 则通过重定位游标检索下一个数据行块。
Example 31-2. 设置抓取的大小以开关游标
把代码修改成游标模式简单到只是设置 Statement 的抓取大小到一个合适的程度。 把抓取大小设置为 0 则是缓冲所有行的模式(缺省行为)。
Statement st = db.createStatement(); // 打开游标的使用。 st.setFetchSize(50); ResultSet rs = st.executeQuery("SELECT * FROM mytable"); while (rs.next()) { System.out.print("a row was returned."); } rs.close(); // 关闭游标的使用。 st.setFetchSize(0); ResultSet rs = st.executeQuery("SELECT * FROM mytable"); while (rs.next()) { System.out.print("many rows were returned."); } rs.close(); // 关闭语句 st.close();
在使用Statement或 PreparedStatement接口时必须考虑下面的问题:
你可以将一个Statement或 PreparedStatement实例使用任意次。 你可以在打开一个联接后马上创建一个Statement 实例,并且在联接的生存期里使用之。 你必须记住每个Statement或 PreparedStatement只能存在一个 ResultSet。
如果你需要在处理一个ResultSet的时候执行一个查询, 你只需要创建并且使用另外一个Statement。
如果你使用了线程,并且有几个使用数据库, 你对每个线程必须使用一个独立的Statement。 如果考虑使用线程,请参考本文档稍后的 Section 31.9 章节, 因为这些内容包含一些重要的信息。
在你用完 Statement 或者 PreparedStatement 之后,你应该关闭它。
使用ResultSet接口时必须考虑下面的问题:
在读取任何数值的时候,你必须调用next()。 如果还有结果则返回真(true),但更重要的是,它为处理准备了数据行。
在 JDBC 规范里,你对一个字段应该只访问一次。 遵循这个规则是最安全的,不过目前 PostgreSQL 驱动将允许你对一个字段访问任意次。
一旦你结束对一个 ResultSet 的处理,你必须对之调用 close()来关闭它。
一旦你使用那个创建ResultSet的 Statement做另一个查询请求, 当前打开的 ResultSet 实例将自动关闭。