重写Hibernate查询没有巨大的列表参数

Dón*_*nal 9 java sql postgresql hibernate

在我的数据库中,我有一个zip包含code列的表.用户可以上传Zip代码列表,我需要确定哪些已经存在于数据库中.目前,我使用以下Hibernate查询(HQL)执行此操作:

select zip.code from Zip zip
where zip.code in (:zipCodes)
Run Code Online (Sandbox Code Playgroud)

:zipCodes参数的值是用户上载的代码列表.但是,在Hibernate的版本中,我使用的是一个限制此类列表参数大小的错误,有时候我们超出了这个限制.

因此,我需要找到另一种方法来确定哪些(可能非常长的)邮政编码列表已经存在于数据库中.以下是我考虑过的几个选项

选项A.

使用SQL而不是HQL重写查询.虽然这将避免Hibernate错误,但我怀疑如果需要检查30,000个Zip代码,性能将会很糟糕.

选项B.

将Zip代码列表拆分为一系列子列表,并为每个子列表执行单独的查询.同样,这将避免Hibernate错误,但性能可能仍然很糟糕

选项C.

使用临时表,即将要检查的Zip代码插入临时表,然后将其连接到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
  }    
}
Run Code Online (Sandbox Code Playgroud)

有没有比上面的伪代码更有效的方法来实现它,还是有其他解决方案,我没有想到?我正在使用Postgres数据库.

Kai*_*Kai 0

选项 D:
从数据库加载所有现有的邮政编码(分页?)并在应用程序中进行比较。

关于你的选项A:
我记得SQL查询长度有限制,但那是在DB2上,我不知道PostgreSQL上是否有限制。