2016-11-28 97 views
0

我想根據用戶可以通過HTML表單指定的各種條件執行SELECT查詢。查詢中的每個條件都映射到HTML表單中的適當字段。如果沒有爲字段指定值,則可以在查詢中跳過相應的條件。如何根據用戶從HTML表單中動態生成選擇查詢

的完全形成的查詢如下所示:

select 
    d 
from 
    TotalInventoryTransaction d 
where 
    d.transactionDate between ?1 and ?2 
and d.material=?3 
and d.shipmentOrder between ?4 and ?5 
and d.source = ?6 
and d.destination= ?7 

春季數據JPA存儲庫的方法如下:

@Query(FILTER_DATA_QUERY) 
List<TotalInventoryTransaction> getFilteredData(Date dateFrom 
               , Date dateTo 
               , Long material 
               , Long stoFrom 
               , Long stoTo 
               , String source 
               , String destination); 

我想通過FILTER_DATA_QUERY該方法以這樣的方式即如果未指定方法參數,則在執行的查詢中跳過其對應的子句。

請建議如何實現這一點。

+0

你是說如果'material'參數的值是'null',查詢子句'和d.material =?3'應該跳過(因爲沒有指定材質),所以上? – manish

+0

是............ – Priya

回答

1

您只需確保在提供參數值時,將該值視爲查詢,並且未指定該值時,將考慮相應的列值。

下面的硬編碼的JPA查詢將工作:

select 
    d 
from 
    TotalInventoryTransaction d 
where 
    d.transactionDate >= coalesce(?1, d.transactionDate) 
and d.transactionDate <= coalesce(?2, d.transactionDate) 
and d.material = coalesce(?3, material) 
and d.shipmentOrder >= coalesce(?4, d.shipmentOrder) 
and d.shipmentOrder <= coalesce(?5, d.shipmentOrder) 
and d.source = coalesce(?6, d.source) 
and d.destination = coalesce(?7, d.destination) 

COALESCE是已被採用到JPA的查詢語言以及標準ANSI-SQL函數。像d.material = coalesce(?3, material)這樣的條款可以簡單地理解爲if a (non-null) value is specified, match the specified value against the values in the material column; otherwise, match the column with its own value。這樣,每當沒有指定特定值時,相應列中的值將與其自身進行比較,並根據需要始終爲該特定列生成匹配。

我已經用單個操作員替換了between操作員,假設用戶可能最終只傳遞一個日期對。

1

如果您使用Spring-data-Jpa,我想建議您使用標準API。查看文檔here.您可以使用謂詞來創建動態where子句。我創建了一個示例來向您展示使用情況。

表: -

@Entity 
public class Test { 
    @Id private Long id;  
    String attributeOne; 
    String attributeTwo; 
    ... 
} 

的實際查詢

//Params from the method 
String param1 = "1"; 
String paramNull = null; 

CriteriaBuilder qb = em.getCriteriaBuilder(); 
CriteriaQuery cq = qb.createQuery(); 
Root<Test> variableName = cq.from(Test.class); 

//Creating Predicates 
List<Predicate> predicates = new ArrayList<Predicate>(); 

//Adding predicates when params are not null 
if (param1 != null) { 
    predicates.add(
      qb.equal(variableName.get("attributeOne"), param1)); 
} 
if (paramNull != null) { 
    predicates.add(
      qb.equal(variableName.get("attributeTwo"), paramNull)); 
} 
//Actual query 
cq.select(variableName) 
     .where(predicates.toArray(new Predicate[]{})); 
//executing the query 
em.createQuery(cq).getResultList(); 

希望這有助於。

0
I am now building a query statement by using string buffer according to condition it is working.. if value is not null then I am appending it into the query else I am not appending.. 
one section is like this.. 

StringBuffer queryBuff = new StringBuffer(); 
     queryBuff 
       .append("select * from table_name where"); 
try { 
      if ((dateFromStr != null && dateFromStr != "") 
        && (dateToStr != null && dateToStr != "")) { 
       dateFrom = df.parse(dateFromStr); 
       dateTo = df.parse(dateToStr); 
       queryBuff.append(" transaction_date between " + "\'" + dateFrom 
         + "\'" + "and" + "\'" + dateTo + "\'"); 
      } else { 
       queryBuff.append(""); 
      } 
     } catch (ParseException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
if (materialName != null && materialName != "") { 

      if ((dateFromStr == null || dateFromStr == "") 
        && (dateToStr == null || dateToStr == "")) 

      { 
       queryBuff.append(" material=" + "\'" + materialName + "\'"); 

      } else { 
       queryBuff.append(" and "); 
       queryBuff.append(" material=" + "\'" + materialName + "\'"); 
      } 

     } 
相關問題