一:背景介绍
在开发的过程当中,前端开发人员往往需要不同的查询条件进行删选所需要的数据,这里将会面对几个普遍的问题:
1. 由于需求的变动,今天需要2个查询条件,明天需要5个查询条件。
2. 需要根据某个字段,或者某几个字段进行排序。
3. 需要可以定义灵活定义获取几条数据,或者要不要获取总数。
由于这样的问题存在,降低了开发的效率,下面本文将介绍一种有前端驱动后端简洁高效传参方式。
二:前端驱动后端简洁高效传参方式讲解
1.举例分析
传参条件:
返回结果:
{
"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.入参参数传到后台解析过程
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)
},
});