真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

列表頁(yè)的動(dòng)態(tài)條件搜索-創(chuàng)新互聯(lián)

之前在搞.net的時(shí)候,我們可以借助強(qiáng)大的ExpressionTree來(lái)解決,之前有一篇是微軟的EntityFramework表達(dá)式轉(zhuǎn)換:Linq to Entity經(jīng)驗(yàn):表達(dá)式轉(zhuǎn)換,是將一種表達(dá)式轉(zhuǎn)換成數(shù)據(jù)庫(kù)組件能夠識(shí)別的表達(dá)式,只不過(guò)那篇沒(méi)有涉及到View中的條件而已。頁(yè)面動(dòng)態(tài)查詢的最簡(jiǎn)單的方法就是解析View中特定的值來(lái)得到后臺(tái)組件能夠識(shí)別的查詢邏輯。

 我們期待View中能夠這樣指定條件:

成都創(chuàng)新互聯(lián)公司是一家專業(yè)提供惠山企業(yè)網(wǎng)站建設(shè),專注與成都做網(wǎng)站、成都網(wǎng)站設(shè)計(jì)、成都外貿(mào)網(wǎng)站建設(shè)、H5場(chǎng)景定制、小程序制作等業(yè)務(wù)。10年已為惠山眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站建設(shè)公司優(yōu)惠進(jìn)行中。

 它的意思是查詢字段storeName,操作符是like,看起來(lái)并不難,但要解決這么幾個(gè)問(wèn)題:

  1.  參數(shù)收集問(wèn)題,表單域的值以什么樣的方式提交到后臺(tái)?

  2.  后臺(tái)接收參數(shù)類型是什么?

  3.  如何將表單域中的條件轉(zhuǎn)換成數(shù)據(jù)庫(kù)組件能夠識(shí)別的條件?

 我們選擇的數(shù)據(jù)庫(kù)組件是mybatis+mysql。個(gè)人感覺(jué)mybatis在處理動(dòng)態(tài)查詢時(shí)比JPA在前期(技術(shù)學(xué)習(xí)前期,即水平還不太夠的時(shí)候)要簡(jiǎn)單些,也可能是我對(duì)JPA的認(rèn)識(shí)還不夠,總感覺(jué)mybatis這種拼SQL的方式比較熟悉一些,也比較容易控制。當(dāng)然它們的定位本身就不同,這里不多討論?;趍ybatis我們采用了tk.mybatis這個(gè)開源的組件,它的功能非常豐富,分頁(yè),通用mapper,代碼生成等大部分功能都已經(jīng)包含,大家有興趣可以去搜索。

   注:下面的功能是我的同事完成,這里我做為學(xué)習(xí)的過(guò)程來(lái)分享下,可能也有理解不到位的地方,純屬個(gè)人學(xué)習(xí)理解。其中有部分功能未展示出來(lái)(比如權(quán)限過(guò)濾,and or這些分組查詢的支持等),只包含最基本的,每個(gè)項(xiàng)目的需求不同以及團(tuán)隊(duì)環(huán)境不同可以會(huì)有多種實(shí)現(xiàn)方式,選擇大家都能接受的就可以了。

 我們?cè)俜謩e看下上面的三個(gè)問(wèn)題怎么解決:

  1.  參數(shù)收集問(wèn)題,表單域的值以什么樣的方式提交到后臺(tái)方法?

    一般做頁(yè)面查詢時(shí)請(qǐng)求數(shù)據(jù)就兩種方式,get或者post。get一般是在采用了ajax這類技術(shù),post就復(fù)雜一些,分為兩種:一種也是采用ajax提交到后臺(tái),一種是表單的提交。這里呢,由于我們采用了angularjs,所以很顯然只能采用ajax提交,如果查詢條件多,可采用ajax的post。由于上面貼的代碼片段顯示條件的name是動(dòng)態(tài)的,所以我們不可能定義一個(gè)具體的后臺(tái)的業(yè)務(wù)Model對(duì)前臺(tái)的條件,比如有name,email,phone等等,所以我們采用將表單域整個(gè)序列化后的結(jié)果傳遞到后臺(tái)。

