database - Hibernate:LEFT JOIN FETCH 具有用于连接的多列

标签 database hibernate jpa hql

我们想在 HQL 中使用两列进行左外连接两个表。

连接的第二列在逻辑级别没有相关性,并且不以任何方式限制结果集。它是分区键,仅用作加速物理数据访问的优化。

在 SQL 中它会是这样的

select * 
from t1 
left outer join t2 
on t1.id = t2.parent_id 
and t1.partion_key = t2.partition_key

我们尝试的以下方法均无效:

  • 我们可以在 HQL left join fetch 中进行外部连接,并且可以使用 with 在连接中指定附加条件,但两者都不能结合在一起。 documentation 中明确提到了此限制: “Fetch 也不应与 impromptu with condition 一起使用”。

  • 使用额外的 where 条件 t1.partion_key = t2.partition_key 不起作用,因为它将查询的语义从外连接更改为内连接:当没有数据匹配时条件不成立,该行被忽略。

  • 使用 oracle 语法 t1.partion_key = t2.partition_key (+) 也不起作用,因为它会导致 SQL 查询混合了 ANSI 和 Oracle 语法。

  • 我们考虑过使用组合键,但这并不正确,因为在逻辑层面上,键只是 id。我们不想让物理数据建模(分区)影响逻辑模型。

我们如何用 HQL 表达我们想要的查询?

最佳答案

1) 自 hibernate 以来 5.1我们可以在 HQL 查询中对不相关的类使用“加入”。在这种情况下,我们可以使用这个 HQL 查询:

select 
    p as parent, 
    c as child 
from 
    Parent p 
    left join Child c on c.parentId = p.id and c.partitionKey = p.partitionKey

2) 另一种方法是如下修改实体(将两个 JoinColumn 添加到 Parent 实体中的 children 属性并替换 parentChild 实体中的简单 parentId 属性的“多对一”关系):

@Entity
public class Parent {    
    @Id
    @GeneratedValue
    private Integer id;

    @Column(name = "partition_key")
    private Integer partitionKey;

    @OneToMany
    @JoinColumns({
            @JoinColumn(name = "parent_id", referencedColumnName = "id"),
            @JoinColumn(name = "partition_key", referencedColumnName = "partition_key")
    })
    private List<Child> children;
}

@Entity
public class Child {    
    @Id
    @GeneratedValue
    private Integer id;

    @Column(name = "partition_key")
    private Integer partitionKey;

    @Column(name = "parent_id")
    private Integer parentId;

    // @ManyToOne
    // private Parent parent;
}

然后我们可以使用以下简单的 JPQL 查询:

select distinct p as parent from Parent p left join fetch p.children c

这两个查询都由 Hibernate 翻译为喜欢这个 SQL 查询:

select 
    p.id, 
    p.partition_key, 
    s.id, 
    s.parent_id, 
    s.partition_key 
from 
    parents p 
    left outer join children c on (c.parent_id=p.id and c.partition_key=p.partition_key) 

工作演示是 here .

关于database - Hibernate:LEFT JOIN FETCH 具有用于连接的多列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49118193/

相关文章:

java - FetchType.EAGER 执行时间很多

database - 如何查找SQLITE数据库文件版本

java - 通过服务 API 公开 Hibernate 条件

java.lang.NoClassDefFoundError : org/hibernate/cfg/Configuration 错误

java - Spring Boot 中使用 3 个表进行 Hibernate 映射的问题

hibernate - Hibernate/JPA 中的@OrderColumn 导致冗余的 UPDATE SQL 语句

java - SQL 列 Jpa 中最常见的值

php - MYSQL SELECT 从带有或不带有外键的两个表中获取行

PHP从数据库结果中对具有多个维度的数组进行分组

mongodb - MongoDB、CouchDB 和 Cassandra 需要 Solr/Lucene 吗?