[英]Need to return List of Custom Object using JPA @Query
I've a custom object我有一个自定义对象
@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;
}
}
I need to return List of this object using a JpaRepository<Sale, Integer>
The SaleRepository
is as follow:我需要返回使用这个对象的名单
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);
}
Here is my Controller method:这是我的控制器方法:
@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);
}
While I run the code it shows this error:当我运行代码时,它显示了这个错误:
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]
My DATABASE NAME is alright.我的数据库名称没问题。 It works perfectly while I request in other methods.
当我用其他方法请求时,它工作得很好。 Please suggest me an ideal solution.
请建议我一个理想的解决方案。
1) You need to create a constructor for the SaleReport
class that accepts all the parameters that you use in the select
statement and in the exact order. 1)您需要为
SaleReport
类创建一个构造函数,该构造函数接受您在select
语句中使用的所有参数并按确切顺序。
2) Alter your query so that you wrap the selected columns with a new
statement: 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) In my opinion you don't need a native query here and you can use HQL directly (changed joins). 3)在我看来,您在这里不需要本机查询,您可以直接使用 HQL(更改连接)。
Spring has an annotation called @SqlResultSetMapping
This annotation can be used for above problem. Spring 有一个名为
@SqlResultSetMapping
的注解,这个注解可以用于上述问题。 Details about this annotation can be found from following link:可以从以下链接找到有关此注释的详细信息:
Annotation Type ConstructorResult 注释类型 ConstructorResult
This is actually mapping a hibernate query result into a plain POJO
Class.这实际上是将一个休眠查询结果映射到一个普通的
POJO
类中。 Thats what actually needed.这才是真正需要的。
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)
}
)
}
)
Put @SqlResultSetMapping
into top of any @Entity
and make sure the datatype
returning from database is same as your POJO
Class datatype
.将
@SqlResultSetMapping
放入任何@Entity
顶部,并确保从数据库返回的datatype
与您的POJO
Class datatype
相同。
Hope this will help you.希望这会帮助你。 Enjoy :)
享受 :)
I hope this answer might help you !!希望这个回答可以帮到你!!
Sale is your entity class and SaleReport is pojo class. Sale是您的实体类,而SaleReport 是 pojo类。
public List<SaleReport> getSaleReportByDate(@Param("from_date")String fromDate, @Param("to_date")String toDate);
you can not return a pojo class list from database.It return entity class list.您不能从数据库返回 pojo 类列表。它返回实体类列表。 Use public List not public List
使用公共列表而不是公共列表
public List<Sale> getSaleReportByDate(@Param("from_date")String fromDate, @Param("to_date")String toDate);
@Repository
public interface SaleRepository extends JpaRepository<**Sale**, Integer>
you have to map Entity Class list to POJO class list.您必须将实体类列表映射到 POJO 类列表。
Mapping of Entity class list to a pojo class list: As there are lot of ways to achieve this still Easiest solution is loop over entity class and set entity attribute to pojo attribute:将实体类列表映射到 pojo 类列表:因为有很多方法可以实现这一点,最简单的解决方案是循环实体类并将实体属性设置为 pojo 属性:
I don't suggest to use constructor because some times you may want to set only several fields not all fields of POJO class.我不建议使用构造函数,因为有时您可能只想设置几个字段,而不是 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;
Here sr is your POJO list.这里 sr 是你的 POJO 列表。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.