列表頁(yè)的動(dòng)態(tài)條件搜索

                 var requestData = $("#"+options.searchFormId+"").serialize();                     var url = listUrl+"?"+requestData+"&pageNum="+$scopeLocal.pageRequest.pageNum;
                     $.ajax({
                         type : "POST",
                         url : url,
                         dataType : 'json',
                         async : false,
                         beforeSend:options.beforeSend,
                         error:options.error,
                         success : function(data) {
                             $scopeLocal.pageResponse = data;
                             $scopeLocal.content=data.list;
                             options.callback($scopeLocal,data);
                         }
                     });

列表頁(yè)的動(dòng)態(tài)條件搜索

 2:參數(shù)類型是什么?
    如果是表單提交方式,我們可以采用HttpServletRequest這個(gè)對(duì)象來(lái)接收所有表單域的值,但上一步我們采用的提交方式并非表單自身的提交,而是ajax的提交,ajax的請(qǐng)求,是不識(shí)別HttpServletRequest這個(gè)參數(shù)類型的,為此我們需要定義一個(gè)自定義的公共的對(duì)象來(lái)接收我們動(dòng)態(tài)View中指定的條件,這里就有個(gè)我們的SearchModel,它包含如下內(nèi)容:

  • 分頁(yè)信息,當(dāng)前頁(yè),頁(yè)數(shù)據(jù)大小

  • 搜索條件信息集合List,一堆我們自己定義的條件,主要包含字段名稱,操作符以及值,這里是本文的重點(diǎn)。

  • 轉(zhuǎn)換為SQL的邏輯

    SearchFilter:

列表頁(yè)的動(dòng)態(tài)條件搜索

  public final class SearchFilter implements Serializable {    private String propertyName;    private Object value;    private Operator operator;    private String orGroup;

列表頁(yè)的動(dòng)態(tài)條件搜索

     SearchModel:

public class SearchModel implements Serializable {    private List searchFilters;    private int pageNum = 1;    private int pageSize = 10;

    上面搜索條件的信息,我們需要從View中獲取,這里應(yīng)用HandlerMethodArgumentResolver來(lái)解決,它只有兩個(gè)方法:

  • 判斷是否是支持的參數(shù)類型

boolean supportsParameter(MethodParameter parameter);

      這個(gè)方法實(shí)現(xiàn)比較簡(jiǎn)單,只需要判斷下當(dāng)前的參數(shù)類型是否是指定的類型即可:

@Override    public boolean supportsParameter(MethodParameter parameter) {
         Class parameterType = parameter.getParameterType();         return SearchModel.class.isAssignableFrom(parameterType);
    }

  • 解析數(shù)據(jù)的詳細(xì)過(guò)程

Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception;

     這個(gè)方法是核心,之前有提到過(guò),因?yàn)槲覀兪莂jax提交,在后臺(tái)的controller方法中不能包含HttpServletRequest request 這個(gè)參數(shù),但后臺(tái)要想取表單域的值從哪取呢?其實(shí)還是從這個(gè)參數(shù)中取,只不過(guò)我們需要換一種方法,可以從上面接口的的webRequest對(duì)象中獲取,有了這個(gè)對(duì)象也就意味著你得到了表單域的所有值了,后臺(tái)的事情就好辦了。

HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);

     下面只需要一個(gè)轉(zhuǎn)換類將HttpServletRequest中的表單值填充到我們自定義的SearchModel中就可以了,這里需要一個(gè)專業(yè)處理轉(zhuǎn)換有類SearchFilterBuilder,首先將表單值轉(zhuǎn)換成一個(gè)集合,字符串類型的:

