FunTester PreparedStatement 实践和批处理实践

FunTester · 2024年01月10日 · 1702 次阅读

之前在学习 JDBC 使用的过程中,主要使用了实现类是 StatementImpl 单独执行的一些 SQL 语句,一直也是相安无事。在最近复习 JDBC 的过程中,发现了一些新知识,发现了新大陆 PreparedStatement

PreparedStatement 是 Java 编程语言中的一个接口,用于执行预编译的 SQL 语句。它继承自 Statement 接口,允许在执行 SQL 查询之前将参数添加到 SQL 语句中。通过使用 PreparedStatement,可以避免在每次执行查询时重新解析和编译 SQL 语句,提高了性能和安全性。此外,它允许参数化查询,即将动态值作为参数传递到 SQL 语句中,防止了 SQL 注入攻击的风险。PreparedStatement 接口还支持批处理操作,能够有效地执行一组 SQL 语句,减少了与数据库的通信次数,提升了数据库操作的效率。通过预先编译 SQL 语句并重复使用 PreparedStatement 对象,可以更高效地与数据库进行交互,是进行数据库操作时常用的一种方式。

相比较来讲,PreparedStatement 优点还是挺多的:

  1. 提高性能: PreparedStatement 允许数据库预编译 SQL 查询,即使执行多次,也只编译一次,然后在之后的执行中重复使用,减少了 SQL 查询的编译开销,提高了执行效率。
  2. 防止 SQL 注入攻击: 通过参数化查询,PreparedStatement 允许将参数传递到 SQL 语句中,参数值会被严格处理,不会被视为 SQL 语句的一部分,因此有效地预防了 SQL 注入攻击。
  3. 提高安全性: 使用参数化查询可以更安全地处理用户输入数据,避免了直接在 SQL 语句中拼接用户提供的数据,减少了潜在的安全风险。
  4. 易于重用和维护: PreparedStatement 对象可以被重复利用,可以在不同的查询中动态地设置参数值,因此更易于维护和重用。
  5. 支持批处理操作: PreparedStatement 支持批处理操作,可以一次性执行多个 SQL 语句,从而减少了与数据库的交互次数,提升了数据库操作的效率。

预编译相比较动态 SQL 性能是比较强的,特别在批处理的场景下,相比较单个执行 SQL 语句性能就更好了。通常我在批量爬虫的时候,喜欢把所有的数据存一份到数据库中。所以先拿这个场景练手了。

我模拟了批量插入用户数据到数据库中的场景,为了简化,我只保留了 2 列 agename 。下面是我的测试 Demo:

static void main(String[] args) {
    String url = "jdbc:mysql://localhost:3306/FunTester"// 数据库连接url
    String username = "root"// 数据库用户名
    String password = "password"// 数据库密码
    String query = "INSERT INTO users (age, name) VALUES (?, '?')"// SQL语句
    Connection connection = DriverManager.getConnection(url, username, password)// 获取连接
    PreparedStatement preparedStatement = connection.prepareStatement(query)// 获取PreparedStatement
    preparedStatement.setInt(1, getRandomInt(100))// 设置参数
    preparedStatement.setString(2, "FunTester" + StringUtil.getString(20))// 设置参数
    preparedStatement.addBatch()// 添加到批处理
    preparedStatement.setInt(1, getRandomInt(100))// 设置参数
    preparedStatement.setString(2, "FunTester" + StringUtil.getString(20))// 设置参数
    preparedStatement.addBatch()// 添加到批处理
    preparedStatement.executeBatch()// 执行批处理
    preparedStatement.close()// 关闭PreparedStatement
    connection.close()// 关闭连接
}

在使用批处理的过程中,有些事项还是多注意的:

  1. 批处理大小: 批处理操作中的批处理大小是需要考虑的重要因素。批处理太小可能会导致频繁的数据库通信,而批处理太大可能会占用过多的内存或导致性能下降。根据数据库和应用程序的性能特点,进行合理的批处理大小设置和调整。
  2. 事务处理: 批处理操作可能涉及多个 SQL 语句,因此应该考虑是否需要将这些语句放在一个事务中。事务能够确保一组操作要么全部成功提交,要么全部失败回滚,以保持数据的一致性和完整性。
  3. 异常处理: 在批处理操作中,如果某个操作失败,可能会影响整个批处理。因此,在执行批处理操作时,要考虑适当的异常处理机制,例如记录失败的操作并进行后续处理,或者回滚整个批处理。
  4. 性能和优化: 批处理操作能够减少与数据库的交互次数,但也需要注意优化和性能调整。例如,可以合理设置批处理大小、监控数据库连接池的使用情况、对 SQL 语句进行优化以提高执行效率等。
  5. 适用性和场景: 批处理适用于需要一次性执行多个相似操作的场景,如大量的插入、更新或删除操作。但并不是所有情况都适合使用批处理,应根据具体的业务需求和性能考虑来决定是否使用批处理操作。
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册