简体   繁体   中英

Create Dynamic JPA Query

I have a view with many fields as query filters, and I am using JPA derived queries, however creating all queries for every combination of fields/filters would be tedious and long.

I found out that I can create a dynamic query for it, but not sure how.

So far I have created these queries in my repository, but still need a lot more:

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

}

员工报告

Do you want to write Native Sql queries instead? You can do through entityManager

I can understand your needs:you want to dynamically generate query conditions based on the url issued by the form.Let's assume that the url maps to the back end to a HashMap<String,String> .

For instance,url:

127.0.0.1/employees?nameContains=jack&ageEquals=10

Map:

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

The Spring framework can do this mapping automatically( RequestParamMapMethodArgumentResolver ). What you need to do is to dynamically generate the Specification( Specification ) by this map.

  1. Gets the type of property corresponding to the field using reflect: name=>String, age=>Integer
  2. Using CriteriaBuilder to build query criteria,it has comprehensive api,such as:

Predicate like(Expression x, String pattern); => contains

Predicate equal(Expression x, Expression y); => equal

  1. Assemble your query criteria(or,and)
  2. You get a Specification.

This is a relatively complex solution idea, which requires the coordination between the front table component and the back end, but it will be very convenient.

What I said is relatively simple and general, there are a lot of details.(such as nested properties,one-to-one,one-to-many,etc)

Also,You can have a look http://www.querydsl.com/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM