一:背景介绍

        在开发的过程当中,前端开发人员往往需要不同的查询条件进行删选所需要的数据,这里将会面对几个普遍的问题:

1. 由于需求的变动,今天需要2个查询条件,明天需要5个查询条件。

2. 需要根据某个字段,或者某几个字段进行排序。

3. 需要可以定义灵活定义获取几条数据,或者要不要获取总数。

         由于这样的问题存在,降低了开发的效率,下面本文将介绍一种有前端驱动后端简洁高效传参方式。

二:前端驱动后端简洁高效传参方式讲解

    1.举例分析

传参条件:

       一:背景介绍-LMLPHP

返回结果:

{
	"status": "200",
	"header": {
		"usNm": "登陆名",
		"nkNm": "昵称"
	},
	"data": {
		"items": [{
			"usNm": "admin",
			"nkNm": "yui",
		}]
	},
	"page": {
		"total": 1,
		"pageSize": 10,
		"pageNum": 1
	}
}

    2.入参参数分析       

        以系统用户为例,需要通过用户名,电话号码为条件查询,然后通过创建时间进行排序,再进行分页。

        query:     {"w":[{"k":"usNm","v":"admin","m":"LK"},{"k":"mob","v":"123","m":"LK"}],"o":[{"k":"usNm","t":"desc"}],"p":{"n":1,"s":10}}

        上面的查询条件解析:

         w:就是where,类似于sql中的where,表示过滤条件。w中的k,v,m分别是key,value,mode。

                key表示查询参数,value表示参数值,mode表示查询模式。

                model有这么几种模式:

                EQ(" = ", "等于"), 
                NE(" <> ", "不等于"), 
                LK(" like ", "包含"), 
                LLK(" like ", "左包含"), 
                RLK(" like ", "右包含"), 
                NLK(" not like ", "不包含"), 
                IN(" in ", "在..中"), 
                NIN(" not in ", "不在..中"),
                LT(" < ", "小于"), 
                LE(" <= ", "小于等于"), 
                GT(" > ", "大于"), 
                GE(" >= ", "大于等于"), 
                BT(" between ", "位于..和..之间"),
                IS(" is ", "是"),
                NIS(" is not ", "不是"),

          o:就是order,类似于sql中的order,表示排序条件。o中的k,t分别是key,type。

                key表示排序参数,type表示升序还是降序。

          p:就是page,类似于sql中的limit,分页查询。p中的n,s分别是pageNo,pageSize。

                pageNo表示第几页,pageSize表示每页显示几页。

          其中where和order是数组,where可以包含多个查询条件,order也可以包含多个排序条件

3.入参参数传到后台解析结果

   1. "w":[{"k":"usNm","v":"admin","m":"LK"},{"k":"mob","v":"123","m":"LK"}]

     后台解析结果:

     and T_SYS_USER.US_NM  like  '%admin%' and T_SYS_USER.MOB  like  '%123%'

    2. "o":[{"k":"usNm","t":"desc"}]

     后台解析结果:

     T_SYS_USER.US_NM desc

    3. "p":{"n":1,"s":10}

     后台解析结果:

      limit 0, 10

  4.入参参数传到后台解析过程 

    一:背景介绍-LMLPHP 

    214行表示:把query解析成java实体对象。 

    217行表示:where和order中的key值映射为数据库表+表字段。例如:<col name="usNm" mapper="T_SYS_USER.US_NM" />

    219行表示:把where查询条件转化为数据库查询条件。

    220行表示:把order排序条件转化为数据库排序条件。

    225行表示:把page分页条件转化为数据库分页条件。


    219行,220行where查询条件转化为数据库查询条件代码实现:

public class GenerateSqlClause {

    public static StringBuffer toOrderClause(QueryClause queryClause, Map<String, String> queryMapper) {
        if (null == queryClause || null == queryClause.getO()) {
            return null;
        }

        StringBuffer result = new StringBuffer();
        List<OrderClause> orderClauseList = queryClause.getO();
        if (CollectionUtils.isNotEmpty(orderClauseList)) {
            boolean isFirst = true;
            for (OrderClause orderClause : orderClauseList) {
                if (!isFirst) {
                    result.append(Symbol.COMMA).append(Symbol.SPACE);
                } else {
                    isFirst = false;
                }
                result.append(toOrderClause(orderClause, queryMapper));
            }
            return result;
        }
        return null;
    }

    public static StringBuffer toOrderClause(OrderClause orderClause, Map<String, String> queryMapper) {
        StringBuffer orderBuff = new StringBuffer();
        String mapper = queryMapper.get(orderClause.getK());
        orderBuff.append(mapper).append(Symbol.SPACE).append(orderClause.getT());
        return orderBuff;
    }

    public static StringBuffer toWhereClause(QueryClause queryClause, Map<String, String> queryMapper) {
        if (null == queryClause || null == queryClause.getW()) {
            return null;
        }
        List<WhereClause> whereClauseList = queryClause.getW();
        if (CollectionUtils.isNotEmpty(whereClauseList)) {
            StringBuffer result = new StringBuffer();
            for (WhereClause whereClause : whereClauseList) {
                result.append(Symbol.SPACE).append(Symbol.AND).append(Symbol.SPACE);
                result.append(toWhereClause(whereClause, queryMapper));
            }
            return result;
        }
        return null;
    }

    public static StringBuffer toWhereClause(WhereClause whereClause, Map<String, String> queryMapper) {
        StringBuffer wherebuff = new StringBuffer();

        String mapper = whereClause.getK();

        if (null != queryMapper) {
            mapper = queryMapper.get(whereClause.getK());
        }
        if (StringUtils.isBlank(mapper)) {
            throw new RuntimeException("key:" + whereClause.getK() + ", not find mapper");
        }

        String val = whereClause.getV();

        SqlCompareMode mode = SqlCompareMode.LK;
        if (null != whereClause.getM()) {
            mode = SqlCompareMode.valueOf(StringUtils.upperCase(whereClause.getM()));
        }

        wherebuff.append(mapper).append(Symbol.SPACE).append(mode.symbol());
        switch (mode) {
            case BT:
                String[] vals = StringUtils.split(val, Symbol.COMMA);
                if (vals.length != 2) {
                    throw new IllegalArgumentException("between mode param value length not equal 2");
                }
                wherebuff.append(SqlMethod.between(vals[0], vals[1]));
                break;
            case NLK:
            case LK:
                wherebuff.append(SqlMethod.like(val));
                break;
            case LLK:
                wherebuff.append(SqlMethod.leftLike(val));
                break;
            case RLK:
                wherebuff.append(SqlMethod.rightLike(val));
                break;
            case IN:
            case NIN:
                wherebuff.append(SqlMethod.in(val));
                break;
            case IS:
            case NIS:
                wherebuff.append(SqlMethod.isOrNis());
                break;
            case EQ:
            case NE:
            case LT:
            case LE:
            case GT:
            case GE:
            default:
                wherebuff.append(SqlMethod.eq(val));
                break;
        }
        return wherebuff;
    }

}

5.前端组装参数:

如果前端采用拼写jsonString的方式,容易出错,且麻烦,所以前端写一个通用query.js来进行入参处理。

前端入参写法:       

var query = new Query();
query.toW("prntPk", "", "IS")
.toW("usNm", "admin", "EQ")
.toO("usNm", "desc")
.toP(1, 10);

Query.js代码

/**
 * 查询条件类
 *
 * @author yuyi
 * @version 1.0.0
 *
 */
var Query = new Class;
Query.include({                      // 和后台交互的数据结构
	queryClause: {
		w: [],
		o: []
	},

	/**
	 * 构造函数,根据传入的参数初始化每个grid类的属性
	 */
	construct: function(obj){
		this.queryClause = {
				w: [],
				o: []
		}
	},

	toW: function(fieldName, targetValue, mode){
		return this.buildWhereClause(fieldName, targetValue, mode);
	},

	toO: function(sortByKey, sortByType) {
		return this.buildOrderClause(sortByKey, sortByType);
	},

	toP: function(pageNum, pageSize) {
		return this.buildPageClause(pageNum, pageSize);
	},

	toWhere: function(fieldName, targetValue, mode){
		return this.buildWhereClause(fieldName, targetValue, mode);
	},

	toOrder: function(sortByKey, sortByType) {
		return this.buildOrderClause(sortByKey, sortByType);
	},

	toPage: function(pageNum, pageSize) {
		return this.buildPageClause(pageNum, pageSize);
	},

	buildWhereClause: function(fieldName, targetValue, mode){
		if(typeof mode == "undefined" || $.trim(mode) == '') {
			//mode = Query.LK;
			//mode = 'LK';
			mode = SqlCompareMode.LK;
		}
		this.queryClause.w.push ({
			'k': $.trim(fieldName),
			'v': $.trim(targetValue),
			'm': mode
		});
		return this;
	},

	buildOrderClause: function(sortByKey, sortByType) {
		if(typeof sortByType == "undefined" || $.trim(sortByType) == '') {
			sortByType = 'DESC';
		}
		this.queryClause.o.push ({
			'k': $.trim(sortByKey),
			't': sortByType
		});
		return this;
	},

	buildPageClause: function(pageNum, pageSize) {
		this.queryClause.p = {
			'n': pageNum,
			's': pageSize
		};
		return this;
	},

	toString: function() {
		return JSON.stringify(this.queryClause)
	},

});
05-18 03:28