這是標準數據庫封裝的上半部分,智能查詢(JSON-ORM)的實現。完整代碼:https://github.com/zhoutk/gels前端
咱們通用的ORM,基本模式都是想要脫離數據庫的,幾乎都在編程語言層面創建模型,由程序去與數據庫打交道。雖然脫離了數據庫的具體操做,但咱們要創建各類模型文檔,用代碼去寫表之間的關係等等操做,讓初學者一時如墜雲霧。個人想法是,將關係數據庫擁有的完善設計工具之優點與微服務結合起來,數據設計提供結構信息;前端送到後端的json對象自動映射成爲標準的SQL查詢語句。只要咱們理解了標準的SQL語言,咱們就可以完成數據庫查詢操做。個人這種ORM方式,服務端不須要寫一行代碼,只需完成關係數據庫的設計,就能爲前端提供標準服務接口。而且遵循一套統一的接口(已經實踐檢驗,知足百分之九九的查詢需求)來實現數據庫封裝,達到業務層能夠隨意切換數據庫的目的。node
export default interface IDao { select(tablename: string, params: object, fields?: Array<string>): Promise<any>; //自動生成sql語句 execSql(sql: string, values: Array<any>, params: object, fields?: Array<string>): Promise<any>; //執行手動sql語句 }
查詢保留字:fields, page, size, sort, search, lks, ins, ors, count, sum, group
fields, 定義查詢結果字段,支持數組和逗號分隔字符串兩種形式
由前端來肯定返回的數據庫字段信息,這樣後端的設計能夠適用面更普遍,而不會形成網絡帶寬的浪費。
在KOA2的框架下,GET請求要支持輸入數組,只能把同一個key屢次輸入,如:age=11&age=22。這樣很不方便,我實現了一個參數轉換函數,針對數組提供多種輸入形式。
arryParsemysql
arryParse(arr): Array<any>|null { //返回值爲數據或空值 try { if (Array.isArray(arr) || G.L.isNull(arr)) { //若是輸入是數組或空,直接返回 return arr } else if (typeof arr === 'string') { //如果字符串 if (arr.startsWith('[')) { //數組的字符串形式,進行轉換 arr = JSON.parse(arr) } else { //逗號拼接的字符串,mysql的驅動同時支持參數以字符串形式或數組形式提供, //因此這裏能夠不加判斷,直接用split函數將字符串轉化爲數組 arr = arr.split(',') } } } catch (err) { arr = null //數組的字符串形式轉換失敗,劉明輸入參數是錯誤的 } return arr }
查詢示例:git
請求URL: /rs/users?username=white&age=22&fields=["username","age"] 生成sql: SELECT username,age FROM users WHERE username = ? and age = ?
page, size, sort, 分頁排序
在mysql中這比較好實現,limit來分頁是很方便的,排序只需將參數直接拼接到order by後就行了。
查詢示例:github
請求URL: /rs/users?page=1&size=10&sort=age desc 生成sql: SELECT * FROM users ORDER BY age desc LIMIT 0,10
search, 模糊查詢切換參數,不提供時爲精確匹配
提供字段查詢的精確匹配與模糊匹配的切換,實現過程當中,注意參數化送入參數時,like匹配,是要在參數兩邊加%,而不是在佔位符兩邊加%。
另外,同一個字段匹配兩次模糊查詢,須要特別處理,我提供了一種巧妙的方法:sql
//將值用escape編碼,數組將轉化爲逗號鏈接的字符串,用正則全局替換,變成and鏈接 value = pool.escape(value).replace(/\', \'/g, "%' and " + key + " like '%") //去掉兩頭多餘的引號 value = value.substring(1, value.length - 1) //補齊條件查詢語句,這種方式,比用循環處理來得快捷,它統一了數組與其它形式的處理方式 where += key + " like '%" + value + "%'"
查詢示例typescript
請求URL: /rs/users?username=i&password=1&search
ins, lks, ors
這是最重要的三種查詢方式,如何找出它們之間的共同點,減小冗餘代碼是關鍵。數據庫
ins, 數據庫表單字段in查詢,一字段對多個值,例:
查詢示例:編程
請求URL: /rs/users?ins=["age",11,22,26] 生成sql: SELECT * FROM users WHERE age in ( ? )
ors, 數據庫表多字段精確查詢,or鏈接,多個字段對多個值,支持null值查詢,例:
查詢示例:json
請求URL: /rs/users?ors=["age",1,"age",22,"password",null] 生成sql: SELECT * FROM users WHERE ( age = ? or age = ? or password is null )
lks, 數據庫表多字段模糊查詢,or鏈接,多個字段對多個值,支持null值查詢,例:
查詢示例:
請求URL: /rs/users?lks=["username","i","password",null] 生成sql: SELECT * FROM users WHERE ( username like ? or password is null )
count, sum
這兩個統計求和,處理方式也相似,查詢時通常要配合group與fields使用。
count, 數據庫查詢函數count,行統計,例:
查詢示例:
請求URL: /rs/users?count=["1","total"]&fields=["username"] 生成sql: SELECT username,count(1) as total FROM users
sum, 數據庫查詢函數sum,字段求和,例:
查詢示例:
請求URL: /rs/users?sum=["age","ageSum"]&fields=["username"]
group, 數據庫分組函數group,例:
查詢示例:
請求URL: /rs/users?group=age&count=["*","total"]&fields=["age"] 生成sql: SELECT age,count(*) as total FROM users GROUP BY age
不等操做符查詢支持
支持的不等操做符有:>, >=, <, <=, <>, =;逗號符爲分隔符,一個字段支持一或二個操做。
特殊處:使用"="可使某個字段跳過search影響,讓模糊匹配與精確匹配同時出如今一個查詢語句中
一個字段一個操做,示例:
查詢示例:
請求URL: /rs/users?age=>,10 生成sql: SELECT * FROM users WHERE age> ?
一個字段二個操做,示例:
查詢示例:
請求URL: /rs/users?age=>,10,<=,35 生成sql: SELECT * FROM users WHERE age> ? and age<= ?
使用"="去除字段的search影響,示例:
查詢示例:
請求URL: /rs/users?age==,22&username=i&search 生成sql: SELECT * FROM users WHERE age= ? and username like ?
運用typescript進行node.js後端開發精要
nodejs實戰之智能微服務快速開發框架
JSON-ORM(對象關係映射)設計與實現
凝膠(gels)項目: https://github.com/zhoutk/gels
視頻講座資料: https://github.com/zhoutk/sifou
我的博客: https://segmentfault.com/blog...