121.md 4.8 KB
Newer Older
W
wizardforcel 已提交
1
# Java JDBC `PreparedStatement`示例
W
wizardforcel 已提交
2 3 4

> 原文: [https://howtodoinjava.com/java/jdbc/how-to-execute-preparedstatement-using-jdbc/](https://howtodoinjava.com/java/jdbc/how-to-execute-preparedstatement-using-jdbc/)

W
wizardforcel 已提交
5
在数据库管理系统中, [**预备语句**](https://en.wikipedia.org/wiki/Prepared_statement)**参数化语句**是用于高效重复执行相同或相似数据库语句的功能。 预备语句通常与 SQL 语句(例如查询或更新)一起使用,采用模板的形式,在每次执行期间将某些常量值替换为模板。
W
wizardforcel 已提交
6

W
wizardforcel 已提交
7 8
一个典型的模板如下所示:“`NSERT INTO EMPLOYEE (ID, NAME) VALUES (?, ?);`
此处,值在运行时在以“`?`”表示的占位符处设置。
W
wizardforcel 已提交
9

W
wizardforcel 已提交
10
## 预备语句如何工作?
W
wizardforcel 已提交
11 12 13 14 15 16 17 18

大多数关系数据库通过四个步骤来处理 JDBC / SQL 查询:

1.  解析传入的 SQL 查询
2.  编译 SQL 查询
3.  规划/优化数据采集路径
4.  执行优化的查询/获取并返回数据

W
wizardforcel 已提交
19
对于发送到数据库的每个 SQL 查询,一个`Statement`将始终执行上述四个步骤。 **在**上面的执行过程中,`PreparedStatement`预先执行步骤(1)–(3)。 因此,在创建`PreparedStatement`时,会立即执行一些预优化。 这样做的目的是减轻执行时数据库引擎的负担。
W
wizardforcel 已提交
20

W
wizardforcel 已提交
21
## 使用预备语句比简单的 JDBC 语句的优势
W
wizardforcel 已提交
22 23

*   SQL 语句的预编译和数据库侧缓存可提高整体执行速度,并能够批量重用同一 SQL 语句。
W
wizardforcel 已提交
24 25
*   通过内置对引号和其他特殊字符的转义,自动防止 SQL 注入攻击。 请注意,这要求您使用任何`PreparedStatement.setXxx()`方法来设置值,并且不能通过字符串连接使用 SQL 字符串中的值。
*   除了以上两种主要用法外,预备语句还使处理诸如 BLOB 和 CLOB 之类的复杂对象变得容易。
W
wizardforcel 已提交
26

W
wizardforcel 已提交
27
如果您错过了,在以前的文章中,我们了解了 [JDBC 驱动的类型](//howtodoinjava.com/java/jdbc/jdbc-basics-types-of-jdbc-drivers/ "JDBC Basics : Types of JDBC Drivers?")和一些基本操作,例如[使用 JDBC](//howtodoinjava.com/java/jdbc/jdbc-mysql-database-connection-example/ "JDBC MySQL Database Connection Example") 建立数据库连接,然后是[如何执行`SELECT`查询](//howtodoinjava.com/misc/jdbc-select-query-example/ "JDBC SELECT Query Example"),然后单击[`INSERT`查询示例](//howtodoinjava.com/java/jdbc/jdbc-sql-insert-query-example/ "JDBC SQL INSERT Query Example")
W
wizardforcel 已提交
28 29 30

![JDBC-Icon](img/353e2fc90002c7f65b66549c16f491fa.png)

W
wizardforcel 已提交
31
**执行预备语句**需要执行以下步骤:
W
wizardforcel 已提交
32 33

1)建立数据库连接
W
wizardforcel 已提交
34 35

2)设置值并执行预备语句
W
wizardforcel 已提交
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64

前提条件包括至少设置数据库架构和创建表。

```java
CREATE SCHEMA 'JDBCDemo' ;

CREATE TABLE 'JDBCDemo'.'EMPLOYEE'
(
	'ID' INT NOT NULL DEFAULT 0 ,
	'FIRST_NAME' VARCHAR(100) NOT NULL ,
	'LAST_NAME' VARCHAR(100) NULL ,
	'STAT_CD' TINYINT NOT NULL DEFAULT 0
);

```

让我们在代码中编写以上步骤:

## 1)建立 JDBC 数据库连接

尽管我们在建立 [JDBC 连接](//howtodoinjava.com/java/jdbc/jdbc-mysql-database-connection-example/)时已经了解了它,但是让我们用这个简单的代码片段来回顾一下。

```java
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager
	.getConnection("jdbc:mysql://localhost:3306/JDBCDemo", "root", "password");

```

W
wizardforcel 已提交
65
## 2)设置值并执行`PreparedStatement`
W
wizardforcel 已提交
66

W
wizardforcel 已提交
67
这是帖子中的主要步骤和核心部分。 它需要创建一个`Statement`对象,然后使用其`executeQuery()`方法。
W
wizardforcel 已提交
68 69 70 71 72 73 74 75 76 77 78 79 80 81

```java
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.setInt(1, 87);
pstmt.setString(2, "Lokesh");
pstmt.setString(3, "Gupta");
pstmt.setInt(4, 5);

int affectedRows = pstmt.executeUpdate();

```

让我们看看整个代码在工作。

W
wizardforcel 已提交
82
## 完整的 JDBC `PreparedStatement`示例
W
wizardforcel 已提交
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132

```java
package com.howtodoinjava.jdbc.demo;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;

public class PreparedStatementDemo 
{
	public static void main(String[] args) 
	{
		Connection connection = null;
		PreparedStatement pstmt = null;
		String sql = "INSERT INTO EMPLOYEE (ID,FIRST_NAME,LAST_NAME,STAT_CD) VALUES (?,?,?,?)";
		try 
		{
			Class.forName("com.mysql.jdbc.Driver");
			connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/JDBCDemo", "root", "password");

			pstmt = connection.prepareStatement(sql);
			pstmt.setInt(1, 87);
			pstmt.setString(2, "Lokesh");
			pstmt.setString(3, "Gupta");
			pstmt.setInt(4, 5);
			int affectedRows = pstmt.executeUpdate();
			System.out.println(affectedRows + " row(s) affected !!");
		} 
		catch (Exception e) {
			e.printStackTrace();
		}finally {
			try {
				pstmt.close();
				connection.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}

Output:

1 row(s) affected !!

```

以上就是这篇文章。 如果需要解释,请给我评论。

**快乐学习!**