Statement
Statement
用于执行静态的 SQL 查询,通常在 SQL 语句不会频繁变化的情况下使用。
特点
- 不支持参数化查询:SQL 语句直接嵌入在代码中,在语句中添加参数较为麻烦。
- 存在 SQL 注入风险:由于直接拼接字符串,容易受到 SQL 注入攻击。
- 性能较低:每次执行 SQL 语句时,数据库都需要重新编译和优化语句。也就是说
Statement
适合只执行一次的SQL语句
示例
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class StatementExample {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/your_database";
String user = "your_username";
String password = "your_password";
String userNameInput = "exampleUser";
String passwordInput = "examplePass";
// SQL 语句直接拼接
String sql = "SELECT * FROM users WHERE username = '" + userNameInput + "' AND password = '" + passwordInput + "'";
try (Connection conn = DriverManager.getConnection(url, user, password);
Statement statement = conn.createStatement();
ResultSet resultSet = statement.executeQuery(sql)) {
while (resultSet.next()) {
String username = resultSet.getString("username");
String userPassword = resultSet.getString("password");
System.out.println("Username: " + username + ", Password: " + userPassword);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
PreparedStatement
PreparedStatement
用于执行带参数的预编译 SQL 查询,通常在 SQL 语句包含参数时使用。
特点
- 支持参数化查询:SQL 语句中的参数使用占位符
?
,参数在执行时动态设置。 - 防止 SQL 注入:通过参数化查询有效防止 SQL 注入攻击。
- 性能较高:SQL 语句只需编译和优化一次,之后可以重复使用,提高性能,适合需要多次重复执行的SQL语句。
示例
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class PreparedStatementExample {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/your_database";
String user = "your_username";
String password = "your_password";
String sql = "SELECT * FROM users WHERE username = ? AND password = ?";
String userNameInput = "exampleUser";
String passwordInput = "examplePass";
try (Connection conn = DriverManager.getConnection(url, user, password)) {
// 创建 PreparedStatement 对象
PreparedStatement preparedStatement = conn.prepareStatement(sql);
// 设置 SQL 参数
preparedStatement.setString(1, userNameInput);
preparedStatement.setString(2, passwordInput);
// 执行查询
ResultSet resultSet = preparedStatement.executeQuery();
// 处理查询结果
while (resultSet.next()) {
String username = resultSet.getString("username");
String userPassword = resultSet.getString("password");
System.out.println("Username: " + username + ", Password: " + userPassword);
}
// 关闭 ResultSet 对象
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
主要区别
特性 | Statement | PreparedStatement |
---|---|---|
使用场景 | 静态 SQL 语句 | 动态 SQL 语句 |
参数化查询 | 不支持 | 支持 |
SQL 注入风险 | 高 | 低(防止 SQL 注入) |
性能 | 每次执行都要编译和优化 | 预编译一次后可重复使用,性能较高 |
代码复杂度 | 较低 | 略高(需要设置参数) |
适用性 | 简单的、一次性的查询 | 复杂的、多参数的、重复执行的查询 |
总结
Statement
适用于简单的一次性查询,但存在 SQL 注入风险,性能较低,且参数化查询编写代码不方便。同时安全性较低,容易受到SQL注入攻击。PreparedStatement
适用于复杂的多次查询,编写参数化查询时较为方便,可以使用占位符来设置参数,同时可以防止SQL注入,安全性较高。