使用 Spring 和 @QuerydslPredicate

问题描述

如何编写 HTTP 请求 URL 以获得类似于以下内容查询

select *
from incidents i,jira_issues ji
where i.incident_id = ji.incident_id
  and ji.external_jira_issue_id = 'ABC-123'
  and ji.jira_server_id = '1'

我有以下课程:

@Entity(name = "incidents")
public class IncidentEntity {
  @OnetoMany(
      mappedBy = "incident",cascade = CascadeType.ALL
  )
  @LazyCollection(LazyCollectionoption.FALSE)
  private List<JiraIssueEntity> jiraIssues;
...
}
@Entity(name = "jira_issues")
public class JiraIssueEntity {

  @EmbeddedId
  @EqualsAndHashCode.Include
  private JiraIssueId id;

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "incident_id")
  @ToString.Exclude
  private IncidentEntity incident;
...
}
@Embeddable
public class JiraIssueId implements Serializable {

  @EqualsAndHashCode.Include
  private String externalJiraIssueId;
  @EqualsAndHashCode.Include
  private String jiraServerId;
}

这是我的 API 方法签名:

  @GetMapping("")
  public Page<Incident> listIncidents(
      @QuerydslPredicate(root = IncidentEntity.class) Predicate predicate
  );

我知道我可以发送以下内容

/incidents/?jiraIssues.id.externalJiraIssueId=ABC-123&jiraIssues.id.jiraServerId=1"

这转化为以下查询

select *
from incidents incidenten0_
where (exists(select 1
              from jira_issues jiraissues1_
              where incidenten0_.incident_id = jiraissues1_.incident_id
                and (lower(jiraissues1_.external_jira_issue_id) like ? escape '!')))
  and (exists(select 1
              from jira_issues jiraissues2_
              where incidenten0_.incident_id = jiraissues2_.incident_id
                and (lower(jiraissues2_.jira_server_id) like ? escape '!')))

这不太好。

我不知道如何:

  1. 做等于而不包含(externalJiraIssueId=ABC-1234 的行也会返回,但我不希望那样)。
  2. 检查同一个 JiraIssue 是否有 externalJiraIssueId=ABC-123 和 jiraIssues.id.jiraServerId=1,而不是每个匹配一个的不同 JiraIssues(类似于 jiraIssues.id=(ABC-123,1)

谢谢。

解决方法

关于第一个问题,您可以使您的“存储库”接口扩展 QuerydslPredicateExecutor 和 QuerydslBinderCustomizer 然后您可以使用以下内容覆盖“自定义”方法:

    @Override
      default void customize(QuerydslBindings bindings,@NotNull QIncidentEntity root) 
      {
         bindings.bind(String.class)
            .first((SingleValueBinding<StringPath,String>) 
                StringExpression::equalsIgnoreCase);
      }

这将使查询检查等于(忽略大小写)而不是包含。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...