簡體   English   中英

通過本機查詢按多個參數的組合進行搜索

[英]Search by the combination of multiple parameters via Native Query

我目前正在研究一種功能,它將允許系統通過6個參數的組合來搜索公共服務收據,這些參數可以為null,這意味着不應使用以下參數過濾收據:accountNumber,amountRangeMin,amountRangeMax,dateRangeMin,dateRangeMax, publicServiceId。 但是,為每個參數組合制作方法都不是一種選擇,我認為必須有更好的方法,一開始我的方法如下:

在我的服務上,我有以下方法:

public Map<String,Object> findPublicServiceReceiptsByParams(Integer accountNumber, BigDecimal amountRangeMin,
        BigDecimal amountRangeMax, LocalDate dateRangeMin, LocalDate dateRangeMax, Integer publicServiceId) {
    Map<String,Object> publicServiceReceipts = new HashMap<String,Object>();
    String accountNumberFilter = !(accountNumber==null) ? accountNumber.toString() : "AccountNumberTableName";
    String amountRangeMinFilter = !(amountRangeMin==null) ? amountRangeMin.toString() : "table.AmountColumnName";
    String amountRangeMaxFilter = !(amountRangeMax==null) ? amountRangeMax.toString() : "table.AmountColumnName";
    String dateRangeMinFilter = !(dateRangeMin==null) ? dateRangeMin.toString() : "Table.ReceiptCreationDateColumn";
    String dateRangeMaxFilter = !(dateRangeMax==null) ? dateRangeMax.toString() : "Table.ReceiptCreationDateColumn";
    String publicServiceIdFilter = !(publicServiceId==null) ? publicServiceId.toString() : "table.publicServiceIdColumn";
    publicServiceReceipts = publicServiceReceiptRepository.findPublicServiceReceiptsByParams(accountNumberFilter,
            amountRangeMinFilter, amountRangeMaxFilter, dateRangeMinFilter, dateRangeMaxFilter,
            publicServiceIdFilter);
    return publicServiceReceipts;
}

然后在我的存儲庫中,我有:

final static String FIND_PUBLIC_SERVICES_BY_ARGS = "Select (Insert whatever logic should go in here to select columns from receipts the where clause is the one that matters)"
        + "    WHERE ACT.ACT_AccountNumber=:accountNumberFilter\n"
        + "      AND PSE.PSE_Id=:publicServiceIdFilter\n"
        + "      AND PSR.PSR_CreateDate BETWEEN :dateRangeMinFilter AND :dateRangeMaxFilter\n"
        + "      AND PSR.PSR_Amount BETWEEN :amountRangeMinFilter AND :amountRangeMaxFilter\n"
        + " order by PSR.PSR_CreateDate desc";

@Query(nativeQuery = true, value = FIND_PUBLIC_SERVICES_BY_ARGS)
Map<String, Object> findPublicServiceReceiptsByParams(@Param("accountNumberFilter") String accountNumberFilter,
        @Param("amountRangeMinFilter") String amountRangeMinFilter,
        @Param("amountRangeMaxFilter") String amountRangeMaxFilter,
        @Param("dateRangeMinFilter") String dateRangeMinFilter,
        @Param("dateRangeMaxFilter") String dateRangeMaxFilter,
        @Param("publicServiceIdFilter") String publicServiceIdFilter);

}

我的理由是,如果參數為null,則意味着使用Web Service的人對該參數都不感興趣,因此,如果發生這種情況,我將該變量設置為Column Name,以使其在WHERE子句中不受影響,並且從理論上講使它生效比較簡單,但是我發現它會以字符串形式發送名稱,因此不會被視為sql語句,這是我的思想上的缺陷,正如我所說,除了為每種組合編寫每種方法外,還必須有其他方法,感謝您的幫助:)。

您應該使用Criteria API ,該API是為創建動態查詢而設計的。 在這種情況下,並不一定要使用命名查詢。 有了它,您可以執行以下操作:

@PersistenceContext
EntityManager em;

List<YourEntity> method(String argument) {
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<YourEntity> cq = cb.createQuery(YourEntity.class);
    Root<YourEntity> root = cq.from(YourEntity.class);

    List<Predicate> predicates = new ArrayList<>();
    if (argument == null) {
        predicates.add(cb.equal(root.get("yourAttribute"), argument);
    }
    // rest of your logic goes here

    cq.where(predicates.toArray(new Predicate[]{}));
    return em.createQuery(cq).getResultList();
}

我找到了一種解決此問題的方法,我這樣做是這樣的(我將僅顯示本機Query,因為這是我所更改的內容):

DECLARE  @actNum varchar(50),@crdNum varchar(50),@pseId varchar(50),@dateMin varchar(50),@dateMax varchar(50),@amountMin varchar(50),@amountMax varchar(50)
SET @actNum = :actNum
SET @crdNum = :crdNum 
SET @pseId =  :pseId 
SET @dateMin = :dateMin 
SET @dateMax = :dateMax 
SET @amountMin = :amountMin 
SET @amountMax = :amountMax 
--Whatever Select with joins statement
                   WHERE ACT.ACT_AccountNumber = CASE WHEN @actNum = 'N/A' 
                                             THEN ACT.ACT_AccountNumber 
                                             ELSE @actNum END
                 AND CRD_CardNumber = CASE WHEN @crdNum = 'N/A' 
                                      THEN CRD_CardNumber 
                                      ELSE @crdNum END
                 AND PSE.PSE_Id= CASE WHEN @pseId = 'N/A' 
                                 THEN PSE.PSE_Id 
                                 ELSE @pseId END
                 AND PSR.PSR_CreateDate >= CASE WHEN @dateMin = 'N/A' 
                                                THEN PSR.PSR_CreateDate 
                                                ELSE @dateMin END 
                                        AND PSR.PSR_CreateDate <= CASE WHEN @dateMax = 'N/A' 
                                            THEN PSR.PSR_CreateDate 
                                            ELSE @dateMax END
                 AND PSR.PSR_Amount BETWEEN CASE WHEN @amountMin = 'N/A' 
                                            THEN PSR.PSR_Amount 
                                            ELSE @amountMin END 
                                    AND CASE WHEN @amountMax = 'N/A' 
                                        THEN PSR.PSR_Amount 
                                        ELSE @amountMax END 
            ORDER BY PSR.PSR_CreateDate DESC

后端會將參數發送為“ N / A”(如果不應該用於過濾數據)或實際值,這對我來說很好!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM