【JEECG技术文档】Jeecg高级查询器
1. 背景
对于用户来讲查询功能按易用性分三个层次:
1)最简单查询操作是一个输入框,全文检索,如百度,后台实现技术使用搜索引擎,需要设计和建立索引,技术较为复杂,适用于文档和信息数据库检索,但是结果很难精确控制。
2)其次是定义字段查询,很多企业信息系统大多用的是这种查询,针对模块特定字段的查询,有针对性、使用门坎低,适用于企业内部信息管理系统模块定制。
3)最后一种是专门针对数据模型灵活的查询编辑器,使用难度最高,但是查询结果可以灵活和精确的控制,适用于有一定IT知识并对数据相当了解的用户,同时又可以避免直接将数据库暴露给用户带来的不安全隐患。
大家不难发现一个好的系统软件的查询基本会涵盖上述三种类型的查询功能
2. jeecg实现原理
Jeecg系统中模块主要使用第二种方式的查询功能,使用hibernate的QBC来封装前端查询条件,针对字段的定制过滤条件,最后转换为sql执行数据库查询。
现有方案优点:
- 默认无须复杂开发即可实现字段检索,支持范围、模糊、精确匹配查询
- 内置简单表达式支持:!*,实现非、模糊、数组等
现有方案缺点:
- 不支持or条件
- 不支持字段间操作field1=field2
- 不支持非hibernate关联表联合查询
- 单一字段条件只能出现一次
- 不支持sql嵌套
- 要支持上述功能需要额外开发定制工作
某些特定场景下,用户想要通过模块获得相关信息必须借助于第三方报表模块功能或求助于开发人员,无形中对报表模块开发带来一定压力。比如,用户要从模块中查询特殊的部分数据进行操作,现有查询功能无法做到,报表模块又不能操作编辑,这个时候就是高级查询器定制查询功能派上用场的时候了。
3. 类似应用举例
我们来看看Outlook邮件查询设计:
1)全文检索型
2)字段定制型
3)高级查找
微软Team Foundation Server查询编辑器:
4. Jeecg查询器设计与实现
UI设计:首先要实现高级查询,必须要对数据表元信息metadata进行封装才可以通用化,我们利用datagrid标签中的columnList来自动生成字段下拉列表。作为高级查询,从易用的性和使用频率的角度功能所占UI比例不能太多,采用弹出窗口实现,如图:
这里的表格我使用了treegrid,因为更适合表达sql语法树,但没有实现树形结构,条件只加了大于、小于、包含等常用操作符,有待后续扩展sql嵌套。
右侧有查询历史,将每次查询的json条件保存在一个数组中实现快速重查,这个历史查询记录使用HTML5的localstorage保存在客户端缓存中,下次登录仍然有效,对于不支持localstorage的浏览器将使用cookie存储。
前后端交互:从到向前兼容性和对框架升级改动最小的因素考虑,将查询器组装的所有内容封装到一个json字符串,作为一个参数_sqlbuidler传递到后台,由后台控制条件组装,更加安全,防止sql注入等漏洞
json格式示例:
- [{“id”:101,”field”:”user_name”,”condition”:”like”,”value”:”%王%”,”relation”:”and”},{“id”:101,”field”:”user_name”,”condition”:”like”,”value”:”%王%”,”relation”:”and”}]
后台封装处理java对象QueryCondition
- package org.jeecgframework.web.demo.entity.test;
- import java.util.List;
- public class QueryCondition {
- String field;
- String type;
- String condition;
- String value;
- String relation;
- List<QueryCondition> children;
- public List<QueryCondition> getChildren() {
- return children;
- }
- public void setChildren(List<QueryCondition> children) {
- this.children = children;
- }
- public String getField() {
- return field;
- }
- public void setField(String field) {
- this.field = field;
- }
- public String getType() {
- return type;
- }
- public void setType(String type) {
- this.type = type;
- }
- public String getCondition() {
- return condition;
- }
- public void setCondition(String condition) {
- this.condition = condition;
- }
- public String getValue() {
- return value;
- }
- public void setValue(String value) {
- this.value = value;
- }
- public String getRelation() {
- return relation;
- }
- public void setRelation(String relation) {
- this.relation = relation;
- }
- public String toString(){
- StringBuffer sb =new StringBuffer();
- sb.append(this.relation).append(" ");
- sb.append(this.field).append(" ")
- .append(this.condition).append(" ");
- if("java.util.Date".equals(this.type)){
- sb.append("to_date('").append(this.value).append("','yyyy-MM-dd')");
- }else if("java.lang.Number".equals(this.type)
- ||this.condition.indexOf("in")>0){//TODO 需要按类型处理
- sb.append(this.value);
- }else{
- sb.append("'").append(this.value).append("'");//TODO 需要处理特殊字符
- }
- return sb.toString();
- }
- }
后台解析处理代码,修改org.jeecgframework.core.extend.hqlsearch.HqlGenerateUtil:
- public static void installHql(CriteriaQuery cq, Object searchObj,
- Map<String, String[]> parameterMap) {
- installHqlJoinAlias(cq, searchObj, getRuleMap(), parameterMap, "");
- // --增加一个特殊sql参数处理----------------------------------
- try{ if(StringUtil.isNotEmpty(parameterMap.get("_sqlbuilder"))){
- List<QueryCondition> list = JSONHelper.toList(
- parameterMap.get("_sqlbuilder")[0]
- , QueryCondition.class);
- String sql=getSql(list,"");
- System.out.println("DEBUG sqlbuilder:"+sql);
- cq.add(Restrictions.sqlRestriction(sql));
- }
- }catch(Exception e){
- e.printStackTrace();
- }
- // --增加一个特殊sql参数处理----------------------------------
- cq.add();
- }
5. 实现约束
- 只支持标准命名的表名,因为是通过java驼峰命名转换带下划线的数据库表名,如果表名不是这个规则字段名会转换错误;
- Sql前端界面在输入时并没有做太多约束和控制,因此非专业用户使用时会出现非法的语句而查询无果,建议在懂sql的人员指导下使用不要直接交给用户。
6. 标签使用
Datagrid标签中已经对高级查询器做了封装,js变量也根据每个模块的id做了命名处理防止冲突。
使用时只需在datagrid标签加一个属性queryBuilder="true",例如
- <t:datagrid name="jeecgDemoList" title="DEMO示例列表" autoLoadData="true" actionUrl="jeecgDemoController.do?datagrid" sortName="userName" fitColumns="true"
- idField="id" fit="true" queryMode="group" checkbox="true" queryBuilder="true">
模块UI效果如下,重置后面会多一个按钮:
7. TODO
UI方面:易用性还可以提升,比如选中某字段和条件=时,值自动根据数据库表中该列实际值枚举一部分候选项;字段为date类型时,值编辑框变成date控件;字段为整形时,值编辑框有校验或只能输入整数的spinbox来防呆
功能:List<QueryCondition>对象转换为sql getSql()函数中仅仅实现拼装原生sql,这块还有很大的改进空间,可以增加字段类型(int,string,date)的识别和处理、操作符(正则匹配)、内置表达式和函数(类似TFS)等扩展。
安全:模块按钮还没有跟权限绑定,只是通过标签属性来开关,应该加一个动态权限由系统配置来控制
【JEECG技术文档】Jeecg高级查询器的更多相关文章
- 【JEECG技术文档】JEECG高级查询构造器使用说明
功能介绍 高级查询构造器支持主子表联合查询,查询出更精确的数据. 要使用高级查询构造器需要完成以下步骤: 1. 在高级查询管理配置主子表信息. 2. 配置完后在JSP页面DataGrid标签上添加 ...
- 【JEECG技术文档】JEECG 接口权限开发及配置使用说明
1.功能介绍 通过接口配置实现,对接口的访问权限控制和数据权限控制,接口时REST接口,接口权限认证机制使用Json web token (JWT) 接口权限调用流程: (1)通过接口用户的用户名 ...
- 【JEECG技术文档】JEECG平台对外接口JWT应用文档V3.7.2
一. 接口方式 接口调用采用http协议,rest请求方式: 二. 接口安全 接口安全采用Json web token (JWT)机制,基于token的鉴权机制. 1. 机制说明 基于token的鉴权 ...
- 【JEECG技术文档】JEECG在线聊天插件功能集成文档
原文地址:http://jeecg.iteye.com/blog/2320670 JEECG在线聊天插件功能集成文档 前提: 采用jeecg_3.6.3版本以上(Maven工程) 插件项目: 在线聊天 ...
- 【JEECG技术文档】JEECG online 表单填值规则使用说明
1. 功能介绍 JEECG online规则值自动生成功能 为实现online表单数据初始化功能. 为实现图中红框字段初始化功能,需要完成下面4步操作: 1)编写规则实现类 2) 配置填值规则 3)o ...
- 【JEECG技术文档】Online唯一校验使用说明
1.功能介绍 配置了唯一校验的字段,在录入和编辑页面中,动态查询用户输入值是否存在校验. 要使用online唯一校验功能必须先在online表单开发中配置唯一字段的校验方式为唯一校验. 2.配置唯一校 ...
- 【JEECG技术文档】表单配置-树形表单
表单配置支持树型表单了,具体效果如下图: 配置说明: 1.是否树:选择是. 2.树形表单父Id:表的自关联外键. 3.树形表单列表:显示树形图标的列,如上图中为[组织机构名称]. 4.默认值:最外层数 ...
- 【JEECG技术文档】online自定义模板的使用
一. 业务背景 客户需要快速开发一个信息采集的功能模块,并使用已规划好的页面,实现个性化页面展示,使用标准左右布局的Table或DIV风格的页面表现力不强,不能满足客户的个性化页面需要 二. 需求 1 ...
- 【JEECG技术文档】JEECG 组织机构导入V3.7
1.功能介绍 组织机构导入 提供组织机构模版导入功能,使用户更快速的创建组织机构 要使用组织机构导入功能需要完成以下步骤: 1. 下载模版excel 2. 填写组织机构信息 3. 点击导入-选择文件- ...
随机推荐
- bzoj5006: [THUWC2017 Bipartite]随机二分图
某人在玩一个非常神奇的游戏.这个游戏中有一个左右各 nnn 个点的二分图,图中的边会按照一定的规律随机出现. 为了描述这些规律,某人将这些边分到若干个组中.每条边或者不属于任何组 (这样的边一定不会出 ...
- jquery插件的几种写法
/** * Created by peng on 2016/12/8. */jQuery.extend({ min: function(a, b) { return a < b ? a : b; ...
- HTML-Ronoob-基础教程:HTML 字符实体
ylbtech-HTML-Ronoob-基础教程:HTML 字符实体 1.返回顶部 1. HTML 中的预留字符必须被替换为字符实体. HTML 实体 在 HTML 中,某些字符是预留的. 在 HTM ...
- 云区域(region),可用区(AZ),跨区域数据复制(Cross-region replication)与灾备(Disaster Recovery)(部分1)
本文分两部分:部分1 和 部分2.部分1 介绍 AWS,部分2 介绍阿里云和OpenStack云. 1. AWS 1.1 AWS 地理组件概况 AWS 提供三种地理性组件: Regions:区域,即A ...
- get和post的解析
get 直接获取数据 post 将数据发送到服务端缓存下来,当无法缓存数据或用户输入未知字符时用post, get:常用于数据 post:不想缓存数据,不再浏览器中缓存数据,在服务端可以,因为取数据及 ...
- WireGuard协议介绍
原文: https://www.jianshu.com/p/32c3e62c2711
- Linux安装jsvc,及Linux服务开发
在linux上以服务的方式启动java程序,需要提前安装jsvc.linux是利用daemon(jsvc)构建java守护进程. 编译 daemon 安装JSVC 1 下载文件,http://comm ...
- 非mapreduce生成Hfile,然后导入hbase当中
转自:http://blog.csdn.net/stark_summer/article/details/44174381 未实验 最近一个群友的boss让研究hbase,让hbase的入库速度达到5 ...
- jQuery+html+css-自己写的分页
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- C#截取字符串按字节截取SubString
public static string CutByteString(string str,int len) { string result=string.Empty;// 最终返 ...