使用 JDBC 处理 SQL 语句

原文: https://docs.oracle.com/javase/tutorial/jdbc/basics/processingsqlstatements.html

通常,要使用 JDBC 处理任何 SQL 语句,请执行以下步骤:

  1. 建立连接。
  2. 创建一个声明。
  3. 执行查询。
  4. 处理ResultSet对象。
  5. 关闭连接。

本页使用以下方法, [CoffeesTables.viewTable](gettingstarted.html),从教程示例中演示这些步骤。此方法输出表COFFEES的内容。本教程后面将详细讨论此方法:

  1. public static void viewTable(Connection con, String dbName)
  2. throws SQLException {
  3. Statement stmt = null;
  4. String query = "select COF_NAME, SUP_ID, PRICE, " +
  5. "SALES, TOTAL " +
  6. "from " + dbName + ".COFFEES";
  7. try {
  8. stmt = con.createStatement();
  9. ResultSet rs = stmt.executeQuery(query);
  10. while (rs.next()) {
  11. String coffeeName = rs.getString("COF_NAME");
  12. int supplierID = rs.getInt("SUP_ID");
  13. float price = rs.getFloat("PRICE");
  14. int sales = rs.getInt("SALES");
  15. int total = rs.getInt("TOTAL");
  16. System.out.println(coffeeName + "\t" + supplierID +
  17. "\t" + price + "\t" + sales +
  18. "\t" + total);
  19. }
  20. } catch (SQLException e ) {
  21. JDBCTutorialUtilities.printSQLException(e);
  22. } finally {
  23. if (stmt != null) { stmt.close(); }
  24. }
  25. }

首先,与要使用的数据源建立连接。数据源可以是 DBMS,遗留文件系统或具有相应 JDBC 驱动程序的某些其他数据源。此连接由Connection对象表示。有关详细信息,请参阅建立连接

Statement是表示 SQL 语句的接口。执行Statement对象,它们生成ResultSet对象,这是表示数据库结果集的数据表。您需要Connection对象来创建Statement对象。

例如,CoffeesTables.viewTable使用以下代码创建Statement对象:

  1. stmt = con.createStatement();

有三种不同的陈述:

  • Statement:用于实现没有参数的简单 SQL 语句。
  • PreparedStatement :(扩展Statement。)用于预编译可能包含输入参数的 SQL 语句。有关详细信息,请参阅使用准备语句
  • CallableStatement:(扩展PreparedStatement。)用于执行可能包含输入和输出参数的存储过程。有关详细信息,请参阅存储过程

要执行查询,请从Statement调用execute方法,如下所示:

  • execute:如果查询返回的第一个对象是ResultSet对象,则返回true。如果查询可以返回一个或多个ResultSet对象,请使用此方法。通过重复调用Statement.getResultSet来检索从查询返回的ResultSet对象。
  • executeQuery:返回一个ResultSet对象。
  • executeUpdate:返回一个整数,表示受 SQL 语句影响的行数。如果使用INSERTDELETEUPDATE SQL 语句,请使用此方法。

例如,CoffeesTables.viewTable使用以下代码执行Statement对象:

  1. ResultSet rs = stmt.executeQuery(query);

有关详细信息,请参阅从结果集中检索和修改值。

您可以通过游标访问ResultSet对象中的数据。请注意,此游标不是数据库游标。该游标是一个指向ResultSet对象中一行数据的指针。最初,光标位于第一行之前。您可以调用ResultSet对象中定义的各种方法来移动光标。

例如,CoffeesTables.viewTable重复调用方法ResultSet.next将光标向前移动一行。每次调用next时,该方法都会输出光标当前所在行的数据:

  1. try {
  2. stmt = con.createStatement();
  3. ResultSet rs = stmt.executeQuery(query);
  4. while (rs.next()) {
  5. String coffeeName = rs.getString("COF_NAME");
  6. int supplierID = rs.getInt("SUP_ID");
  7. float price = rs.getFloat("PRICE");
  8. int sales = rs.getInt("SALES");
  9. int total = rs.getInt("TOTAL");
  10. System.out.println(coffeeName + "\t" + supplierID +
  11. "\t" + price + "\t" + sales +
  12. "\t" + total);
  13. }
  14. }
  15. // ...

有关详细信息,请参阅从结果集中检索和修改值。

使用完Statement后,调用Statement.close方法立即释放正在使用的资源。调用此方法时,其ResultSet对象将关闭。

例如,方法CoffeesTables.viewTable通过将finally块包装在finally块中,确保Statement对象在方法结束时关闭,无论抛出任何SQLException对象如何:

  1. } finally {
  2. if (stmt != null) { stmt.close(); }
  3. }

JDBC 在与数据源交互期间遇到错误时会抛出SQLException。有关更多信息,请参见处理 SQL 异常

在 Java SE 7 及更高版本中可用的 JDBC 4.1 中,无论SQLException是否具有SQLException,您都可以使用 try-with-resources 语句自动关闭ConnectionStatementResultSet对象。被抛出自动资源语句由try语句和一个或多个声明的资源组成。例如,您可以修改CoffeesTables.viewTable以使其Statement对象自动关闭,如下所示:

  1. public static void viewTable(Connection con) throws SQLException {
  2. String query = "select COF_NAME, SUP_ID, PRICE, " +
  3. "SALES, TOTAL " +
  4. "from COFFEES";
  5. try (Statement stmt = con.createStatement()) {
  6. ResultSet rs = stmt.executeQuery(query);
  7. while (rs.next()) {
  8. String coffeeName = rs.getString("COF_NAME");
  9. int supplierID = rs.getInt("SUP_ID");
  10. float price = rs.getFloat("PRICE");
  11. int sales = rs.getInt("SALES");
  12. int total = rs.getInt("TOTAL");
  13. System.out.println(coffeeName + ", " + supplierID +
  14. ", " + price + ", " + sales +
  15. ", " + total);
  16. }
  17. } catch (SQLException e) {
  18. JDBCTutorialUtilities.printSQLException(e);
  19. }
  20. }

以下语句是try -with-resources 语句,它声明一个资源stmt,当try块终止时它将自动关闭:

  1. try (Statement stmt = con.createStatement()) {
  2. // ...
  3. }

有关详细信息,请参阅 基本类跟踪中的try - with-resources 语句。