JDBC 准备好的语句创建了一个额外的数据库命中,没有任何参数
JDBC prepared statement creates one extra database hit without any params
我有一个烦人的问题,我不明白为什么会这样。简单介绍一下,我在我的 Spring 引导项目中使用 MySql 和 JDBC 模板实现了批处理(批量插入)。
所以基本上批量插入工作正常,性能真的很棒,但是有一个小问题真的很烦人,当我插入一个 table 时它会导致约束异常两列 (id, value) 上的唯一键。
所以我有这个代码:
private String INSERT_SQL_PARAMS = "INSERT INTO item_params(p_key, p_value, item_id) values (?,?,?)"
override fun saveParams(configParams: Set<ItemParam>) {
jdbcTemplate!!.update { connection ->
connection.autoCommit = false
val ps: PreparedStatement = connection.prepareStatement(INSERT_SQL_PARAMS)
configParams.forEachIndexed { index, it ->
ps.setLong(1, it.configurationId)
ps.setString(2, it.pKey)
ps.setString(3, it.pValue)
ps.addBatch()
if (index != 0 && index % 1000 == 0) {
ps.executeBatch()
connection.commit()
}
}
ps.executeBatch()
connection.commit()
ps
}
}
当我在 spring 引导中使用数据源代理查看日志时,我可以看到实际执行的查询。
所以当我想一次插入例如 2 个项目时,我在日志中看到了这个:
Batch: True, INSERT INTO item_param(item_id, p_key, p_value) values (1, 1, 1), (2, 2, 2)
Batch: False, INSERT INTO item_param(item_id, p_key, p_value) values ()
正如您所看到的,我总是在最后看到一个没有任何值的 extra/spare 语句,出于某种原因,日志显示 Batch = False。
任何人都可以看到我在代码中遗漏的东西吗?为什么会这样?我可以用它做什么?
还有一个问题,比如我有1000条记录,我会执行batch 2次,一次在if语句中,一次在最后。有什么方法可以让我仅在查询中有参数时才说 ps.executeBatch 吗?
因为jdbcTemplate.update
为你执行了你的SQL,所以它会在你的代码末尾自动调用execute
。
由于它只调用了一次 execute
,因此不符合您的目的。试试这个使用 jdbcTemplate.batchUpdate
的 tutorial。它为您实现了对 jdbcConnection
的多次调用。
我有一个烦人的问题,我不明白为什么会这样。简单介绍一下,我在我的 Spring 引导项目中使用 MySql 和 JDBC 模板实现了批处理(批量插入)。
所以基本上批量插入工作正常,性能真的很棒,但是有一个小问题真的很烦人,当我插入一个 table 时它会导致约束异常两列 (id, value) 上的唯一键。
所以我有这个代码:
private String INSERT_SQL_PARAMS = "INSERT INTO item_params(p_key, p_value, item_id) values (?,?,?)"
override fun saveParams(configParams: Set<ItemParam>) {
jdbcTemplate!!.update { connection ->
connection.autoCommit = false
val ps: PreparedStatement = connection.prepareStatement(INSERT_SQL_PARAMS)
configParams.forEachIndexed { index, it ->
ps.setLong(1, it.configurationId)
ps.setString(2, it.pKey)
ps.setString(3, it.pValue)
ps.addBatch()
if (index != 0 && index % 1000 == 0) {
ps.executeBatch()
connection.commit()
}
}
ps.executeBatch()
connection.commit()
ps
}
}
当我在 spring 引导中使用数据源代理查看日志时,我可以看到实际执行的查询。
所以当我想一次插入例如 2 个项目时,我在日志中看到了这个:
Batch: True, INSERT INTO item_param(item_id, p_key, p_value) values (1, 1, 1), (2, 2, 2)
Batch: False, INSERT INTO item_param(item_id, p_key, p_value) values ()
正如您所看到的,我总是在最后看到一个没有任何值的 extra/spare 语句,出于某种原因,日志显示 Batch = False。
任何人都可以看到我在代码中遗漏的东西吗?为什么会这样?我可以用它做什么?
还有一个问题,比如我有1000条记录,我会执行batch 2次,一次在if语句中,一次在最后。有什么方法可以让我仅在查询中有参数时才说 ps.executeBatch 吗?
因为jdbcTemplate.update
为你执行了你的SQL,所以它会在你的代码末尾自动调用execute
。
由于它只调用了一次 execute
,因此不符合您的目的。试试这个使用 jdbcTemplate.batchUpdate
的 tutorial。它为您实现了对 jdbcConnection
的多次调用。