java - 在没有巨大列表参数的情况下重写 Hibernate 查询

标签 java sql hibernate postgresql

在我的数据库中,我有一个包含 code 列的 zip 表。用户可以上传邮政编码列表,我需要找出哪些已经在数据库中。目前,我使用以下 Hibernate 查询 (HQL) 执行此操作:

select zip.code from Zip zip
where zip.code in (:zipCodes)

:zipCodes参数的值为用户上传的编码列表。但是,在我使用的 Hibernate 版本中有 a bug这限制了此类列表参数的大小,有时我们会超过此限制。

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

选项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 数据库。

最佳答案

将数据库中的所有邮政编码加载到列表中。并在用户输入的邮政编码列表上执行 removeAll(databaseList)

问题解决了!

关于java - 在没有巨大列表参数的情况下重写 Hibernate 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13798868/

相关文章:

java - hibernate中的关联路径是什么?

java - Oracle SOA Suite 中的自定义记录器记录到错误的文件

java - Hibernate连接设计

sql - 在 SQL 中设计多种类型的支付模式?

sql - 消除具有相反值的行

sql - Access 预约系统

java - 为什么java不允许为子类中的静态方法分配较弱的访问权限?

java - 将敌人从一个类别实现到另一个类别时出错

java - 不可变对象(immutable对象)的 Hibernate 组件映射

java - com.mchange.v2.resourcepool.CannotAcquireResourceException : A ResourcePool could not acquire a resource from its primary factory or source