在開發(fā)過程遇到一個需求诗箍,查詢篩選框中存在兩種可傳入字段:多選字段和手動輸入,根據(jù)傳入的字符串?dāng)?shù)組和手動輸入對數(shù)據(jù)庫的某個字段分別進(jìn)行一次in的精確匹配和like模糊查詢挽唉。
因?yàn)閰?shù)是動態(tài)傳入的滤祖,開始拼裝的sql語句如下
if(GETWAYLIST != null && ! GETWAYLIST.isEmpty() && GETWAY? != null && GETWY != "")
sql="select * from HOUSE where 1=1? ?and?GETWAY? ?in (:GETWAYLIST) and GETWAY like :GETWAY";
GETWAYLIST = Arrays.asList(getWay.sprit(",")//傳入的多選項(xiàng),多個以逗號相隔
這樣寫的問題就是如果兩個條件同時存在瓶籽,其中一個查詢?yōu)榭諘?dǎo)致另外一個條件查詢失敗匠童。
將上述的sql修改后的語句為
select * from HOUSE where?1=1? ?and?GETWAY??in (:GETWAYLIST) or GETWAY like :GETWAY;
但是sql中and的執(zhí)行優(yōu)先度比or的優(yōu)先度高,先執(zhí)行了前面的and邏輯再執(zhí)行后面的or語句塑顺,所以查出來的數(shù)據(jù)并不是我想要的數(shù)據(jù)
最后查閱資料后修改語句為
select * from HOUSE where?1=1? ?and (GETWAY??in (:GETWAYLIST) or GETWAY like :GETWAY);
()的優(yōu)先度比and的要高汤求。
另外項(xiàng)目中用到了springjpa的Specification方法拼裝數(shù)據(jù)庫查詢方法,其中的寫法如下(針對同一參數(shù)不同的查詢類型)
public class HouseSpecification implements Specification<House>{
? ??//篩選條件參數(shù)-證載用途
????String proveUse;
? ??//篩選條件參數(shù)-實(shí)際用途手動輸入
????String proveUseOther;
? ??public HouseSpecification(?String proveUse,?String proveUseOther){
? ??????this.proveUse=proveUse;
? ??????this.proveUseOther=proveUseOther;
????}
? ??@SuppressWarnings("static-access")
????@Override
????public Predicate toPredicate(Root<House> root, CriteriaQuery<?> query, CriteriaBuilder cb)
????{
? ? ? ? ?//證載用途,根據(jù)傳入?yún)?shù)拼裝
? ? ? ? ?if(!CheckUtil.isNullorEmpty(proveUse)&&!CheckUtil.isNullorEmpty(proveUseOther)){
? ? ? ? ?????List<String> proveUseList = Arrays.asList(proveUse.split(","));
? ? ? ? ?????predicates.add(cb.or(cb.and(root.<String>get("proveUse").in(proveUseList)),cb.and(cb.like(root.? <String>get("proveUse"),"%"+proveUseOther+"%"))));
? ? ? ?}
????????else if(!CheckUtil.isNullorEmpty(proveUse)&&CheckUtil.isNullorEmpty(proveUseOther)){
????????????List<String> proveUseList = Arrays.asList(proveUse.split(","));
????????????predicates.add(cb.and(root.<String>get("proveUse").in(proveUseList)));
????????}
????????else if(!CheckUtil.isNullorEmpty(proveUseOther)){
????????????predicates.add(cb.and(cb.like(root.<String>get("proveUse"),"%"+proveUseOther+"%")));
????????}
? ??????return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
? ?? ???}
}
使用時調(diào)用dao層封裝好的 findAll(new HouseSpecification (proveUse,proveUseOther))