spring - postgresql Not In 子句使用批量更新
问题描述
我需要的是一个查询来删除除我指定的ID之外的所有ID。因此我在春天有这样一个疑问:
private final String SQL_Clear_Deleted_Options = "DELETE FROM vote_votes WHERE poll_id=? AND option_id <> ?";
我正在使用 jdbcTemplate 和 batchUpdate 这样做。我还使用 <> 运算符来表示 NOT IN 子句。这是我的代码:
public void clearDeletedOptions(int id) {
int[] argTypes = { Types.INTEGER, Types.INTEGER };
List<Object[]> batchArgs = new ArrayList<>();
for (int i:ids) {
batchArgs.add(new Object[]{id, i});
}
jdbcTemplate.batchUpdate(SQL_Clear_Deleted_Options, batchArgs, argTypes);
}
在上面的代码中 ids 是一个整数列表,表示查询中的 option_id 。我想知道为什么它会相反并删除所有给定的ID!每件事看起来都很好,batchArges 包含对 (poll_id,option_id) 指示不应删除的特定 poll_id 和 option_ids。
问题是什么?
解决方案
这是因为,每个不等于都会删除其余的记录。解决方案之一是jdbcTemplate.execute
通过动态创建 sql 来使用。
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.jdbc.core.JdbcTemplate;
@SpringBootApplication
public class Application implements CommandLineRunner {
private static final Logger log = LoggerFactory.getLogger(Application.class);
public static void main(final String args[]) {
SpringApplication.run(Application.class, args);
}
@Autowired
JdbcTemplate jdbcTemplate;
@Override
public void run(final String... strings) throws Exception {
log.info("Creating tables");
jdbcTemplate.execute("DROP TABLE votes IF EXISTS");
jdbcTemplate.execute("CREATE TABLE votes(id SERIAL, poll_id integer, option_id integer)");
final List<Object[]> splitUpValues = Arrays.asList("1 0", "1 1", "2 2", "1 3", "1 4").stream()
.map(name -> name.split(" ")).collect(Collectors.toList());
splitUpValues.forEach(name -> log.info(String.format("Inserting votes record for %d %d",
Integer.valueOf((String) name[0]), Integer.valueOf((String) name[1]))));
jdbcTemplate.batchUpdate("INSERT INTO votes(poll_id, option_id) VALUES (?,?)", splitUpValues);
log.info("Querying for all votes");
jdbcTemplate
.query("SELECT id, poll_id, option_id FROM votes",
(rs, rowNum) -> new Votes(rs.getLong("id"), rs.getInt("poll_id"), rs.getInt("option_id")))
.forEach(vote -> log.info(vote.toString()));
jdbcTemplate.execute("DELETE FROM votes WHERE poll_id = 1 AND option_id not in (1, 3)");
log.info("Querying for all votes after batch delete");
jdbcTemplate
.query("SELECT id, poll_id, option_id FROM votes",
(rs, rowNum) -> new Votes(rs.getLong("id"), rs.getInt("poll_id"), rs.getInt("option_id")))
.forEach(vote -> log.info(vote.toString()));
}
}
推荐阅读
- google-maps-api-3 - SquareSpace 上的 Google Maps API - 未捕获的类型错误
- hash - 预测未来的 CRC 值
- angular - 使用角度从另一个组件执行功能时更新组件的更改
- python - Python MultiProcessing apply_async 等待所有进程完成
- python - 使用 Headless WebDriver 应用函数
- java - google dialogflow 上的操作 - 使用 Java 的 webhook
- c# - 防止 SendGrid 消息中出现重复的电子邮件地址?
- c++ - 为什么我的十进制到二进制输出不会反转?
- google-search - 您如何在 Google 上搜索以类似词缀结尾的网站?
- php - 用微时间测量持续时间随机结果为零