cms查询系统(一)背景以及需求分析与设计

本人想做一个cms查询框架,用于解决实际的业务问题,顺便锻炼下能力

1 背景介绍

在一个配置管理系统即cms系统中,有很多的实体,实体间有很多的关联关系,这些实体就是构建成了一张网。如下图所示: 

目前面临的问题是,如何轻松应对其他用户对实体的各种各样的查询需求?

2 需求整理

站在用户的角度来分析需求

2.1 用户的输入

2.1.1 用户要查询的数据

  • 可能只需要获取某些想要的字段
  • 可能想获取每个实体的所有字段

2.1.2 查询条件

  • 各种各样的查询条件,如

     如 =、 !=、>、<、like、in、exists 等查询条件,时间段查询等
    
  • 查询条件间的and or 关系,以及多层条件嵌套
    如 a>2 and (b>3 or c<4)
    

2.2 查询输出

2.2.1 字段对应的值的格式化

如某个表的type字段的值为0或1,需要将这些0或1转化成有意义的值,如 0表示online 1表示offline

2.2.2 返回的数据形式的格式化

sql查询的结果是平铺的形式,然而返回给用户的希望是一个格式良好的形式,所以要求必须具备格式化的功能。

目前可能的格式化形式如下所示:

  • 形式1 a下的所有的b(外层主体内容是a,然后包含一个b的集合)

    {
        "aName":"name1",
        "bs":[
            {
                "bName":"name2"
            },
            {
                "bName":"name3"
            }
        ]
    }
    
  • 形式2 b的信息(外层主体是b,然后包含一个a的信息)
    {
        "bName":"name2",
        "a":{
            "aName":"name1"
        }
    }
    
  • 形式3 a下所有的b、c(外层主体是a,然后包含一个b的集合,也包含一个c的集合)
    {
        "aName":"name1",
        "bs":[
            {
                "bName":"name2"
            },
            {
                "bName":"name3"
            }
        ],
        "cs":[
            {
                "cName":"name4"
            },
            {
                "cName":"name5"
            }
        ]
    }
    

3 大概的设计

  • 1 用户查询封装成QueryBody
  • 2 对QueryBody进行解析,解析成sql
  • 3 根据sql查询出对应的结果
  • 4 对sql查询的结果进行值的格式化和形式的格式化,返回满意的结果

3.1 用户查询封装成QueryBody

QueryBody就是配置用户需求的地方。它的来源有两种方式,分别如下:

  • 方式1 用户配置QueryBody的一些参数直接进行http请求

    这种方式的情况下,用户需要了解QueryBody的配置意义,同时用户可以自行进行各种各样的查询

  • 方式2 根据用户的查询需求,在后台配置QueryBody的参数,并映射对应的key,然后让用户拿着key来进行查询,如下
    {
        "key1":{QueryBody1的配置},
        "key2":{QueryBody2的配置}
    }
    

    用户拿着key1来查询,即我们使用key1对应的QueryBody配置来进行查询。这种方式,用户不需要关心QueryBody的配置,但只能按照我们后台所配置的参数进行查询了。方式1就不需要维护信息,方式2就需要维护key对应的QueryBody的配置信息

以上的这两种方式都可能会出现,所以都要支持。

3.2 对QueryBody进行解析,解析成sql

这一部分其实就是一个sql生成器。这里需要说明的是,我们并不是去设计一个复杂的sql生成器,而是针对cms系统常见的查询操作能够生成sql就行了。所以不要指望这个查询框架能自动帮你生成复杂的sql。 但是有很多地方要注意:

3.2.1 对解析要进行缓存

方便下一次相同的请求直接跳过解析过程,加快搜索。然而一旦服务器关闭,缓存就消失,所以是否要考虑将解析缓存持久化起来,在服务器启动的时候,就去先加载解析缓存。

同时允许清空缓存等操作

3.2.2 普通查询sql的几个要素

普通sql如下所示:

select 表1.column_a,表1.column_b,表2.column_c,表3.column_d
from  表1 表2 表3
where 表1.column_e>4 and 表2.column_f='test'

主要分成三大部分:

  • 第一部分 要查询的column

    这一部分,可以让用户自己输入,还要进行下配置映射,避免对外暴漏数据库中的表和字段名

    上述方式一般很少,所以大部分的时候还是,查询表1 表2 表3 的全部有用字段的信息,所以需要在后台配置哪些表的哪些字段需要对外暴漏。

    上面的两种方式也都是要支持的

  • 第二部分 表之间的连接关系

    一种方式就是,直接配置表与表之间的连接关系(简单粗暴,但是会有很多的重复配置信息)

    另一种方式就是,只配置两两表之间的连接关系,通过一个针对图的算法模块来找到表之间的连接关系。如博客开头的图片中,算法模块能够自动计算出entity1和entity4之间的连接关系是 entity1->entity2->entity3->entity4。这种方式大大减少了配置的冗余度。

    虽然算法这一块是美好的,仍然会存在很多的问题。算法要找出最短路径,但是最短路径的连接关系不一定是用户想要的,所以有时候又不能来依靠算法,还需要人为的干预配置。如上图中的entity1到entity7有2条途径,算法只能给我们推荐一个最短的路径,但这并不一定是用户想要的,所以在这个时候,我们是需要配置使用哪条路径的

  • 第三部分 查询参数部分

    用户的查询条件就是一个json对象,我们要把这个json对象转化成sql中的where部分

    用户的查询条件是各种各样的,同时查询条件是可以嵌套的,如下两种查询条件

    {
        "a.name":"lg",
        "b.age@>":24
    }
    

    这里就表示查询 where a.name='lg' and b.age>24

    {
        "a.name":"lg",
        "$or":{
            "b.age@>":24,
            "c.id@in":[1,2,3]
        }
    }
    

    这里就表示查询 where a.name='lg' and (b.age>24 or c.id in (1,2,3) )

    所以希望能够做到上述的查询效果,这就需要设计一系列内置的查询参数解析器,同时方便用户自定义扩展查询参数解析器,来支持更加复杂的查询

3.3 根据sql查询出对应的结果

这一块就需要借助于如Spring的JdbcTemplate来执行相应的sql,或者借助于其他,这就需要思考如何更加方便的接入呢?

3.4 对sql查询的结果进行值的格式化和形式的格式化,返回满意的结果

sql的查询结果是平铺的,这时候就需要进行聚合操作,聚合操作就需要依据外层实体的主键作为聚合的重要依据了。

对数据进行格式化处理,就需要遍历查询结果,一一进行处理。然后返回给用户,如果用户还要进行相应的处理操作,又要遍历一次,造成浪费,所以该框架还要支持用户配置一些处理操作。

4 还涉及的问题

4.1 日志

  • 该框架应该不能定死所使用的日志系统,所以需要采用slf4j这个统一的日志接口
  • 对于程序中哪部分的日志采用debug级别,哪部分的日志采用info级别需要仔细考量。简单来说就是,程序的主要执行过程采用info级别,使得我们能够迅速定位错误原因就可以了,而一些详细的解析过程采用debug级别就够了。

4.2 配置文件的监控模块

为了不用重启服务器,就能方便的发布新的API、或者改动老的API,就需要对这些配置文件进行监控。

因为这些各种各样的配置文件会很多,所以就需要把监控单独写成一个模块,方便外界随意的添加监控项。

同时还需要监控的总开关和每个监控项的子开关,来随时关闭或者打开某个监控项。

4.3 上下文环境Context

在解析的过程中,用户的查询QueryBody,会在很多地方都要用到,如果都是作为方法的参数传递来传递去,将非常难看和难以维护,很明显这里就需要用到ThreadLocal形式了,将类似QueryBody和一些对应的缓存存储到绑定的对应的线程中,通过ThreadLocal对象来随时随地获取这些数据。最好是弄一个上下文环境来封装数据。

4.4 异常处理

配置文件加载、解析产生的异常要进行规范的自定义处理

4.5 集成与配置

如何更加方便的使用与配置这个cms查询框架

5 最终达成的效果

还是如文章最上面的图

1 用户输入如下:

{
    "entites":["entity1","entity2s@listentity2","entity3s@listentity3"],
    "params":{
        这里放置查询参数
    }
}

则代表查询的是所有的entity1,以及它所包含的entity2和entity3,返回的数据格式是如下形式的:

{
    "entity1Name":"aaa",
    "entity2s":[
        {"entity2Name":"xxx"},
        {"entity2Name":"xxx"}
    ],
    "entity3s":[
        {"entity3Name":"xxx"}
    ]
}

2 如果用户输入如下:

{
    "entites":["entity2","entity1@mapentity1"],
    "params":{
        这里放置查询参数
    }
}

则表示用户想查询entity2的信息,并且想知道每个entity2所属的entity1信息,是如下格式的:

{
    "entity2Name":"aaa",
    "entity1":{
        "entity1Name":"xxx"
    }
}
时间: 2024-09-13 17:17:44

cms查询系统(一)背景以及需求分析与设计的相关文章

cms查询系统(三)查询demo体验

