gpt4 book ai didi

java - 如何使用 hibernate 查询仅获取具有关联的实体的某些字段?

转载 作者:行者123 更新时间:2023-12-05 06:36:07 25 4
gpt4 key购买 nike

我有一个实体,它有多个字段,其中一些是关联。假设实体具有与以下类似的结构:

@Entity
@Table(name="foos")
public class Foo {

public Foo() {}
@Id
private Long id;

@Column
private String name;

@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "bar_id")
private Bar bar;

@ManyToOne
@JoinColumn(name = "bar1_id")
private Bar1 bar1;

@ManyToOne
@JoinColumn(name = "bar2_id")
private Bar2 bar2;

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
@JoinColumn(name = "foo_id")
private List<Bar3> bar3;

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
@JoinColumn(name = "foo_id")
private List<Bar4> bar4;

//getters and setters
}

我的问题是如何使用 Hibernate 查询只加载部分字段而不加载整个实体?
我只想获取 id、bar、bar1 和 bar3,而不想获取创建的 Foo 对象中的其余字段(name、bar2、bar4)。
我是 Hibernate 的新手,所以任何建议都将不胜感激。

最佳答案

hibernate 5, Spring 5

您有多种选择,但最简单的选择是使用您想要的列/字段创建一个简单的@Query,请参阅我的一个项目中的示例代码。

首先,您不需要使用子集字段创建 DTO,我将展示两者和混合版本的选项。

选项一:具有列/字段子集的 DTO 对象。

DTO 存储库代码:

@Query( "SELECT new com.your.package.name.customers.CompanyDTOIdName(c.id, c.name) " +
"FROM Company c " +
"WHERE c.enabled = 1 " +
"ORDER BY c.name ASC" )
List<CompanyDTOIdName> compDtoNameWhereEnabledTrue();

DTO 子集对象:

public class CompanyDTOIdName {

private long id;
private String name;

public CompanyDTOIdName(long id, String name) {
this.id = id;
this.name = name;
}

// accessors/mutators methods
}

Hibernate SQL 执行代码:

SELECT
new com.your.package.name.customers.CompanyDTOIdName(c.id, c.name)
FROM
Company c
WHERE
c.enabled = 1
ORDER BY
c.name ASC

select
company0_.companyId as col_0_0_,
company0_.name as col_1_0_
from
ome_company company0_
where
company0_.enabled=1
order by
company0_.name ASC

主要缺点是您将需要一个单独的 DTO 对象,其中包含每个不同的列组合。


选项二:使用原始@Entity

第二个选项更简单,适用于任何列子集,如下所示:

存储库代码:

@Query( "SELECT new com.your.package.name.customers.Company(c.id, c.name) " +
"FROM Company c " +
"WHERE c.enabled = 1 " +
"ORDER BY c.name ASC"
)
List<Company> compNameWhereEnabledTrue();

Company 是您的原始@Entity 对象。

在这种情况下,您的 Entity 对象必须包含空构造函数以及与您的 @Query 语句匹配的构造函数:

public void Company() {}
public void Company(Long id, String name) { /* code omitted */ }

Hibernate SQL 执行代码:

SELECT
new com.your.package.name.customers.Company(c.id, c.name)
FROM
Company c
WHERE
c.enabled = 1
ORDER BY
c.name ASC

select
company0_.companyId as col_0_0_,
company0_.name as col_1_0_
from
ome_company company0_
where
company0_.enabled=1
order by
company0_.name ASC

警告:我相信您可以看出这种方法的问题。仅加载指定的列/字段。如果您尝试访问未启动的字段,您将获得异常。


使用接口(interface)的混合版本(两全其美)

创建具有所需访问器字段的接口(interface)。

public interface CompanyDTOIdNameInterface {

public Long getId();
public String getName();
}

在@Entity 对象上实现接口(interface)。

public class Company implements Serializable,
CompanyDTOIdNameInterface
{ /* omitted code */ }

存储库代码:

@Query( "SELECT new com.your.package.name.customers.Company(c.id, c.name) " +
"FROM Company c " +
"WHERE c.enabled = 1 " +
"ORDER BY c.name ASC"
)
List<CompanyDTOIdNameInterface> compNameWhereEnabledTrue();

就这么简单。祝你好运:)

关于java - 如何使用 hibernate 查询仅获取具有关联的实体的某些字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49284556/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com