cms查询系统(一)背景以及需求分析与设计
2019獨角獸企業重金招聘Python工程師標準>>>
本人想做一個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"} }轉載于:https://my.oschina.net/pingpangkuangmo/blog/391837
總結
以上是生活随笔為你收集整理的cms查询系统(一)背景以及需求分析与设计的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 进程内COM与进程外COM
- 下一篇: 高端手机市场,拼配置还是拼安全