gpt4 book ai didi

java - 从表和连接表中选择部分列 Criteria API

转载 作者:行者123 更新时间:2023-12-01 16:18:12 25 4
gpt4 key购买 nike

我试图从不同的表中选择 2 列(它们已连接),但我无法使用 Criteria API 使其工作。问题是,我创建了一个 DTO 类作为 Projection,但无法将连接的表实体转换为内部类。为了澄清一下,这是我的类(class):

用户:

    @Entity
@Table(name = "users", indexes = {@Index(columnList = "email", unique = true)})
public class User extends BaseEntity {

@Column(nullable = false)
private String firstName;

@ManyToMany
@JoinTable(name = "user_roles",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<Role> roles;

角色:

@Table(name = "roles")
@Entity
public class Role extends BaseEntity {

@Column(nullable = false)
private String name;

@Column(nullable = false)
private String description;

DTO 类:

public class UserRoleDto {
private String email;
private Set<RoleDto> roles;

public UserRoleDto(String email, Set<RoleDto> roles) {
this.email = email;
this.roles = roles;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public Set<RoleDto> getRoles() {
return roles;
}

public void setRoles(Set<RoleDto> roles) {
this.roles = roles;
}

public static class RoleDto {
private String name;

public RoleDto(String name) {
this.name = name;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}
}

最后,我尝试过:

    @Override
public Optional<UserRoleDto> findByIdWithRoles(UUID id) {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<UserRoleDto> query = builder.createQuery(UserRoleDto.class);

Root<User> root = query.from(User.class);
root.fetch("roles", JoinType.LEFT);

query.where(builder.equal(root.get("id"), id));
query.select(builder.construct(UserRoleDto.class, root.get("email"), root.join("roles")));

UserRoleDto user = entityManager.createQuery(query).getSingleResult();

return Optional.ofNullable(user);
}

如您所见,我只想查询 user.firstName 和 Role 加入表中的名称。如何在此处从 Role 转换为 UserRoleDto.RoleDto?

谢谢!

最佳答案

这行不通。您只能使用 JPA 构造函数语法从标量结果创建对象,但不能用于嵌套结构。您必须自己构建对象图。

无论如何,这是 Blaze-Persistence Entity Views 的完美用例.

Blaze-Persitence 是基于 JPA 的查询生成器,它支持基于 JPA 模型的许多高级 DBMS 功能。我在其之上创建了实体 View ,以允许在 JPA 模型和自定义接口(interface)定义的模型之间轻松映射,就像类固醇上的 Spring Data Projections 一样。这个想法是,您按照自己喜欢的方式定义目标结构,并通过 JPQL 表达式将属性(getter)映射到实体模型。由于属性名称用作默认映射,因此您通常不需要显式映射,因为 80% 的用例都具有作为实体模型子集的 DTO。

模型的映射可能如下所示简单

@EntityView(User.class)
interface UserRoleDto {
String getEmail();
Set<RoleDto> getRoles();
}

@EntityView(Role.class)
interface RoleDto {
String getName();
}

查询是将实体 View 应用于查询,最简单的是通过 id 进行查询。

UserRoleDto dto =entityViewManager.find(entityManager, UserRoleDto.class, id);

但是 Spring Data 集成允许您像 Spring Data Projections 一样使用它:https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features

它只会获取您告诉它获取的映射

关于java - 从表和连接表中选择部分列 Criteria API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62348693/

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