2016-04-18 13 views
1

Ich habe unten Tabellendaten:Dynamische Abfrage JPA 2 Spezifikation Mit CriteriaBuilder

Product Reason Qty 
Pepsi IN  10 
Pepsi Out 2 
Pepsi In  15 
Pepsi Out 5 
Coke IN  100 
Coke Out 20 
Coke In  35 
Coke Out 25 
Fanta Out  55 

und ich möchte wie unten bekommen führen:

Product Qty 
Pepsi 18 
Coke 90 
Fanta -55 

für, dass ich unter Abfrage erhalten haben:

SELECT Product, 
     SUM(CASE WHEN reason IN ('IN','REFUND') THEN Qty 
       WHEN reason IN ('OUT','WASTE') THEN -Qty 
       ELSE NULL END) AS Qty 
FROM stock 
GROUP BY Product; 

Ich möchte verwenden JPA Specification wie in diesem link verwendet, bin ich neu zu JPA Specification kann jemand bitte mich führen?

Ich habe diese link und diese link, aber ich bin mir nicht sicher, was ist die richtige Frage, um das Problem zu lösen?

EDIT:

Ich habe unten Code versucht

@Override 
    public Predicate toPredicate(Root<Stockdiary> root, CriteriaQuery<?> query, CriteriaBuilder builder) { 

    Path reasonexpression = root.get("reason"); 
        Path qtyexpression = root.get("qty"); 

        List<String> inList = new ArrayList<String>(); 
        inList.add("IN"); 

        List<String> outList = new ArrayList<String>(); 
        outList.add("OUT"); 

        Predicate inpredicate = reasonexpression.in(inList); 
        Predicate outpredicate = reasonexpression.in(outList); 

        Expression<Number> sum = builder.sum(
          builder.<Number>selectCase() 
           .when(inpredicate,qtyexpression.as(Double.class)) 
           .when(outpredicate,builder.neg(qtyexpression).as(Double.class)) 
           .otherwise(0)); 

return builder.equal(sum.as(Integer.class), 1) 
} 

Anruf aus als seitenwechselbar

Page<Stockdiary> page = stockRepository.findAll(spec,pageable); 

, die unter Abfrage macht: -

select count(stock0_.stock_id) as col_0_0_ from stock stock0_ cross join session_tbl session_tb1_ 
where stock0_.session_id=session_tb1_.session_id and 
cast(sum(case when stock0_.reason in (?) then stock0_.qty when stock0_.reason in (?) then -stock0_.qty else 101 end) as signed)=1 
group by stock0_.reason , stock0_.products_id , session_tb1_.terminal_id 

Ich bekomme SQL-Ausnahme wegen case Anweisung ist nach where Klausel. Ich weiß nicht, warum Frühling case nach der where Klausel setzen.

Ich versuche dynamische Abfrage zu machen, da ich statische Abfrage nicht verwenden kann.

Antwort

0

Im Wesentlichen möchten Sie eine Native Query durchführen.

Insbesondere können Sie die JPA Funktion SqlResultSetMapping verwenden, um die Zuordnung zwischen Ihrer systemeigenen Abfrage und dem DTO-Objekt zu definieren, das Ihre Daten enthalten kann.

die DTO für Ihre Bedürfnisse sieht wie folgt aus der Annahme:

class ProductQuantity { 
    private String product; 
    private Integer quantity; 

    public ProductQuantity(String product, Integer quantity) { 
     this.product = product; 
     this.quantity = quantity; 
    } 

    public getProduct() { return this.product; } 

    public getQuantity() { return this.quantity; } 
} 

Die folgende Definition als eine Abbildung für die native Abfrage handeln kann:

@SqlResultSetMapping(
    name = "ProductQuantityMapping", 
    classes = @ConstructorResult(
     targetClass = ProductQuantity.class, 
     columns = { 
      @ColumnResult(name = "product", type = String.class), 
      @ColumnResult(name = "qty", type = Integer.class) 
     }) 
) 

Und schließlich kann die Abfrage wie aufgerufen werden:

Für weitere Informationen/Beispiele werfen Sie einen Blick auf diese article.

+0

Ich kann EntityManager nicht verwenden, da ich die Spring Specification und Criteriabuilder nur verwenden muss –

+0

Ich habe meine Frage bearbeitet. –

Verwandte Themen