标题已指出本文要说的三件事,首先是主角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. Integer类toString(int i,int radix)方法

    Integer类toString(int i,int radix)方法: 首先抛出java的api中的介绍: public static String toString(int i, int radi ...

  2. Java程序设计第三次作业

    编写“学生”类及其测试类. 5.1 “学生”类: 类名:Student 属性:姓名.性别.年龄.学号.5门课程的成绩 方法1:在控制台输出各个属性的值. 方法2:计算平均成绩 方法3:输出各个属性的值 ...

  3. 【Contest Hunter 5302】金字塔

    [原题链接]传送门 [题解思路] 1.考虑如何将序列与树相对应,想到类似dfs序和欧拉序,同一个子树对应序列连续 2.暴力分子树过于复杂,考虑简化(划重点: 若当前区间为[l,r],考虑第一颗子树所在 ...

  4. CentOS7.5 下搭建SFTP

    CentOS7.5 下搭建SFTP Linux 创建用户组 groupadd sftp 创建用户test useradd -G sftp -s /sbin/nologin test -s 禁止用户ss ...

  5. C#File类常用文件操作以及一个模拟的控制台文件管理系统

    重温一下C#中File类的一些基本操作: File类,是一个静态类,主要是来提供一些函数库用的. 使用时需要引入System.IO命名空间. 一.常用操作: 1.创建文件方法 //参数1:要创建的文件 ...

  6. P2678 跳石头

    传送门 思路: 二分跳跃的最短距离 mid .暴力判断如果有两个石头直接的距离小于 mid ,就把这个石头拿走.如果拿走的石头数目 cnt ≤ m,说明二分的答案可行,ans = mid,接着二分更短 ...

  7. Cordova入门系列(四)自定义Cordova插件--showToast

    前三篇Cordova入门系列,简单讲解了Cordova,以及如何调用Cordova插件,今天我们讲解一下如何自己做一个插件. 自定义插件,就是自己写一些安卓java代码,然后和js代码以及配置文件,封 ...

  8. java异常处理try catch finally

    1       异常 1.1      异常处理的作用 在编程时,如果出现文件打开失败,读写文件就会异常退出.如果出现内存溢出错误,程序也会异常退出.如果不能对这些异常进行处理.程序则无法正常运行.所 ...

  9. cobble服务器安装配置

    1.配置系统关闭 firewalld防火墙 [root@sky ~]# systemctl stop firewalld.service [root@sky ~]# systemctl disable ...

  10. Springboot 中配置文件的优先级和加载顺序

    1. 若application.yml 和bootStrap.yml 在同一目录下,则bootStrap.yml 的加载顺序要高于application.yml,即bootStrap.yml  会优先 ...