列表頁(yè)的動(dòng)態(tài)條件搜索

    public static SearchFilterBuilder from(final HttpServletRequest request) {        return new SearchFilterBuilder(request);
    }    public List buildToStrings() {        return buildToStrings(true);
    }    public List buildToStrings(final boolean containsDataAuth) {
        List searchFilterStrings = Lists.newArrayList();

        Map map = request.getParameterMap();        for (Map.Entry entry : map.entrySet()) {
            String strKey = entry.getKey();            for (String value : entry.getValue()) {                if (!Strings.isNullOrEmpty(value)                        && !"none".equals(value)                        && strKey.startsWith(preWhere)) {

                    String filedAndOp = strKey.substring(preWhere.length());
                    searchFilterStrings.add(String.format("%s=%s", filedAndOp, value));
                }
            }
        }        if (containsDataAuth) {           // to do        }        return searchFilterStrings;
    }

列表頁(yè)的動(dòng)態(tài)條件搜索

    基于上面得到的條件集合進(jìn)一步解析條件,由于我們前端View傳遞的條件是字符串的,所以這里應(yīng)用了一個(gè)專門的正則表達(dá)式的類DefaultSearchFilterStringProcessor去解析數(shù)據(jù)

列表頁(yè)的動(dòng)態(tài)條件搜索

   public List build() {

        List searchFilterStrings = buildToStrings();

        List searchFilters = Lists.newArrayList();

        searchFilters.addAll(searchFilterStrings.stream()
                .map(DefaultSearchFilterStringProcessor::from)
                .collect(Collectors.toList()));        return searchFilters;

    }

列表頁(yè)的動(dòng)態(tài)條件搜索

  由于字符串處理的邏輯與本文關(guān)聯(lián)并不大,這里就不貼相關(guān)代碼了,不會(huì)正則的用最笨的人肉解析字符串也是可以的,如前面說(shuō)的都拿到Request對(duì)象了后面都好操作。

 3:如果將表單域中的條件轉(zhuǎn)換成數(shù)據(jù)庫(kù)組件能夠識(shí)別的條件?
    tk.mybatis或者是官方的mybatis-spring組件都支持動(dòng)態(tài)條件,由于我這采用的是tk.mybatis,所以某些類都是tk.mybatis的,tk是進(jìn)一步的封裝,所以原理大體是相同的,之前有提到過(guò)操作mybtis有點(diǎn)像操作原生SQL,感覺(jué)就是一種拼SQL的過(guò)程,這里我們拼這個(gè)動(dòng)態(tài)條件也是類似,簡(jiǎn)單的話只需要一個(gè)靜態(tài)轉(zhuǎn)換方法就可以了,如果再深入一點(diǎn)可以想辦法做成自動(dòng)識(shí)別并轉(zhuǎn)換,有能力的可研究。無(wú)非就是如下的轉(zhuǎn)換:

列表頁(yè)的動(dòng)態(tài)條件搜索

             switch (op) {                case EQ:                    this.criteria.andEqualTo(filed, value);                    break;                case NOTEQ:                    this.criteria.andNotEqualTo(filed, value);                    break;                case LE:                    this.criteria.andLessThanOrEqualTo(filed, value);                    break;

列表頁(yè)的動(dòng)態(tài)條件搜索

 解決完上面這些,我們就可以直接這樣寫后臺(tái)代碼了:
 controller:

列表頁(yè)的動(dòng)態(tài)條件搜索

@RequestMapping(value = "/getAllByPage")
    @ResponseBody    public PageInfo getAllByPage(final SearchModel s1) {        this.convertSearchModel(s1);        
        return storeService.select(s1);
    }

列表頁(yè)的動(dòng)態(tài)條件搜索

 service:有了example對(duì)象,分頁(yè)信息,排序字段,后面的就是tk.mybatis的基本功能了。

@Override    public final PageInfo select(final SearchModel searchModel) {
        Example example = ExampleBuilder.forClass(genericType).fromSearchFilters(searchModel.getSearchFilters()).build();        return select(example, searchModel.getPageNum(), searchModel.getPageSize(), searchModel.getOrderBy());
    }

 基于上面的內(nèi)容,針對(duì)查詢條件,我們可以在View中任意指定查語(yǔ)語(yǔ)句所包含的條件,后臺(tái)的controller以及service基本保持不變,應(yīng)付普通的管理界面查詢足夠了。

 列表頁(yè)的動(dòng)態(tài)條件搜索

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。


文章標(biāo)題:列表頁(yè)的動(dòng)態(tài)條件搜索-創(chuàng)新互聯(lián)
本文路徑:http://weahome.cn/article/ccgoii.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部