标题已指出本文要说的三件事,首先是主角jqgrid,将应用在自定义列表中,重点介绍如何实现高级查询。

  使用jqgrid实现自定义列表分为两大步骤,首先是要根据业务完成jqgrid的对象定义,即列表的描述配置;再就是服务端加载数据json对象。为实现更丰富条件的数据展示,jqgrid内置了高级检索的功能,可以自定义条件、自定义and、or的规则来查询数据,如图:

查询功能很强大,但问题也明显,后台如何识别这些条件?以下是我使用的方法:

1、定义高级查询的对象,通过json转换为对象,一来后台能够好进行参数处理,二来强制性的规则更安全,有规则成方圆。

2、为了完成where条件的转换,对高级查询对象进行解析,处理成可执行的sql where查询条件。

3、在实现上面功能之前,应先完成列表数据字段的规则定义,只有有效的字段才能进行查询。

以下是查询对象的定义:

     /// <summary>
/// jqgrid高级查询json反序列化对象
/// </summary>
[Serializable]
public class ComplexFilters
{
/// <summary>
/// 查询条件AND、OR
/// </summary>
public string groupOp { get; set; } /// <summary>
/// 查询字段
/// </summary>
public List<FilterItem> rules { get; set; } /// <summary>
/// 嵌套查询
/// </summary>
public List<ComplexFilters> groups { get; set; }
} /// <summary>
/// jqgrid高级查询字段明细
/// </summary>
[Serializable]
public class FilterItem
{
/// <summary>
/// 字段名称
/// </summary>
public string field { get; set; } /// <summary>
/// 查询条件
/// </summary>
public string op { get; set; } /// <summary>
/// 关键字
/// </summary>
public string data { get; set; }
}

以下是查询规则的解析:

     /// <summary>
