在我的数据库中,我有一个zip
带有code
列的表。用户可以上传邮政编码列表,我需要找出哪些已经在数据库中。目前,我使用以下 Hibernate 查询 (HQL) 执行此操作:
select zip.code from Zip zip
where zip.code in (:zipCodes)
该:zipCodes
参数的值是用户上传的代码列表。但是,在我使用的 Hibernate 版本中,有一个错误会限制此类列表参数的大小,有时我们会超出此限制。
所以我需要找到另一种方法来确定数据库中已经存在哪些(可能很长)邮政编码列表。以下是我考虑过的几个选项
选项 A
使用 SQL 而不是 HQL 重写查询。虽然这将避免 Hibernate 错误,但我怀疑如果需要检查 30,000 个邮政编码,性能将会很糟糕。
选项 B
将邮政编码列表拆分为一系列子列表,并对每个子列表执行单独的查询。同样,这将避免 Hibernate 错误,但性能可能仍然很糟糕
选项 C
使用临时表,即将要检查的邮政编码插入到临时表中,然后将其连接到zip
表中。看起来这个解决方案的查询部分应该执行得相当好,但是临时表的创建和最多 30,000 行的插入不会。但也许我的方法不对,这就是我在伪 Java 代码中的想法
/**
* Indicates which of the Zip codes are already in the database
*
* @param zipCodes the zip codes to check
* @return the codes that already exist in the database
* @throws IllegalArgumentException if the list is null or empty
*/
List<Zip> validateZipCodes(List<String> zipCodes) {
try {
// start transaction
// execute the following SQL
CREATE TEMPORARY TABLE zip_tmp
(code VARCHAR(255) NOT NULL)
ON COMMIT DELETE ROWS;
// create SQL string that will insert data into zip_tmp
StringBuilder insertSql = new StringBuilder()
for (String code : zipCodes) {
insertSql.append("INSERT INTO zip_tmp (code) VALUES (" + code + ");")
}
// execute insertSql to insert data into zip_tmp
// now run the following query and return the result
SELECT z.*
FROM zip z
JOIN zip_tmp zt ON z.code = zt.code
} finally {
// rollback transaction so that temporary table is removed to ensure
// that concurrent invocations of this method operate do not interfere
// with each other
}
}
有没有比上面的伪代码更有效的方法来实现这一点,还是有其他我没有想到的解决方案?我正在使用 Postgres 数据库。