安装相应的jar包到maven仓库 安装2个项目 有2个项目的jar包需要安装,分别是: search-sqlparams-1.3.0.jar 主要用于查询参数的解析 search-core-1.3.0.jar 整体的查询流程体系,需要使用上述参数解析包 上述两个项目地址分别如下: search-sqlparams search-core 以search-sqlparams-1.3.0.jar为例来说下安装步骤: 第一步:fork search-sqlparams 项目(这两个项目都是maven

cms查询系统(二)json形式参数的设计与解析

1 前言 本篇文章主要来说明下代码模块的设计.像我们这种菜鸟级别,只有平时多读读源码,多研究和探讨其中的设计才可能提升自己,写出高质量的代码. 没有最好的设计,只有更好的设计,所以在发表我自己的愚见的同时,希望小伙伴们相互探讨更好的设计,有探讨才有更大的进步. 2 题目及分析 我们维护了一个数据中心,对外提供查询API,如何能让用户随意的添加查询条件,而不用修改后台的查询代码呢?用户如何配置查询条件,从而达到如下的sql效果呢?: a.name='lg' or b.age>12 b.id in

【百度地图API】建立全国银行位置查询系统(三)——如何在地图上添加银行标注

原文:[百度地图API]建立全国银行位置查询系统(三)--如何在地图上添加银行标注 <摘要>你将在第三章中学会以下知识: 如何在地图上添加带银行logo的标注?(你也可以换成商场logo,酒店logo等) 如何在标注上显示信息窗口,以及添加文字标签等其他覆盖物: 最后,介绍一个获取坐标的给力工具. ---------------------------------------------------------------------------------------------------

新闻出版总署将推出网游家长查询系统

本报记者 赵海霞 对于家长而言,学生放假既让他们感到开心,也让他们感到担忧.开心的自然是孩子可以在此期间放松一下,担忧的是摆脱了紧张的学习后,孩子又会将注意目标转向网络,这让家长对孩子的网游消费着实担心.如何找到一种安心的方法,把钱消费在刀刃上呢? 日前,从2010年年度中国游戏产业年会上传来好消息:新闻出版总署将推出网游家长查询系统,依法促进家长有效履行监护人责任,防止未成年人沉迷网络游戏.尽管这是个好消息,但这套查询系统将如何帮助家长不让孩子沉迷网络?孩子的"网瘾"问题能否得到根治

网游家长查询系统将推出根治网瘾还需联动

对于家长而言,学生放假既让他们感到开心,也让他们感到担忧.开心的自然是孩子可以在此期间放松一下,担忧的是摆脱了紧张的学习后,孩子又会将注意目标转向网络,这让家长对孩子的网游消费着实担心.如何找到一种安心的方法,把钱消费在刀刃上呢? 日前,从2010年年度中国游戏产业年会上传来好消息:新闻出版总署将推出网游家长查询系统,依法促进家长有效履行监护人责任,防止未成年人沉迷网络游戏.尽管这是个好消息,但这套查询系统将如何帮助家长不让孩子沉迷网络?孩子的"网瘾"问题能否得到根治?这还需要多方联动

PHP+AJAX实现的国际域名查询系统开发实例教程

PHP+AJAX 域名查询预备知识 本查询系统利用 PHP 和 JQUery 的 Ajax 功能实现了对域名信息的查询(这里主要实现了域名是否已经注册的查询).系统主要用到了万网提供的域名查询 API 接口,相关知识点罗列如下:     JQUery Ajax 的实现:这部分内容具体可以参见 JQuery API 文档或本站即将推出的<JQUery 教程>.     file_get_contents 函数:把整个文件读入一个字符串,这里用于读取一个网页(万网 API 返回结果页面).    

政府部门多媒体查询系统解决方案

信息技术的发展,特别是网络技术的发展,正在改变着人们几千年来形成的信息传递方式.人际间的沟通方式和社会管理的组织方式,并深刻地影响着社会生活和政府的运作.利用多媒体查询系统,可以在政府.社会和公众之间之间建立一个良好的沟通渠道. 软件目的 政府部分多媒体查询系统主要介绍政府.宣传政策法规知识:充实政府办公大厅的服务功能:满足群众对政府机关多层次,多样化的需求:联结政府部门和广大群众的纽带:提高政府机关整体形象:减少群众对工作人员的询问,提高工作效率. 本系统是一个集政府部门介绍.办事程序以及各项

用Dreamweaver MX建立一个简单的图书查询系统

dreamweaver|查询系统 最近公司为了充分利用图书资源,方便员工查询,决定在公司内部网上建立一个图书查询系统.考虑到公司图书不多,只有1千多册,且专业书居多的特点,我决定做两个查询条件:一个是根据图书类别来查询,用户只要选择相应的类别就可以显示出该类别的所有图书,这主要是面对对公司图书不熟悉的人:第二个是根据图书名称来查询,用户只要输入图书名,就可以快速的搜索到符合条件的所有图书. 方案已定,接下来就是用什么软件做及如何做的问题了.在这里,我选用了网页的形式,这样同事们只要打开浏览器,输

DreamWeaver打造Web查询系统(3)

dreamweaver|web|查询系统 二.将 index.asp 转换为动态页面 从本小节开始,我们逐步将前面建立的静态页面转换为动态页面,使其和数据库相结合,以完成我们最终的页面. 首先我们要把首页转换为动态页面.在首页中,仅有右侧的"超值推荐"部分需要从数据库中读取数据,因此,我们的目的是从数据库中的 tele 表中读取 Is_Good 字段值为1的记录并按降序显示就可以了. ok,开始工作.第1步,建立数据集.在绑定面板,选择 记录集(查询) 菜单,并在对话框内根据图 6-5