当前位置: 首页 > 知识库问答 >
问题:

QueryDSL@OneToone Join-FetchMode with Hibernate

西门胜涝
2023-03-14
@Entity
public class Customer extends EntityBase {
    @Column(name = "name", nullable = true)
    private String name;

    @OneToOne(mappedBy = "customer")
    private Address address;

    // getter, setter, ...
}

@Entity
public class Address extends EntityBase {
    @OneToOne(optional = false)
    private Customer customer;

    @Column(nullable = true)
    private String street;
    @Column(nullable = true)
    private String zip;
    @Column(nullable = true)
    private String city;

    // getter, setter, ...
}
session.createCriteria(Customer.class).list();
select
    this_.id as id1_1_1_,
    this_.name as name2_1_1_,
    address2_.id as id1_0_0_,
    address2_.city as city2_0_0_,
    address2_.customer_id as customer5_0_0_,
    address2_.street as street3_0_0_,
    address2_.zip as zip4_0_0_ 
from
    Customer this_ 
left outer join
    Address address2_ 
        on this_.id=address2_.customer_id
new HibernateQuery<Customer>(session).from(QCustomer.customer).fetchResults();

使用QueryDSLHibernate的功能:

select
    count(customer0_.id) as col_0_0_
from
    Customer customer0_

select
    customer0_.id as id1_1_,
    customer0_.name as name2_1_
from
    Customer customer0_

select
    address0_.id as id1_0_1_,
    address0_.city as city2_0_1_,
    address0_.customer_id as customer5_0_1_,
    address0_.street as street3_0_1_,
    address0_.zip as zip4_0_1_,
    customer1_.id as id1_1_0_,
    customer1_.name as name2_1_0_
from
    Address address0_
inner join
    Customer customer1_
        on address0_.customer_id=customer1_.id
where
    address0_.customer_id=?

问题:
是否可以为QueryDSL查询设置全局FetchMode。在Hibernate中,您可以用@fetch(FetchMode.join)指定这一点,但不幸的是,QueryDSL忽略了这一点。

因此,我的目标是用QueryDSL加载1000个客户,并且只运行2个查询(count+select)。

new HibernateQuery<Customer>(session)
    .from(QCustomer.customer)
    .leftJoin(QCustomer.customer.address).fetchJoin()
    .fetchResults();
new HibernateQuery<Customer>(session)
    .from(QCustomer.customer)
    .where(QCustomer.customer.address.street.in("Musterstraße 12"))
    .fetchResults();

共有1个答案

史懿轩
2023-03-14

一旦我有同样的问题。但是我使用的是Hibernate JPA条件查询。如果您想在一个查询中获得结果,那么一种方法是使用

@OneToOne(fetch=FetchType.EAGER)
@JoinColumn(name = "address_id", insertable = false, updatable = false, referencedColumnName = "id")
private Address address;

或者我有一个条件查询的解决方案。可能会帮助你把它转换成DSL。

创建Customer类的根。

Root<Customer> root = . . .
Join<Customer, Address> join = (Join<Customer, Address>)root.fetch(Customer_.address);
 类似资料:
  • null 类似于REST查询DSL 用于全文和结构化搜索的查询语言

  • Querydsl是一个Java开源框架用于构建类型安全的SQL查询语句。它采用API代替拼凑字符串来构造查询语句。可跟 Hibernate 和 JPA 等框架结合使用。 基本查询: JPAQuery query = new JPAQuery(entityManager);List<Person> persons = query.from(person)  .where(    person.fir

  • 正在尝试启动并运行查询Dsl(版本3.1.1)和Spring Data JPA(版本1.3.1.release)。 我希望在这里找到答案,但我看不出有什么用。

  • 我希望通过gradle将querydsl引入我的spring-boot项目。尽管在网上找到了几个例子,但实际上没有一个对我有用,因为存在依赖性的问题(我想)。根据QueryDSL支持论坛,gradle还不被支持。但是我想知道所有的事情 这是我的版本。gradle: 但是格拉德失败了: 我尝试将querydsl-apt版本更改为早期版本,但我得到了相同的错误。

  • 我试图使用querydsl-collections,但未能编写简单的groupBy表达式。以下是我的尝试: 但当我试着运行它的时候。我得到:

  • 我正在寻找最简单的方法(尽可能用最少的代码/定制)来提供一个HTTP API来从我的数据库中搜索对象。 到目前为止,我使用的是querydsl和一个简单地委托给底层存储库的Spring控制器: 这很有效。例如,我可以做: 它返回拥有所有者的所有文件夹。 但是,我无法搜索以给定关键字开头的字段。我希望能够这样做: 它应该返回所有以开头的文件夹。我不介意语法是否不同,只要我可以使用“startsWit

  • 我想使用具有QueryDSL支持的Spring Data JDBC。根据Spring留档(https://docs.spring.io/spring-data/jdbc/docs/current/reference/html/#core.extensions.querydsl),它是受支持的,但我无法使其工作。 我使用MariaDB作为数据库,我的SpringBoot版本是2.6.0。 我对pom

  • 我正在尝试使用QueryDSL计算平均日期差异。 我还尝试了其他方法,例如使用,但它没有返回正确的值。如果我们想要获得以秒为单位的日期差异,我们似乎需要找到一些方法来调用数据库特定的日期/时间差函数,而不仅仅是使用减号。 遗憾的是,在JPQL中计算日期差异似乎是不可能的,所以我想querydsl-jpa在这方面也有限制。因此,我们必须编写一个本机SQL查询,或者找到一些黑客来让QueryDSL生成