/// 高级查询,通过grid传入的filter参数进行解析
/// </summary>
public class GridComplexFilter
{
#region 初始化查询对象 /// <summary>
/// 高级查询对象
/// </summary>
public Util.WebControl.ComplexFilters _filterObj { get; set; } /// <summary>
/// 字段定义
/// </summary>
public Service.Grid.Base_QueryFieldRORL _baseFiles { get; set; } /// <summary>
/// 原始高级查询字符串
/// </summary>
public string _filterStr { get; set; } /// <summary>
/// 初始化对象
/// </summary>
/// <param name="f">grid传入filter参数</param>
/// <param name="b">查询字段对象集</param>
public GridComplexFilter(string f, Service.Grid.Base_QueryFieldRORL b)
{
if (!string.IsNullOrEmpty(f) && b != null)
{
this._filterObj = Json.ToObject<Util.WebControl.ComplexFilters>(f);
_baseFiles = b;
}
} #endregion /// <summary>
/// 获取SQL条件
/// </summary>
/// <returns></returns>
public string GetSqlWhere()
{
return GetSql(_filterObj);
} /// <summary>
/// 处理SQL查询条件,含子查询
/// </summary>
/// <param name="_fObj">查询对象</param>
/// <returns></returns>
private string GetSql(Util.WebControl.ComplexFilters _fObj)
{
if (_fObj == null)
{
return "";
} bool _isFirst = true;//标识是否为首次加载有效字段条件,作为添加AND或OR关键字
StringBuilder _sqlWhere = new StringBuilder("");
//处理字段查询明细
if (_fObj.rules != null && _fObj.rules.Count > )
{
foreach (var item in _fObj.rules)
{
if (!string.IsNullOrEmpty(item.field) && !string.IsNullOrEmpty(item.op))
{
if (_isFirst != true)
{
//非首个条件添加AND或者OR
_sqlWhere.AppendFormat(" {0} ", _fObj.groupOp);
}
_sqlWhere.Append(getFieldFilter(item));
_isFirst = false;
}
}
}
//处理嵌套查询
if (_fObj.groups != null && _fObj.groups.Count > )
{
foreach (var item in _fObj.groups)
{
string _child = GetSql(item);
if (!string.IsNullOrEmpty(_child))
{
_sqlWhere.AppendFormat(" {0} {1}", _fObj.groupOp, _child);
}
}
} if (_sqlWhere.Length > )
{
return string.Format(" ({0}) ", _sqlWhere.ToString());
}
else
{
return "";
}
} /// <summary>
/// 处理单个字段查询,匹配数据类型及查询方式
/// </summary>
/// <param name="_fil">查询字段对象</param>
/// <returns></returns>
private string getFieldFilter(FilterItem _fil)
{
if (string.IsNullOrEmpty(_fil.op) || string.IsNullOrEmpty(_fil.field))
{
return "";
}
var _dataType = getDataType(_fil.field);//字段对象
string _reValue = "";
if (_dataType.MQF_DataType == "string")
{//字段为字符串时的查询
#region 字符串查询 if (_fil.op == "eq" && !string.IsNullOrEmpty(_fil.data))
{//等于
_reValue = string.Format(" {0}='{1}' ", _fil.field, _fil.data);
}
else if (_fil.op == "ne" && !string.IsNullOrEmpty(_fil.data))
{//不等于
_reValue = string.Format(" {0}<>'{1}'", _fil.field, _fil.data);
}
else if (_fil.op == "bw" && !string.IsNullOrEmpty(_fil.data))
{//开头是
_reValue = string.Format(" {0} Like '{1}%' ", _fil.field, _fil.data);
}
else if (_fil.op == "bn" && !string.IsNullOrEmpty(_fil.data))
{//开头不是
_reValue = string.Format(" {0} not Like '{1}%' ", _fil.field, _fil.data);
}
else if ((_fil.op == "in" || _fil.op == "ni") && !string.IsNullOrEmpty(_fil.data))
{//属于、不属于
//处理数据项
string[] _split = _fil.data.Replace("'", "").Split(' ');
string _strSplit = "";
foreach (var item in _split)
{
if (!string.IsNullOrEmpty(item))
{
_strSplit += "'" + item + "',";
}
}
_strSplit = _strSplit.TrimEnd(',');
if (!string.IsNullOrEmpty(_strSplit))
{
if (_fil.op == "in")
{//属于项
_reValue = string.Format(" ({0} in ({1})) ", _fil.field, _fil.data);
}
else if (_fil.op == "ni")
{//不属于项
_reValue = string.Format(" ({0} not in ({1})) ", _fil.field, _fil.data);
}
}
}
else if (_fil.op == "ew" && !string.IsNullOrEmpty(_fil.data))
{//结尾是
_reValue = string.Format(" {0} Like '%{1}' ", _fil.field, _fil.data);
}
else if (_fil.op == "en" && !string.IsNullOrEmpty(_fil.data))
{//结尾不是
_reValue = string.Format(" {0} not Like '%{1}' ", _fil.field, _fil.data);
}
else if (_fil.op == "cn" && !string.IsNullOrEmpty(_fil.data))
{//包含
_reValue = string.Format(" {0} Like '%{1}%' ", _fil.field, _fil.data);
}
else if (_fil.op == "nc" && !string.IsNullOrEmpty(_fil.data))
{//不包含
_reValue = string.Format(" {0} not Like '%{1}%' ", _fil.field, _fil.data);
}
else if (_fil.op == "nu")
{//为空
_reValue = string.Format(" ({0} is Null or {0}='')", _fil.field);
}
else if (_fil.op == "nn")
{//不为空
_reValue = string.Format(" ({0} is not Null and {0}<>'')", _fil.field);
} #endregion
}
else if (_dataType.MQF_DataType == "int" || _dataType.MQF_DataType == "float")
{//字段类型为数字
#region 数字类型查询 if (_fil.op == "eq" && !string.IsNullOrEmpty(_fil.data))
{//等于
if (!Util.ValidateUtil.IsNumberSign(_fil.data) && !Util.ValidateUtil.IsDecimalSign(_fil.data))
{
throw new Util.SysException.HfQueryPlatException("查询字符串数据类型转换失败,应为数据,查询名称:" + _dataType.MQF_ChineseName);
}
_reValue = string.Format(" {0} = {1} ", _fil.field, _fil.data);
}
else if (_fil.op == "ne" && !string.IsNullOrEmpty(_fil.data))
{//不等于
if (!Util.ValidateUtil.IsNumberSign(_fil.data) && !Util.ValidateUtil.IsDecimalSign(_fil.data))
{
throw new Util.SysException.HfQueryPlatException("查询字符串数据类型转换失败,应为数据,查询名称:" + _dataType.MQF_ChineseName);
}
_reValue = string.Format(" {0} <> {1} ", _fil.field, _fil.data);
}
else if (_fil.op == "lt" && !string.IsNullOrEmpty(_fil.data))
{//小于
if (!Util.ValidateUtil.IsNumberSign(_fil.data) && !Util.ValidateUtil.IsDecimalSign(_fil.data))
{
throw new Util.SysException.HfQueryPlatException("查询字符串数据类型转换失败,应为数据,查询名称:" + _dataType.MQF_ChineseName);
}
_reValue = string.Format(" {0} < {1} ", _fil.field, _fil.data);
}
else if (_fil.op == "le" && !string.IsNullOrEmpty(_fil.data))
{//小于等于
if (!Util.ValidateUtil.IsNumberSign(_fil.data) && !Util.ValidateUtil.IsDecimalSign(_fil.data))
{
throw new Util.SysException.HfQueryPlatException("查询字符串数据类型转换失败,应为数据,查询名称:" + _dataType.MQF_ChineseName);
}
_reValue = string.Format(" {0} <= {1} ", _fil.field, _fil.data);
}
else if (_fil.op == "gt" && !string.IsNullOrEmpty(_fil.data))
{//大于
if (!Util.ValidateUtil.IsNumberSign(_fil.data) && !Util.ValidateUtil.IsDecimalSign(_fil.data))
{
throw new Util.SysException.HfQueryPlatException("查询字符串数据类型转换失败,应为数据,查询名称:" + _dataType.MQF_ChineseName);
}
_reValue = string.Format(" {0} > {1} ", _fil.field, _fil.data);
}
else if (_fil.op == "ge" && !string.IsNullOrEmpty(_fil.data))
{//大于等于
if (!Util.ValidateUtil.IsNumberSign(_fil.data) && !Util.ValidateUtil.IsDecimalSign(_fil.data))
{
throw new Util.SysException.HfQueryPlatException("查询字符串数据类型转换失败,应为数据,查询名称:" + _dataType.MQF_ChineseName);
}
_reValue = string.Format(" {0} >= {1} ", _fil.field, _fil.data);
}
else if (_fil.op == "nu")
{//为空
_reValue = string.Format(" ({0} is Null) ", _fil.field);
}
else if (_fil.op == "nn")
{//不为空
_reValue = string.Format(" ({0} is not Null) ", _fil.field);
} #endregion
}
else if (_dataType.MQF_DataType == "datetime")
{//字段类型为时间
#region 日期类型查询 if (_fil.op == "eq" && !string.IsNullOrEmpty(_fil.data))
{//等于
if (!Util.ValidateUtil.IsDate(_fil.data))
{
throw new Util.SysException.HfQueryPlatException("查询字符串数据类型转换失败,应为日期格式,查询名称:" + _dataType.MQF_ChineseName);
}
_reValue = string.Format(" {0} = '{1}' ", _fil.field, _fil.data);
}
else if (_fil.op == "ne" && !string.IsNullOrEmpty(_fil.data))
{//不等于
if (!Util.ValidateUtil.IsDate(_fil.data))
{
throw new Util.SysException.HfQueryPlatException("查询字符串数据类型转换失败,应为日期格式,查询名称:" + _dataType.MQF_ChineseName);
}
_reValue = string.Format(" {0} <> '{1}' ", _fil.field, _fil.data);
}
else if (_fil.op == "lt" && !string.IsNullOrEmpty(_fil.data))
{//小于
if (!Util.ValidateUtil.IsDate(_fil.data))
{
throw new Util.SysException.HfQueryPlatException("查询字符串数据类型转换失败,应为日期格式,查询名称:" + _dataType.MQF_ChineseName);
}
_reValue = string.Format(" {0} < '{1}' ", _fil.field, _fil.data);
}
else if (_fil.op == "le" && !string.IsNullOrEmpty(_fil.data))
{//小于等于
if (!Util.ValidateUtil.IsDate(_fil.data))
{
throw new Util.SysException.HfQueryPlatException("查询字符串数据类型转换失败,应为日期格式,查询名称:" + _dataType.MQF_ChineseName);
}
_reValue = string.Format(" {0} <= '{1}' ", _fil.field, _fil.data);
}
else if (_fil.op == "gt" && !string.IsNullOrEmpty(_fil.data))
{//大于
if (!Util.ValidateUtil.IsDate(_fil.data))
{
throw new Util.SysException.HfQueryPlatException("查询字符串数据类型转换失败,应为日期格式,查询名称:" + _dataType.MQF_ChineseName);
}
_reValue = string.Format(" {0} > '{1}' ", _fil.field, _fil.data);
}
else if (_fil.op == "ge" && !string.IsNullOrEmpty(_fil.data))
{//大于等于
if (!Util.ValidateUtil.IsDate(_fil.data))
{
throw new Util.SysException.HfQueryPlatException("查询字符串数据类型转换失败,应为日期格式,查询名称:" + _dataType.MQF_ChineseName);
}
_reValue = string.Format(" {0} >= '{1}' ", _fil.field, _fil.data);
}
else if (_fil.op == "nu")
{//为空
_reValue = string.Format(" ({0} is Null) ", _fil.field);
}
else if (_fil.op == "nn")
{//不为空
_reValue = string.Format(" ({0} is not Null) ", _fil.field);
} #endregion
} return _reValue;
} /// <summary>
/// 获取字段数据类型
/// </summary>
/// <param name="field"></param>
/// <returns></returns>
private Service.Grid.Base_QueryFieldROC getDataType(string field)
{
var _field = this._baseFiles.First(p => p.MQF_Name == field);
if (_field != null)
{
return _field;
}
else
{
throw new HFun.Util.SysException.HfQueryPlatException("查询字段数据类型匹配失败,字段:" + field);
}
}
}

