代码之家  ›  专栏  ›  技术社区  ›  Mehedi Hasan Chonchol

需要使用JPA@Query返回自定义对象的列表

  •  -1
  • Mehedi Hasan Chonchol  · 技术社区  · 7 年前

    我有一个自定义对象

    @Component
    public class SaleReport {
    
        private Date date;
        private String customerName;
        private String phoneNo;
        private String productName;
        private Integer quantity;
        private Double totalAmount;
    
        public Date getDate() {
            return date;
        }
    
        public void setDate(Date date) {
            this.date = date;
        }
    
        public String getCustomerName() {
            return customerName;
        }
    
        public void setCustomerName(String customerName) {
            this.customerName = customerName;
        }
    
        public String getPhoneNo() {
            return phoneNo;
        }
    
        public void setPhoneNo(String phoneNo) {
            this.phoneNo = phoneNo;
        }
    
        public String getProductName() {
            return productName;
        }
    
        public void setProductName(String productName) {
            this.productName = productName;
        }
    
        public Integer getQuantity() {
            return quantity;
        }
    
        public void setQuantity(Integer quantity) {
            this.quantity = quantity;
        }
    
        public Double getTotalAmount() {
            return totalAmount;
        }
    
        public void setTotalAmount(Double totalAmount) {
            this.totalAmount = totalAmount;
        }
    }
    

    我需要使用 JpaRepository<Sale, Integer> SaleRepository 具体如下:

    @Repository
    public interface SaleRepository extends JpaRepository<Sale, Integer> {
    
    
        @Query(value = "SELECT B.order_date AS date, E.customer_name AS customerName, " +
                "E.phone_no AS phoneNo, D.product_name AS productName, C.quantity AS quantity, " +
                "C.total_price AS totalAmount " +
                "FROM SALE A " +
                "INNER JOIN A.quotation_id B " +
                "INNER JOIN B.quotation_id C " +
                "INNER JOIN C.product_id D " +
                "INNER JOIN B.customer_id E " +
                "WHERE (B.order_date BETWEEN :from_date AND :to_date)", nativeQuery = true)
        public List<SaleReport> getSaleReportByDate(@Param("from_date")String fromDate, @Param("to_date")String toDate);
    
    }
    

    @GetMapping("api/report/sale/{from_date}/{to_date}")
            public List<SaleReport> getSaleReportByDate(@PathVariable("from_date") String fromDate, @PathVariable("to_date") String toDate){
            return saleRepository.getSaleReportByDate(fromDate, toDate);
    }
    

    当我运行代码时,它显示以下错误:

    com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown database 'a'
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_161]
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_161]
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_161]
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_161]
        at com.mysql.jdbc.Util.handleNewInstance(Util.java:425) ~[mysql-connector-java-5.1.47.jar:5.1.47]
        at com.mysql.jdbc.Util.getInstance(Util.java:408) ~[mysql-connector-java-5.1.47.jar:5.1.47]
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:944) ~[mysql-connector-java-5.1.47.jar:5.1.47]
    

    我的数据库名是正确的。当我用其他方法请求时,它工作得很好。

    3 回复  |  直到 7 年前
        1
  •  0
  •   Maciej Kowalski    7 年前

    1) 您需要为 SaleReport select 陈述和顺序。

    2) 更改查询,以便用 new

    @Query(value = "SELECT new org.mypackage.SaleReport(B.order_date AS date,"
                            + "E.customer_name AS customerName, "
                            + "E.phone_no AS phoneNo, D.product_name AS productName, 
                            + "C.quantity AS quantity, " +
                            + "C.total_price AS totalAmount) " +
                "FROM SALE A " +
                "INNER JOIN A.quotation B " +
                "INNER JOIN B.quotation C " +
                "INNER JOIN C.product D " +
                "INNER JOIN B.customer E " +
                "WHERE (B.order_date BETWEEN :from_date AND :to_date)") 
    

    3)

        2
  •  0
  •   Mehedi Hasan Chonchol    7 年前

    Spring有一个名为 @SqlResultSetMapping 此注释可用于上述问题。有关此批注的详细信息,请参见以下链接:

    Annotation Type ConstructorResult

    POJO 班级。这才是真正需要的。

    Example:
    
       Query q = em.createNativeQuery(
          "SELECT c.id, c.name, COUNT(o) as orderCount, AVG(o.price) AS avgOrder " +
          "FROM Customer c, Orders o " +
          "WHERE o.cid = c.id " +
          "GROUP BY c.id, c.name",
          "CustomerDetailsResult");
    
       @SqlResultSetMapping(
           name="CustomerDetailsResult",
           classes={
              @ConstructorResult(
                   targetClass=com.acme.CustomerDetails.class,
                     columns={
                        @ColumnResult(name="id"),
                        @ColumnResult(name="name"),
                        @ColumnResult(name="orderCount"),
                        @ColumnResult(name="avgOrder", type=Double.class)
                        }
              )
           }
          )
    

    @SqlResultSetMapping结果映射 在任何 @Entity 确保 datatype 从数据库返回与 波乔 等级 .

    希望这对你有帮助。享受:)

        3
  •  0
  •   Vikash Kumar    7 年前

    我希望这个答案能对你有所帮助!!

    是你的实体类和 报告是pojo 班级。

    public List<SaleReport> getSaleReportByDate(@Param("from_date")String fromDate, @Param("to_date")String toDate);
    

    使用公共列表而不是公共列表

    public List<Sale> getSaleReportByDate(@Param("from_date")String fromDate, @Param("to_date")String toDate);
    
    @Repository
    public interface SaleRepository extends JpaRepository<**Sale**, Integer>
    

    必须将实体类列表映射到POJO类列表。

    因为实现这一点还有很多方法 最简单的解决方案是循环实体类并将实体属性设置为pojo属性:

    我不建议使用构造函数,因为有时您可能只想设置几个字段,而不是POJO类的所有字段。

    Arraylist<SaleReport> sr = new Arraylist<SaleReport>();
    ArrayList<Sale> saleEntityList= saleRepository.getSaleReportByDate(fromDate,toDate);
    for(Sale  s : saleEntityList){
        saleReport = new SaleReport();
        saleReport.setDate(s.getDate);
        //same for all attributes
        sr.add(saleReport);
    } 
    return sr;