博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JDBC的Statement对象
阅读量:5922 次
发布时间:2019-06-19

本文共 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语句。

  • ResultSet executeQuery(String SQL) : 返回一个ResultSet对象。当希望得到一个结果集时使用该方法,就像使用一个SELECT语句。

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/

你可能感兴趣的文章
ssh连接超时问题解决
查看>>
【经典算法】——KMP,深入讲解next数组的求解
查看>>
数独个人项目
查看>>
区间覆盖问题 贪心
查看>>
超级楼梯 递推动规
查看>>
Linux C 创建目录函数mkdir相关(转-清新居士)
查看>>
老程序元对于新程序猿交代的事(身体是革命的本钱)
查看>>
spark共享变量
查看>>
了解oracle数据库的情况
查看>>
结构体初始化函数
查看>>
c++ 拾遗
查看>>
图论$\cdot$强连通分量
查看>>
查看android app 线程信息的命令
查看>>
HTML <img>标签 创建图像映射
查看>>
20165324 《Java程序设计》第3周学习总结
查看>>
github Android-Universal-Image-Loader
查看>>
第二章--第四节:运算符(二)
查看>>
HTML5移动开发即学即用(双色) 王志刚 pdf扫描版
查看>>
POJ 3261 可重叠k次最长重复子串
查看>>
虚拟内存原理
查看>>