1. Overview
1.综述
In this tutorial, we’ll explore the differences between JDBC‘s Statement and PreparedStatement
在本教程中。我们将探讨JDBC的StatementPreparedStatement
2. JDBC API Interface
2.JDBC API接口
Both Statement and PreparedStatement can be used to execute SQL queries. These interfaces look very similar. However, they differ significantly from one another in features and performance:
BothStatement和PreparedStatement可以用来执行SQL查询。这些接口看起来非常相似。然而,它们在功能和性能上有很大的不同。
- Statement – Used to execute string-based SQL queries
- PreparedStatement – Used to execute parameterized SQL queries
To be able to use Statement and PreparedStatement in our examples, we’ll declare the h2 JDBC connector as a dependency in our pom.xml file:
为了能够使用Statement和PreparedStatement在我们的例子中。我们将在我们的pom.xml文件中声明h2JDBC连接器为一个依赖项。xml文件中作为依赖。
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.200</version>
</dependency>
public class PersonEntity {
private int id;
private String name;
// standard setters and getters
}
Statement interface accepts strings as SQL queries. Thus, the code becomes less readable when we concatenate SQL
Statement接口接受字符串作为SQL查询。因此,当我们将SQL 。
public void insert(PersonEntity personEntity) {
String query = "INSERT INTO persons(id, name) VALUES(" + personEntity.getId() + ", '"
+ personEntity.getName() + "')";
Statement statement = connection.createStatement();
statement.executeUpdate(query);
}
。
dao.update(new PersonEntity(1, "hacker' --"));
dao.insert(new PersonEntity(1, "O'Brien"))
public void insert(List<PersonEntity> personEntities) {
for (PersonEntity personEntity: personEntities) {
insert(personEntity);
}
}
Fourthly, the Statement interface is suitable for DDL queries like CREATE, ALTER, and :
第四次。pair-s”>DDL查询,如CREATE。ALTER,以及。
public void createTables() {
String query = "create table if not exists PERSONS (ID INT, NAME VARCHAR(45))";
connection.createStatement().executeUpdate(query);
}
Statement interface can’t be used for storing and retrieving files and arrays.
Firstly, the PreparedStatement
首先,PreparedStatement
public void insert(PersonEntity personEntity) {
String query = "INSERT INTO persons(id, name) VALUES( ?, ?)";
PreparedStatement preparedStatement = connection.prepareStatement(query);
preparedStatement.setInt(1, personEntity.getId());
preparedStatement.setString(2, personEntity.getName());
preparedStatement.executeUpdate();
}
@Test
void whenInsertAPersonWithQuoteInText_thenItNeverThrowsAnException() {
assertDoesNotThrow(() -> dao.insert(new PersonEntity(1, "O'Brien")));
}
@Test
void whenAHackerUpdateAPerson_thenItUpdatesTheTargetedPerson() throws SQLException {
dao.insert(Arrays.asList(new PersonEntity(1, "john"), new PersonEntity(2, "skeet")));
dao.update(new PersonEntity(1, "hacker' --"));
List<PersonEntity> result = dao.getAll();
assertEquals(Arrays.asList(
new PersonEntity(1, "hacker' --"),
new PersonEntity(2, "skeet")), result);
}
Thirdly, the PreparedStatement uses pre-compilation. As soon as the database gets a query, it will check the cache before pre-compiling the query. Consequently, if it is not cached, the database engine will save it for the next usage.
第三,PreparedStatement使用预编译。一旦数据库得到一个查询,它将在预编译查询之前检查缓存。因此,如果它没有被缓存,数据库引擎将保存它以备下次使用。。
Moreover, this feature speeds up the communication between the database and the JVM through a non-SQL binary protocol. That is to say, there is less data in the packets, so the communication between the servers goes faster.
此外,该功能通过非SQL二进制协议加快了数据库和JVM之间的通信。也就是说,数据包中的数据较少,所以服务器之间的通信速度更快。
Fourthly, the PreparedStatement
第四,PreparedStatement
public void insert(List<PersonEntity> personEntities) throws SQLException {
String query = "INSERT INTO persons(id, name) VALUES( ?, ?)";
PreparedStatement preparedStatement = connection.prepareStatement(query);
for (PersonEntity personEntity: personEntities) {
preparedStatement.setInt(1, personEntity.getId());
preparedStatement.setString(2, personEntity.getName());
preparedStatement.addBatch();
}
preparedStatement.executeBatch();
}
PreparedStatement provides an easy way to store and retrieve files by using BLOB and CLOB data types. In the same vein, it helps to store lists by converting java.sql.Array to a SQL Array.
PreparedStatement通过使用BLOB和CLOB数据类型,为存储和检索文件提供了简便的方法。同样,它通过将java.sql.Array转换为SQL数组来帮助存储列表。
Lastly, the PreparedStatement implements methods like getMetadata() that contain information about the returned result.
最后一点。PreparedStatement实现方法,例如getMetadata(),这些方法包含有关返回结果的信息。
In this tutorial, we presented the main differences between PreparedStatement and Statement. Both interfaces offer methods to execute SQL queries, but it is more suitable to use Statement for DDL queries and PreparedStatement for DML queries.
在本教程中,我们介绍了PreparedStatement和Statement之间的主要区别。这两个接口都提供了执行SQL查询的方法,但更适合使用Statement进行DDL查询,而PreparedStatement进行DML查询。
As usual, all the code examples are available over on GitHub.
像往常一样,所有的代码实例都可以在GitHub上找到。