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

如何在JPA中使用规范连接多列?

翁翰墨
2023-03-14

我正在尝试将查询转换为JPA规范,该查询包含带OR条件的连接操作。

以下是查询:

select u from User u inner join Operation o on (u.id = o.verificateur1 or u.id = o.verificateur2) where o.id not in (:ids)

我试图编写一个规范,但在如何将多个列与OR条件连接方面遇到了障碍。

public class UserSpecification {

    public static Specification<User> UsersNotInSelectedOperations(final List<Long> operationId ){

        return new Specification<User>() {
            @Override
            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Join<User, Operation> userJoinOp = root.join("fk_user1_id");
                final Path<User> users = userJoinOp.get("id");
                return criteriaBuilder.not(users.in(operationId));
            }
        };
    }

}

用户实体:

@Entity
@Table(name = "aigle_user")
public class User extends AbstractEntity implements UserDetails {

    private static final long serialVersionUID = 2840226091237599675L;

    @Column(name = "mail", nullable = true)
    private String mail;

    @Column(name = "password")
    private String password;

    @Column(name = "is_activated")
    private boolean isActivated;

    @Column(name = "is_admin")
    private boolean isAdmin;

    @ManyToMany(cascade = { CascadeType.PERSIST })
    @LazyCollection(LazyCollectionOption.FALSE)
    @JoinTable(name = "aigle_group_user", joinColumns = @JoinColumn(name = "fk_user_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "fk_group_id", referencedColumnName = "id"))
    private Set<Group> groups;

    @ManyToMany(cascade = { CascadeType.PERSIST })
    @LazyCollection(LazyCollectionOption.FALSE)
    @JoinTable(name = "aigle_role_user", joinColumns = @JoinColumn(name = "fk_user_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "fk_role_id", referencedColumnName = "id"))
    private Set<Role> roles;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "destinataire", orphanRemoval = true)
    private Set<Tache> taches;

    @Column(name = "last_name", unique = false)
    private String lastName;

    @Column(name = "first_name", unique = false)
    private String firstName;

    @Column(name = "telephone")
    private String telephone;

    private String salesforceId;

-----
}

运营实体

public class Operation extends OperationField {

...
    @ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
    @JoinColumn(name = "fk_user1_id")
    private User verificateur1;

    @ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
    @JoinColumn(name = "fk_user2_id")
    private User verificateur2;
.....
}

我希望有一个规范来取代上面的查询

共有1个答案

钮刚洁
2023-03-14

您可以尝试使用子查询而不是连接表达式

    public static Specification<User> UsersNotInSelectedOperations(final List<Long> operationIds) {
            return (root, query, builder) -> {
                    Subquery<Operation> subquery = query.subquery(Operation.class);
                    Root<Operation> operation = subquery.from(Operation.class);

                    Predicate predicate1_1 = builder.equal(operation.get("verificateur1").get("id"), root.get("id"));
                    Predicate predicate1_2 = builder.equal(operation.get("verificateur2").get("id"), root.get("id"));
    
                    Predicate predicate1 = builder.or(predicate1_1, predicate1_2); 
                    Predicate predicate2 = operation.get("id").in(operationIds).not();
    
                    subquery.select(operation).where(predicate1, predicate2);
    
                    return builder.exists(subquery);
            };
   }

使用此规范可以得到如下HQL查询

from User u
where exists( // subquery ->
  from Operation o
  where (o.verificateur1.id = u.id or o.verificateur2.id = u.id) // predicate 1
  and o.id not in (:ids) // predicate 2
  // <- subquery
)

“从用户u中选择u”是“从用户u中选择u”的较短替代

我没有运行这个代码,所以需要修改

 类似资料:
  • 我想使用Spring JPA规范连接函数 这是我的表格代码: > } 我如何在规范中加入表中的学生和家长?

  • 我想创建基于JPA规范的过滤器。我正在使用Spring数据。 我的实体: 实体依赖项为:第1节-一对多- 我有一个转换为规范的问题过滤器类。我想了解第节中的所有问题。 通常,我会使用下面编写的SQL查询来获取部分中的所有问题。 我尝试过使用Join创建规范,但不知道如何在问题上的目标参考不可用时创建连接。

  • 下面是fetch join的代码 上面的代码正在生成下面的查询

  • 我有以下@query,这是非常好的工作。但是现在我有一个场景,其中there screen需要一个过滤器,这将向查询添加一些where子句。

  • 我正在尝试获取员工的详细信息,其雇员类型是职员,其加入日期是最近的一个。 SQL Server 2008中的查询如下所示: 提前致谢

  • 如何用JPA规范替换下面的Hibernate查询 从这里的主要问题是我想要一个独特的记录成员(这是一个左加入)对象,而不是成员资格。下面是我尝试的: 在这里,应用 distinct as true 后,给我成员资格不同对象不是成员不同对象 所以在这里我如何才能获得成员不同的对象,这又是一个左连接。下面是实体结构: 我对JPA规范很陌生,任何帮助都非常感谢。提前致谢!!!