【问题标题】:Create Dynamic JPA Query创建动态 JPA 查询
【发布时间】:2020-03-15 13:16:41
【问题描述】:

我有一个包含许多字段作为查询过滤器的视图,并且我正在使用 JPA 派生查询,但是为每个字段/过滤器组合创建所有查询将是乏味且冗长的。

我发现我可以为它创建一个动态查询,但不确定如何。

到目前为止,我已经在我的存储库中创建了这些查询,但还需要更多:

 public interface EmployeeReportInfoViewRepository extends PagingAndSortingRepository<EmployeeReportInfo, Long> {

 List<EmployeeReportInfo> findByControlNumber(String controlNmber);

 List<EmployeeReportInfo> findByManager(String manager);

 List<EmployeeReportInfo> findByofficeLocation(String officeLocation);

 List<EmployeeReportInfo> findByBenchFlag(char benchFlag);

 List<EmployeeReportInfo> findByBillableFlag(char billableFlag);

 List<EmployeeReportInfo> findByEnableFlag(boolean enableFlag);

 List<EmployeeReportInfo> findByLastNameAndFirstNameAndControlNumber(String lastName, String firstName,String controlNumber);

 List<EmployeeReportInfo> findByLastNameAndFirstNameAndControlNumberAndManager(String lastName, String firstName,String controlNmber,String manager);

 List<EmployeeReportInfo> findByLastNameAndFirstNameAndControlNumberAndManagerAndOfficeLocation(String lastName, String firstName,String controlNmber,String manager,String officeLocation);

 List<EmployeeReportInfo> findByLastNameAndFirstNameAndControlNumberAndManagerAndOfficeLocationAndBenchFlag(String lastName, String firstName,String controlNmber,String manager,String officeLocation, char benchFlag);

 List<EmployeeReportInfo> findByLastNameAndFirstNameAndControlNumberAndManagerAndOfficeLocationAndBenchFlagAndBillableFlag(String lastName, String firstName,String controlNmber,String manager,String officeLocation, char benchFlag,char bllableFlag);

 List<EmployeeReportInfo> findByLastNameAndFirstNameAndControlNumberAndManagerAndOfficeLocationAndBenchFlagAndBillableFlagAndEnableFlagAndStartGreaterThanEqualAndEndLessThanEqual
 (String lastName, String firstName,String controlNmber,String manager,String officeLocation, char benchFlag,char bllableFlag, 
         boolean emableFlag, Date start,Date end); 


}

@Entity
@Table(name = "employee_report_view")
public class EmployeeReportInfo {

    @Id
    @Column(name = "employee_id")
    private Long id;

    private String name;

    private Date start;

    private Date end;

    @Column(name = "control_number")
    private String controlNumber;

    @Column(name = "enable_flag")
    private boolean enableFlag;

    @Column(name = "billable_flag")
    private char billableFlag;

    @Column(name = "bench_flag")
    private char benchFlag;

    @Column(name = "office_location")
    private String officeLocation;

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

    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @param id the id to set
     */
    public void setId(Long id) {
        this.id = id;
    }


    /**
     * @return the start
     */
    public Date getStart() {
        return start;
    }

    /**
     * @param start the start to set
     */
    public void setStart(Date start) {
        this.start = start;
    }

    /**
     * @return the end
     */
    public Date getEnd() {
        return end;
    }

    /**
     * @param end the end to set
     */
    public void setEnd(Date end) {
        this.end = end;
    }

    /**
     * @return the controlNumber
     */
    public String getControlNumber() {
        return controlNumber;
    }

    /**
     * @param controlNumber the controlNumber to set
     */
    public void setControlNumber(String controlNumber) {
        this.controlNumber = controlNumber;
    }

    /**
     * @return the enableFlag
     */
    public boolean isEnableFlag() {
        return enableFlag;
    }

    /**
     * @param enableFlag the enableFlag to set
     */
    public void setEnableFlag(boolean enableFlag) {
        this.enableFlag = enableFlag;
    }

    /**
     * @return the billableFlag
     */
    public char getBillableFlag() {
        return billableFlag;
    }

    /**
     * @param billableFlag the billableFlag to set
     */
    public void setBillableFlag(char billableFlag) {
        this.billableFlag = billableFlag;
    }

    /**
     * @return the benchFlag
     */
    public char getBenchFlag() {
        return benchFlag;
    }

    /**
     * @param benchFlag the benchFlag to set
     */
    public void setBenchFlag(char benchFlag) {
        this.benchFlag = benchFlag;
    }

    /**
     * @return the officeLocation
     */
    public String getOfficeLocation() {
        return officeLocation;
    }

    /**
     * @param officeLocation the officeLocation to set
     */
    public void setOfficeLocation(String officeLocation) {
        this.officeLocation = officeLocation;
    }

    /**
     * @return the manager
     */
    public String getManager() {
        return manager;
    }

    /**
     * @param manager the manager to set
     */
    public void setManager(String manager) {
        this.manager = manager;
    }

}

【问题讨论】:

  • 那么问题是什么?您是否需要知道如何在 Spring 中运行自定义 sql 查询而不是 JPA?
  • 我需要能够运行动态查询,例如,我可以从我的表单中按名称搜索和过滤,或按名称和经理搜索,或按经理和办公室和控制号码搜索,或按开始日期搜索和经理....等等
  • 尝试使用以下方法:1, 2

标签: java spring dynamic spring-data-jpa


【解决方案1】:

我能理解你的需求:你想根据表单下发的url动态生成查询条件。假设url映射到后端一个HashMap&lt;String,String&gt;

例如,网址:

127.0.0.1/employees?nameContains=jack&ageEquals=10

地图:

HashMap<String, String>:key:nameContains,value:jack,key:ageEuqals,value:10

Spring 框架可以自动进行这种映射(RequestParamMapMethodArgumentResolver)。你需要做的是通过这个map动态生成Specification(Specification)。

  1. 使用反射获取字段对应的属性类型:name=>String, age=>Integer
  2. 使用CriteriaBuilder构建查询条件,API全面,如:

谓词like(Expression x, String pattern); => 包含

谓词等于(表达式 x,表达式 y); => 相等

  1. 组合您的查询条件(或、和)
  2. 您将获得一份规范。

这是一个比较复杂的解决思路,需要前表组件和后端协调,但是会很方便。

我说的比较简单笼统,细节很多(比如嵌套属性,一对一,一对多等)

另外,你可以看看http://www.querydsl.com/

【讨论】:

    猜你喜欢
    • 2018-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-25
    • 2017-04-20
    • 1970-01-01
    • 2017-04-06
    • 2012-12-12
    相关资源
    最近更新 更多