本文共 12080 字,大约阅读时间需要 40 分钟。
以下内容引用自:
一旦获得了数据库的连接,就可以和数据库进行交互。JDBC的Statement,CallableStatement和PreparedStatement接口定义的方法和属性,可以发送SQL命令或PL/SQL命令到数据库,并从数据库接收数据。
在数据库中,它们还定义了帮助Java和SQL数据类型之间转换数据差异的方法。
下表提供了每个接口的用途概要,根据实际目的决定使用哪个接口。
接口 | 推荐使用 |
---|---|
Statement | 可以正常访问数据库,适用于运行静态SQL语句。 Statement接口不接受参数。 |
PreparedStatement | 计划多次使用SQL语句, PreparedStatement接口运行时接受输入的参数。 |
CallableStatement | 适用于当要访问数据库存储过程的时候, CallableStatement接口运行时也接受输入的参数。 |
一、Statement对象
1、创建Statement对象
在准备使用Statement对象执行SQL语句之前,需要使用Connection对象的createStatement()方法创建一个,如下面的示例所示:
Statement stmt = null;try { stmt = conn.createStatement( ); . . .}catch (SQLException e) { . . .}finally { . . .}
当创建了一个Statement对象之后,可以用它的三个执行方法的任一方法来执行SQL语句。
boolean execute(String SQL) : 如果ResultSet对象可以被检索,则返回的布尔值为true,否则返回false 。当需要使用真正的动态SQL时,可以使用这个方法来执行SQL DDL语句。
int executeUpdate(String SQL) : 返回执行SQL语句影响的行的数目。使用该方法来执行SQL语句,是希望得到一些受影响的行的数目,例如,INSERT,UPDATE或DELETE语句。
2、关闭Statement对象
正如关闭一个Connection对象来节约数据库资源,出于同样的原因也应该关闭Statement对象。
简单的调用close()方法就可以完成这项工作。如果关闭了Connection对象,那么它也会关闭Statement对象。然而,应该始终明确关闭Statement对象,以确保真正的清除。
Statement stmt = null;try { stmt = conn.createStatement( ); . . .}catch (SQLException e) { . . .}finally { stmt.close();}
示例:
//STEP 1. Import required packagesimport java.sql.*;public class FirstExample { // JDBC driver name and database URL static final String JDBC_DRIVER = "com.mysql.jdbc.Driver"; static final String DB_URL = "jdbc:mysql://localhost/Test?serverTimezone=UTC"; // Database credentials static final String USER = "root"; static final String PASS = "root"; public static void main(String[] args) { Connection conn = null; Statement stmt = null; try { // STEP 2: Register JDBC driver Class.forName("com.mysql.jdbc.Driver"); // STEP 3: Open a connection System.out.println("Connecting to database..."); conn = DriverManager.getConnection(DB_URL, USER, PASS); // STEP 4: Execute a query System.out.println("Creating statement..."); stmt = conn.createStatement(); String sql; sql = "SELECT id, first, last, age FROM Employees"; ResultSet rs = stmt.executeQuery(sql); // STEP 5: Extract data from result set while (rs.next()) { // Retrieve by column name int id = rs.getInt("id"); int age = rs.getInt("age"); String first = rs.getString("first"); String last = rs.getString("last"); // Display values System.out.print("ID: " + id); System.out.print(", Age: " + age); System.out.print(", First: " + first); System.out.println(", Last: " + last); } // STEP 6: Clean-up environment rs.close(); stmt.close(); conn.close(); } catch (SQLException se) { // Handle errors for JDBC se.printStackTrace(); } catch (Exception e) { // Handle errors for Class.forName e.printStackTrace(); } finally { // finally block used to close resources try { if (stmt != null) stmt.close(); } catch (SQLException se2) { } // nothing we can do try { if (conn != null) conn.close(); } catch (SQLException se) { se.printStackTrace(); } // end finally try } // end try System.out.println("Goodbye!"); }// end main}// end FirstExample
这将产生如下所示结果:
二、PreparedStatement对象
PreparedStatement接口扩展了Statement接口,它用一个常用的Statement对象增加几个高级功能。
这个Statement对象可以提供灵活多变的动态参数。
1、创建PreparedStatement对象
PreparedStatement pstmt = null;try { String SQL = "Update Employees SET age = ? WHERE id = ?"; pstmt = conn.prepareStatement(SQL); . . .}catch (SQLException e) { . . .}finally { . . .}
JDBC中所有的参数都被用?符号表示,这是已知的参数标记。在执行SQL语句之前,必须赋予每一个参数确切的数值。
setXXX()方法将值绑定到参数,其中XXX表示希望绑定到输入参数的Java数据类型。如果忘了赋予值,将收到一个SQLException。
每个参数标记映射它的序号位置。第一标记表示位置1,下一个位置为2等等。这种方法不同于Java数组索引,它是从0开始的。
所有的Statement对象的方法都与数据库交互,(a)execute(),(b)executeQuery(),及(c)executeUpdate()也能被PreparedStatement对象引用。然而,这些方法被SQL语句修改后是可以输入参数的。
2、关闭PreparedStatement对象
正如关闭一个Statement对象,出于同样的原因,也应该关闭PreparedStatement对象。
简单的调用close()方法可以完成这项工作。如果关闭了Connection对象,那么它也会关闭PreparedStatement对象。然而,应该始终明确关闭PreparedStatement对象,以确保真正的清除。
PreparedStatement pstmt = null;try { String SQL = "Update Employees SET age = ? WHERE id = ?"; pstmt = conn.prepareStatement(SQL); . . .}catch (SQLException e) { . . .}finally { pstmt.close();}
示例:
//STEP 1. Import required packagesimport java.sql.*;public class JDBCExample { // JDBC driver name and database URL static final String JDBC_DRIVER = "com.mysql.jdbc.Driver"; static final String DB_URL = "jdbc:mysql://localhost/Test?serverTimezone=UTC"; // Database credentials static final String USER = "root"; static final String PASS = "root"; public static void main(String[] args) { Connection conn = null; PreparedStatement stmt = null; try { // STEP 2: Register JDBC driver Class.forName("com.mysql.jdbc.Driver"); // STEP 3: Open a connection System.out.println("Connecting to database..."); conn = DriverManager.getConnection(DB_URL, USER, PASS); // STEP 4: Execute a query System.out.println("Creating statement..."); String sql = "UPDATE Employees set age=? WHERE id=?"; stmt = conn.prepareStatement(sql); // Bind values into the parameters. stmt.setInt(1, 35); // This would set age stmt.setInt(2, 102); // This would set ID // Let us update age of the record with ID = 102; int rows = stmt.executeUpdate(); System.out.println("Rows impacted : " + rows); // Let us select all the records and display them. sql = "SELECT id, first, last, age FROM Employees"; ResultSet rs = stmt.executeQuery(sql); // STEP 5: Extract data from result set while (rs.next()) { // Retrieve by column name int id = rs.getInt("id"); int age = rs.getInt("age"); String first = rs.getString("first"); String last = rs.getString("last"); // Display values System.out.print("ID: " + id); System.out.print(", Age: " + age); System.out.print(", First: " + first); System.out.println(", Last: " + last); } // STEP 6: Clean-up environment rs.close(); stmt.close(); conn.close(); } catch (SQLException se) { // Handle errors for JDBC se.printStackTrace(); } catch (Exception e) { // Handle errors for Class.forName e.printStackTrace(); } finally { // finally block used to close resources try { if (stmt != null) stmt.close(); } catch (SQLException se2) { } // nothing we can do try { if (conn != null) conn.close(); } catch (SQLException se) { se.printStackTrace(); } // end finally try } // end try System.out.println("Goodbye!"); }// end main}// end JDBCExample
这将产生如下所示结果:
三、CallableStatement对象
正如一个Connection对象可以创建Statement对象和PreparedStatement对象,它也可以创建被用来执行调用数据库存储过程的CallableStatement对象。
1、创建CallableStatement对象
假如需要执行以下的Oracle存储过程:
CREATE OR REPLACE PROCEDURE getEmpName (EMP_ID IN NUMBER, EMP_FIRST OUT VARCHAR) ASBEGIN SELECT first INTO EMP_FIRST FROM Employees WHERE ID = EMP_ID;END;
注意:上面的存储过程已经写入到Oracle数据库中,但正在使用MySQL数据库,那么可以在MySQL的EMP数据库中创建相同的存储过程。
DELIMITER $$DROP PROCEDURE IF EXISTS `EMP`.`getEmpName` $$CREATE PROCEDURE `EMP`.`getEmpName` (IN EMP_ID INT, OUT EMP_FIRST VARCHAR(255))BEGIN SELECT first INTO EMP_FIRST FROM Employees WHERE ID = EMP_ID;END $$DELIMITER ;
三种类型的参数有:IN,OUT和INOUT。PreparedStatement对象只使用IN参数。CallableStatement对象可以使用所有的三个参数。
这里是每个参数的定义:
参数 | 描述 |
---|---|
IN | 在SQL语句创建的时候该参数是未知的。可以用setXXX()方法将值绑定到IN参数中。 |
OUT | 该参数由SQL语句的返回值提供。可以用getXXX()方法获取OUT参数的值。 |
INOUT | 该参数同时提供输入输出的值。可以用setXXX()方法将值绑定参数,并且用getXXX()方法获取值。 |
下面的代码片段展示了基于存储过程如何使用Connection.prepareCall()方法来实例化CallableStatement对象。
CallableStatement cstmt = null;try { String SQL = "{call getEmpName (?, ?)}"; cstmt = conn.prepareCall(SQL); . . .}catch (SQLException e) { . . .}finally { . . .}
SQL的String变量使用参数占位符表示存储过程。
使用CallableStatement对象就像使用PreparedStatement对象。必须在执行该语句之前将值绑定到所有的参数,否则将收到一个SQL异常。
如果有IN参数,只要使用适用于PreparedStatement对象相同的规则和技巧;使用setXXX()方法绑定对应的Java数据类型。
当使用OUT和INOUT参数时,就必须使用额外的CallableStatement方法-registerOutParameter()。 registerOutParameter()方法绑定JDBC数据类型,该数据是存储过程返回的值。
一旦调用存储过程,可以用适当的getXXX()方法来获取OUT参数的值。这个方法将检索到的SQL类型映射成Java数据类型。
2、关闭CallableStatement对象
正如关闭其它的Statement对象,出于同样的原因,也应该关闭PreparedStatement对象。
简单的调用close()方法可以完成这项工作。如果关闭了Connection对象,那么它也会关闭CallableStatement对象。然而,应该始终明确关闭CallableStatement对象,以确保真正的清除。
CallableStatement cstmt = null;try { String SQL = "{call getEmpName (?, ?)}"; cstmt = conn.prepareCall(SQL); . . .}catch (SQLException e) { . . .}finally { cstmt.close();}
示例:
创建存储过程:
DELIMITER $$DROP PROCEDURE IF EXISTS `Test`.`getEmpName` $$CREATE PROCEDURE `Test`.`getEmpName` (IN EMP_ID INT, OUT EMP_FIRST VARCHAR(255))BEGIN SELECT first INTO EMP_FIRST FROM Employees WHERE ID = EMP_ID;END $$DELIMITER ;
代码:
//STEP 1. Import required packagesimport java.sql.*;public class JDBCExample2 { // JDBC driver name and database URL static final String JDBC_DRIVER = "com.mysql.jdbc.Driver"; static final String DB_URL = "jdbc:mysql://localhost/Test?serverTimezone=UTC"; // Database credentials static final String USER = "root"; static final String PASS = "root"; public static void main(String[] args) { Connection conn = null; CallableStatement stmt = null; try { // STEP 2: Register JDBC driver Class.forName("com.mysql.jdbc.Driver"); // STEP 3: Open a connection System.out.println("Connecting to database..."); conn = DriverManager.getConnection(DB_URL, USER, PASS); // STEP 4: Execute a query System.out.println("Creating statement..."); String sql = "{call getEmpName (?, ?)}"; stmt = conn.prepareCall(sql); // Bind IN parameter first, then bind OUT parameter int empID = 102; stmt.setInt(1, empID); // This would set ID as 102 // Because second parameter is OUT so register it stmt.registerOutParameter(2, java.sql.Types.VARCHAR); // Use execute method to run stored procedure. System.out.println("Executing stored procedure..."); stmt.execute(); // Retrieve employee name with getXXX method String empName = stmt.getString(2); System.out.println("Emp Name with ID:" + empID + " is " + empName); stmt.close(); conn.close(); } catch (SQLException se) { // Handle errors for JDBC se.printStackTrace(); } catch (Exception e) { // Handle errors for Class.forName e.printStackTrace(); } finally { // finally block used to close resources try { if (stmt != null) stmt.close(); } catch (SQLException se2) { } // nothing we can do try { if (conn != null) conn.close(); } catch (SQLException se) { se.printStackTrace(); } // end finally try } // end try System.out.println("Goodbye!"); }// end main}// end JDBCExample
这将产生如下所示结果:
测试工程:
==>如有问题,请联系我:easonjim#163.com,或者下方发表评论。<==转载地址:http://qjsvx.baihongyu.com/