JDBC的Statement对象
以下内容引用自http://wiki.jikexueyuan.com/project/jdbc/statements.html:
一旦获得了数据库的连接,就可以和数据库进行交互。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 packages
import 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 packages
import 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) AS
BEGIN
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 packages
import 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
这将产生如下所示结果:
测试工程:https://github.com/easonjim/5_java_example/tree/master/jdbcbasics/test3
JDBC的Statement对象的更多相关文章
- jdbc中的Statement对象和Preparedstatement对象的区别,以及通过jdbc操作调用存储过程
一. java.sql.* 和 javax.sql.*的包的类结构 |- Driver接口: 表示java驱动程序接口.所有的具体的数据库厂商要来实现此接口. |- connect(url, p ...
- JDBC Statement对象执行批量处理实例
以下是使用Statement对象的批处理的典型步骤序列 - 使用createStatement()方法创建Statement对象. 使用setAutoCommit()将自动提交设置为false. 使用 ...
- jdbc执行Statement接口的步骤
jdbc执行Statement接口的步骤如下: 1)驱动注册程序: Class.forName(com.mysql.jdbc.Driver); 2)获取连接对象: Connection conn = ...
- jdbc之Statement和Preparement
Jdbc DML 操作 Statement:静态SQL操作 每次操作都会将sql语句提交到数据库执行一次,性能比较低 // 1.加载驱动程序 Class.forName(driverName); // ...
- JDBC与Statement和PreparedStatement的区别
一.先来说说,什么是java中的Statement:Statement是java执行数据库操作的一个重要方法,用于在已经建立数据库连接的基础上,向数据库发送要执行的SQL语句.具体步骤: 1.首先导入 ...
- JDBC PreparedStatement Statement
参考:预编译语句(Prepared Statements)介绍,以MySQL为例 1. 背景 本文重点讲述MySQL中的预编译语句并从MySQL的Connector/J源码出发讲述其在Java语言中相 ...
- 使用Statement对象执行静态sql语句
import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java ...
- Statement对象
Statement 对象 创建 Statement 对象 在你准备使用 Statement 对象执行 SQL 语句之前,你需要使用 Connection 对象的 createStatement() 方 ...
- MySql中PreparedStatement对象与Statement对象
PreparedStatement对象与Statement对象相比 1.代码的可读性和可维护性. 2.PreparedStatement能保证安全性(解决sql注入问题) 3.PreparedSt ...
随机推荐
- 移动端 H5 拍照 从手机选择图片,移动端预览,图片压缩,图片预览,再上传服务器
前言:最近公司的项目在做全网营销,要做非微信浏览器的wap 站 的改版,其中涉及到的一点技术就是采用H5 选择手机相册中的图片,或者拍照,再将获取的图片进行压缩之后上传. 这个功能模块主要有这5点比较 ...
- MAC 添加共享,脚本执行
Linux需要首先安装 yum install samba-client linxu添加windows 公共盘 mount -t cifs user=guest,password=guest // ...
- python学习笔记-02
四.函数 1.定义函数 (1)定义规则 介绍列表方法的时候已经大概说过函数,学过数学的人都知道函数,给一个参数返回一个值.函数也可以自己定义.用如下的格式: >>>def 函数名(参 ...
- Java8新特性 Stream流式思想(三)
Stream接口中的常用方法 forEach()方法package cn.com.cqucc.demo02.StreamMethods.Test02.StreamMethods; import jav ...
- vue之Render函数
(1)什么是Render函数 先来看一个场景,在博客网中,一般有一级标题.二级标题.三级标题...,为了方便分享url,它们都做成了锚点,点击后,会将内容加载网址后面,以#分隔. 例如‘特性’是一个& ...
- css + 和 ~的区别
<style type="text/css"> h1 + p { margin-top:50px; color:red; } </style> <p& ...
- 模板—trie图
做了某题之后发现trie的AC自动机太垃圾了,动不动就TLE,然后我就去学了trie图. #include<iostream> #include<cstdio> using n ...
- 如何用SQL语句在指定字段前面插入新的字段?
如何用SQL语句在指定字段前面插入新的字段? 2007-10-17 09:28:00| 分类: 笔记|举报|字号 订阅 create proc addcolumn @tablename va ...
- javascript的prototype经典使用场景
prototype的经典使用场景就是为对象增加属性和方法,如给自定义的Man对象增加个姓名属性和语言方法: function man() { this.age = "22&qu ...
- iOS 导航栏风格
IOS-导航栏风格 导航控制器可以用几种不同的风格来显示自身.默认风格就是标准的灰色外观.目前支持三种不同的风格. 风 格 描 述 UIBarStyleDefault 默认风格:灰色背景, ...