PreparedStatement 中的这些值/参数是什么意思?
What do these values / parameters in PreparedStatement mean?
我正在学习如何使用 JDBC 和 DAO tutorial 创建数据层。
但是我卡在了这一点上:PreparedStatement statement = prepareStatement(connection, SQL_UPDATE, false, values);
为什么要这样使用 prepareStatement?
如有任何解释和建议,我将不胜感激。
我查看了 documentation 并搜索了相关示例,但没有找到对这种构造的任何解释。我熟悉这样的表达式,当 prepareStatement 方法被 connection 对象调用时:
Connection connection = daoFactory.getConnection();
PreparedStatement statement = connection.prepareStatement(SQL);
但是我不明白为什么 PreparedStatement 会像下面的例子那样实现:
public void update(User user) throws DAOException {
if (user.getId() == null) {
throw new IllegalArgumentException("User is not created yet, the user ID is null.");
}
Object[] values = {
user.getEmail(),
user.getFirstname(),
user.getLastname(),
toSqlDate(user.getBirthdate()),
user.getId()
};
try (
Connection connection = daoFactory.getConnection();
PreparedStatement statement = prepareStatement(connection, SQL_UPDATE, false, values);
) {
int affectedRows = statement.executeUpdate();
if (affectedRows == 0) {
throw new DAOException("Updating user failed, no rows affected.");
}
} catch (SQLException e) {
throw new DAOException(e);
}
}
此方法在教程中给出,它是 DAOUtil class:
的一部分
public static PreparedStatement prepareStatement
(Connection connection, String sql, boolean returnGeneratedKeys, Object... values)
throws SQLException
{
PreparedStatement statement = connection.prepareStatement(sql,
returnGeneratedKeys ? Statement.RETURN_GENERATED_KEYS : Statement.NO_GENERATED_KEYS);
setValues(statement, values);
return statement;
}
DaoUtil prepareStatement 方法由 DaoImpl 在 try-with-resources 构造中使用。那里的初始化工作方式不允许使用多个语句,每个资源都必须用一个表达式进行初始化。该方法将相关的初始化代码组合在一起,以便资源初始化代码可以调用它。
同样,通过这种方式,PreparedStatement 的参数以更具声明性的方式给出,而设置它们的代码隐藏在实用程序方法中。参数设置非常松散且容易出错(没有类型检查等问题),所显示的内容对于简明教程很有用,但不是在实际项目中复制的最佳选择。
如果参数设置代码抛出 SQLException,则方法调用不会返回 PreparedStatement,也不会关闭。实际上,这通常并不可怕,因为它会发生
仅当 sql 中的参数与占位符匹配时出现错误(这意味着您遇到了更严重的问题)。
重要的是关闭连接和准备语句。否则,您可以尝试不同的编写方式并比较生成的代码。
我正在学习如何使用 JDBC 和 DAO tutorial 创建数据层。
但是我卡在了这一点上:PreparedStatement statement = prepareStatement(connection, SQL_UPDATE, false, values);
为什么要这样使用 prepareStatement?
如有任何解释和建议,我将不胜感激。
我查看了 documentation 并搜索了相关示例,但没有找到对这种构造的任何解释。我熟悉这样的表达式,当 prepareStatement 方法被 connection 对象调用时:
Connection connection = daoFactory.getConnection();
PreparedStatement statement = connection.prepareStatement(SQL);
但是我不明白为什么 PreparedStatement 会像下面的例子那样实现:
public void update(User user) throws DAOException {
if (user.getId() == null) {
throw new IllegalArgumentException("User is not created yet, the user ID is null.");
}
Object[] values = {
user.getEmail(),
user.getFirstname(),
user.getLastname(),
toSqlDate(user.getBirthdate()),
user.getId()
};
try (
Connection connection = daoFactory.getConnection();
PreparedStatement statement = prepareStatement(connection, SQL_UPDATE, false, values);
) {
int affectedRows = statement.executeUpdate();
if (affectedRows == 0) {
throw new DAOException("Updating user failed, no rows affected.");
}
} catch (SQLException e) {
throw new DAOException(e);
}
}
此方法在教程中给出,它是 DAOUtil class:
的一部分public static PreparedStatement prepareStatement
(Connection connection, String sql, boolean returnGeneratedKeys, Object... values)
throws SQLException
{
PreparedStatement statement = connection.prepareStatement(sql,
returnGeneratedKeys ? Statement.RETURN_GENERATED_KEYS : Statement.NO_GENERATED_KEYS);
setValues(statement, values);
return statement;
}
DaoUtil prepareStatement 方法由 DaoImpl 在 try-with-resources 构造中使用。那里的初始化工作方式不允许使用多个语句,每个资源都必须用一个表达式进行初始化。该方法将相关的初始化代码组合在一起,以便资源初始化代码可以调用它。
同样,通过这种方式,PreparedStatement 的参数以更具声明性的方式给出,而设置它们的代码隐藏在实用程序方法中。参数设置非常松散且容易出错(没有类型检查等问题),所显示的内容对于简明教程很有用,但不是在实际项目中复制的最佳选择。
如果参数设置代码抛出 SQLException,则方法调用不会返回 PreparedStatement,也不会关闭。实际上,这通常并不可怕,因为它会发生 仅当 sql 中的参数与占位符匹配时出现错误(这意味着您遇到了更严重的问题)。
重要的是关闭连接和准备语句。否则,您可以尝试不同的编写方式并比较生成的代码。