如何使用HQL通过所述PK列表过滤具有复合PK的实体?

时间:2016-12-30 18:57:50

标签: java hibernate jpa hql

考虑:

Rails.application.configure do
  config.cache_classes = false
  config.eager_load = false
  config.consider_all_requests_local = true
  if Rails.root.join('tmp/caching-dev.txt').exist?
  config.action_controller.perform_caching = true
  config.cache_store = :memory_store
  config.public_file_server.headers = {
  'Cache-Control' => 'public, max-age=172800'
    }
  else
    config.action_controller.perform_caching = false
config.cache_store = :null_store
  end
  config.active_support.deprecation = :log
  config.active_record.migration_error = :page_load
  config.assets.debug = true
  config.assets.quiet = true
  config.file_watcher = ActiveSupport::EventedFileUpdateChecker
end

@Entity
public class Foo {
    @EmbeddedId
    private FooPK pk;

    public FooPK getPk() { return pk; }
    public void setPk(FooPK pk) { this.pk = pk; }
}

我有一个@Embeddable public class FooPK { @Column(name="ID_A") private Long idA; @Column(name="ID_B") private Long idB; public Long getIdA() { return idA; } public void setIdA(Long idA) { this.idA = idA; } public Long getIdB() { return idB; } public void setIdB(Long idB) { this.idB = idB; } } 我想在HQL中用作过滤器:

List<FooPK>

这不起作用,因为-- Just an example of what I'm trying to do. SELECT foo FROM Foo foo WHERE foo.pk IN (:pkList) 不是单个值。我只是想列出我拥有pks的所有实体。

可以打破列表并执行以下操作:

pk

但我相信你可以看到这是多么丑陋和不可扩展。

我正在使用Java 6 / JPA 1 / Hibernate 3

对于它的价值,我正在使用Oracle,我期望生成的SQL类似于:

-- Ugly
SELECT foo FROM Foo foo
WHERE (
       (foo.pk.idA = :idA1 AND foo.pk.idB = :idB1)
    OR (foo.pk.idA = :idA2 AND foo.pk.idB = :idB2)
    OR (foo.pk.idA = :idA3 AND foo.pk.idB = :idB3)
    -- ...
)

2 个答案:

答案 0 :(得分:0)

您可以使用Criteria API替换hql

// your list of FooPks
List<FooPk> pkList = ....

//Create a criteria over an entity
Criteria  criteria = session.createCriteria(Foo.class);
// add a restriction
criteria.add(Restrictions.in("pk", pkList));
// Execute query and get result.
List<Foo> foos = criteria.list();

答案 1 :(得分:0)

以下适用于MySQL:

  1. javax.persistence.NamedQuery

    创建@Entity
    @NamedQuery(name = "select", query = "SELECT foo FROM Foo foo WHERE foo.pk IN :pks")
    
  2. 通过

    选择
    final TypedQuery<Foo> typedQuery = this.entityManager.createNamedQuery("select", Foo.class);
    final FooPK fooPk = new FooPK(...); // Create example FooPK
    typedQuery.setParameter("pks", Arrays.asList(fooPk, fooPk));
    
    return typedQuery.getResultList();
    
  3. 生成的SQL:

    select ... from ... where foo0_.idA=? and foo0_.idB=? or foo0_.idA=? and foo0_.idB=?
    

    (请注意每个idAidB

    的两项检查