以上代码还在完善中。

系统现已将服务层改为webapi,通过csla框架作为配置对象基础,使用redis进行中间数据缓存,通过webapi作为核心服务层向asp.net mvc前端提供对象及数据。

(转载请带标记《HFun.net快速开发平台》)

jqgrid自定义列表开发=》实现高级查询的更多相关文章

  1. 循序渐进VUE+Element 前端应用开发(29)--- 高级查询条件的界面设计

    在系统模块中的业务列表展示里面,一般我们都会在列表中放置一些查询条件,如果是表字段不多,大多数情况下,放置的条件有十个八个就可以了,如果是字段很多,而这些条件信息也很关键的时候,就可能放置很多条件,但 ...

  2. Winform开发框架之通用高级查询模块

    最近一直忙于公司的事情,虽然一直在做一些相关的技术研究,但是很久没能静下心来好好写写博客文章了,想想也有半个月之多了,这半个月来,也一直致力于改善我的WInform开发框架,使得自己及客户使用起来更加 ...

  3. jqgrid 表格中筛选条件的多选下拉,树形下拉 ;文本框清除插件;高级查询多条件动态筛选插件[自主开发]

    /** * @@desc 文本框清除按钮,如果isAutoWrap为false当前文本框父级必须是relative定位,boostrap参考input-group * @@author Bear.Ti ...

  4. HFun.快速开发平台(二)=》自定义列表实例(请求参数的处理)

    上编描述了自定义列表的基本实现功能,本此记录列表的请求过程. 个人比较喜欢对参数进行对象化,方便后续人维护及查看,先上代码: /************************************ ...

  5. HFun.快速开发平台(四)=》自定义列表实例(请求参数的处理)

    上编自定义列表描述了自定义列表的基本实现功能,本此记录列表的请求过程. 个人比较喜欢对参数进行对象化,方便后续人维护及查看,先上代码: /******************************* ...

  6. Winform开发框架之通用高级查询模块--SNF快速开发平台3.3-Spring.Net.Framework

    最近项目确实忙,但也是一直忙于有关项目和框架技术的事情,也一直致力于改善我的WInform开发框架.使得自己及客户使用起来更加方便,更加友好,更加高效. 在很多程序模块中都很常见,也是给客户扩展查询的 ...

  7. 每日学习心得:SharePoint 2013 自定义列表项添加Callout菜单项、文档关注、SharePoint服务端对象模型查询

    前言: 前一段时间一直都比较忙,没有什么时间进行总结,刚好节前项目上线,同时趁着放假可以好好的对之前遇到的一些问题进行总结.主要内容有使用SharePoint服务端对象模型进行查询.为SharePoi ...

  8. ABP开发框架前后端开发系列---(13)高级查询功能及界面的处理

    在一般的检索界面中,基于界面易用和美观方便的考虑,我们往往只提供一些常用的条件查询进行列表数据的查询,但是有时候一些业务表字段很多,一些不常见的条件可能在某些场景下也需要用到.因此我们在通用的查询条件 ...

  9. SharePoint 2013开发入门探索(一)- 自定义列表

    在SharePoint 2013中创建自定义列表的方式有很多,在网站内容页面添加应用程序就可以创建(站点内容-〉 您的应用程序),也可以通过SharePoint Designer 2013创建,而本文 ...

随机推荐

  1. Bytom储蓄分红合约解析

    储蓄分红合约简介 储蓄分红合约指的是项目方发起了一个锁仓计划(即储蓄合约和取现合约),用户可以在准备期自由选择锁仓金额参与该计划,等到锁仓到期之后还可以自动获取锁仓的利润.用户可以在准备期内(dueB ...

  2. Struts2---动态action以及应用

    为了处理各种逻辑业务,根据execute方法来判断请求哪种业务,然后将请求转发到对应的业务处理上, 通过动态请求action对象中的方法,实现某个单一的业务逻辑处理. 动态action的应用 //创建 ...

  3. idea for Mac for循环快捷键

    1.itar 生成array for代码块 for (int i = 0; i < array.length; i++) { = array[i]; } 2.itco 生成Collection迭 ...

  4. /etc/security/limits.conf不生效

    总结下来发现要使limits.conf生效,需要在  /etc/ssh/sshd_config  配置中 设置 UsePAM  yes UseLogin yes    #这个保证其他的用户也能修改设置 ...

  5. Log4net详细说明

    1.概述 log4net是.Net下一个非常优秀的开源日志记录组件.log4net记录日志的功能非常强大.它可以将日志分不同的等级,以不同的格式,输出到不同的媒介.本文主要是介绍如何在Visual S ...

  6. Cannot resolve classpath entry: /Program Files/IBM/SQLLIB/java/db2java.zip

    在mybatis的逆向工程中,使用java代码和xml配置文件生成时出现以下的错误 原来自己在复制官方配置文件的参考时将这一句也复制了进来 删掉后运行即可!成功的话控制台是没有输出的

  7. js计算地球(地图)上两点的直线距离

    //计算两点位置距离 getDistance: function (lat1, lng1, lat2, lng2) { lat1 = lat1 || 0; lng1 = lng1 || 0; lat2 ...

  8. Intel收购半导体设计公司eASIC

    来源:本文由公众号 半导体行业观察(ID:icbank)翻译自「anandtech」,谢谢. 北京时间今天凌晨,Intel宣布收购了半导体设计公司eASIC. eASIC的商业模式介于传统Fables ...

  9. vue 简单实现父组件向子组件传值,简单来说就是子组件肆意妄为的调用父组件里后台返回的值

    首先在于父子组件传值的方法很多,本人在这里只是简单描述一下一个组件里面引用了子组件,那么子组件如何才能获取父组件中后台返回的值呢? 首先调用组件相信大家都应该明白了(不明白的自己撸撸文档), < ...

  10. classList用法

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...