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

从表和联接表条件API中选择部分列

黄英韶
2023-03-14

我正在尝试从不同的表中选择2列(它们是连接的),但是我无法使用标准API使其工作。问题是,我已经创建了一个DTO类作为投影,但是我不能将连接的表实体转换为内部类。为了澄清问题,下面是我的课程:

用户:

    @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);
    }

共有1个答案

马沛
2023-03-14

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

无论如何,这是Blaze-Persistence实体视图的完美用例。

Blaze-Persitence是JPA之上的查询构建器,它支持JPA模型之上的许多高级DBMS特性。我在上面创建了实体视图,以便在JPA模型和自定义接口定义的模型之间进行简单的映射,就像Steroids上的Spring数据投影一样。其思想是以您喜欢的方式定义目标结构,并通过JPQL表达式将属性(getter)映射到实体模型。由于属性名被用作默认映射,您基本上不需要显式映射,因为80%的用例都需要DTO作为实体模型的子集。

模型的映射看起来像下面这样简单

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

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

查询是将实体视图应用于查询的问题,最简单的就是按ID查询。

UserRoledTo dto=EntityViewManager.Find(entityManager,UserRoledTo.Class,id);

但是Spring数据集成允许您几乎像使用Spring数据投影一样使用它:https://persistence.blazebit.com/documentation/entity-view/manual/en_us/index.html#spring-data-features

它将只获取您告诉它要获取的映射

 类似资料:
  • 我是criteria api的新手,正在尝试构建一个id匹配id的select查询。 我想建立这样一个:

  • 我需要发票,invoice_details表的所有列,但我想从我的付款表中只得到一列(列名:)。我对它有什么疑问?这是我的控制器。

  • 我想从两个select查询的内部联接中选择两列。我编写了一个连接三个表的查询,从结果中我只希望得到两列。但是我的查询显示错误。我使用的是oracle sql Developer。 我只想要名字和姓氏,但我得到了这样的错误:

  • 我想问一下,是否有人只能从表A中选择值。请参阅下面的hibernate代码 现在,它就像从A、B和C中选择值,而且太多了。 谢谢你吉米

  • 我有三张桌子 表A 我需要根据传递的参数将TableA连接到TableB或TableC。ie 我尝试了以下查询 但是,这是给语法错误。有人能帮忙吗? 解决方案:

  • 我有两张桌子,客户和订单是内部连接的。客户可以有多个与其关联的订单。在我的选择中,我然后按客户分组。id.我需要选择每个客户的最新订单,还需要选择在该订单中花费的金额。目前,我可以选择最近的订单日期,但不知道如何选择与订单日期同一行中的金额。 这是我当前的查询: 查询选择最近日期,但不选择与最近订单日期关联的金额。 表格声明: