node js 各類數(shù)據(jù)庫(kù)常用方法封裝的、心路歷程廊宪、矾瘾、

這是我寫出access-db方法庫(kù)所經(jīng)歷的一個(gè)過程,在這里記錄下吧

想法的誕生

小公司的發(fā)展本來就不易箭启,成本方面壕翩,是能有多節(jié)約就多節(jié)約。有時(shí)多個(gè)人干的事轉(zhuǎn)由一個(gè)人干傅寡,也是毫不奇怪
放妈。也是在這種情況下北救,我慢慢的成了全棧開發(fā)。

最初為了省錢芜抒,外加我們只做小程序扭倾,就選擇了第三方云服務(wù)商作為后臺(tái)。剛開始還好挽绩,后面久了膛壹,發(fā)現(xiàn)他們提供的接口方法使用起來并沒有想像的那么輕松。特別是在復(fù)雜查尋的情況下唉堪,代碼太過復(fù)雜模聋,不易讀,修改起來也不方便唠亚。于是我就開始思考怎么去簡(jiǎn)化他的查尋链方。下面這個(gè)查尋方法,就是封裝的最初版灶搜,可以看到祟蚀,fetchFindByCheck使用起來也并不是那么的簡(jiǎn)單,并且割卖,它還只能支持最簡(jiǎn)單的and前酿,or查尋近零,代碼的可讀性和靈活性都不高傻咖。

fetchFindByCheck({
  tableName: app.table.active_sign,
  relationship: ['and', 'and'],
  way: ['in', 'compare', 'compare'],
  params: [
    { key: 'child_id', value: childID },
    { key: 'active_id', operator: '=', value: that.aid },
    { key: 'is_delete', operator: '=', value: false },
  ],
  limit: 30,
  page: 1,
  order_by: '-created_at',
  expand: [],
}).then((res2) => {
  let tempJoined = res2.data.objects
  console.log('tempJoin', tempJoined)
},(err)=>{})

但即使如此,我還是封裝了一套最簡(jiǎn)單的方法空闲。

minapp-fetch 出現(xiàn)

用過云服務(wù)的肯定都知道丙挽,云服務(wù)有很多類別的接口肺孵。就比如微信云開發(fā),它會(huì)提供小程序端的接口颜阐、云函數(shù)的接口平窘、甚至web接口。我們選擇的云服務(wù)商凳怨,剛開始用得還好瑰艘,后面由于業(yè)務(wù)多樣化,我們又面臨不得不使用web的情況猿棉。而且磅叛,云服務(wù)商提供的web接口也和小程序上面的調(diào)用方式不一樣,就導(dǎo)致即使同樣的查尋萨赁,也要寫兩套不同的查尋方法弊琴。如果你還要用他的云函數(shù)、或者其他端的api杖爽,那更是讓你頭大敲董。

怎么辦呢紫皇?為了減輕開發(fā)和維護(hù)難度,提高開發(fā)效率腋寨。我產(chǎn)生了一個(gè)大膽的想法:要是能把各個(gè)端的接口都統(tǒng)一成一種聪铺,那不就很簡(jiǎn)單了嗎。想法是好的萄窜,但實(shí)現(xiàn)起來就沒那么容易了铃剔。最初在寫web端的接口時(shí),我好幾次都想放棄查刻,感覺把這些不同的寫法,統(tǒng)一成一種穗泵,真的是有點(diǎn)難普气。因?yàn)槟悴坏M可能的保證同一種增刪改查,在不同端得到的結(jié)果是一樣的佃延,還要通過算法现诀,保證封裝的方法盡可能的簡(jiǎn)單。

經(jīng)過一段時(shí)間的奮斗履肃,方法終于出來了仔沿,這個(gè)時(shí)候,我給它取了一個(gè)名字榆浓,叫做 minapp-fetch 于未,現(xiàn)在也發(fā)布在了npm上,但它只支持我們使用過的云服務(wù)商的api陡鹃。它的寫法更加簡(jiǎn)潔,如下:

fetchFind(app.table.question, {
  p1: {
    way: 'compare',
    data: ['status', '>', 0]
  },
  p2: {
    way: 'compare',
    data: ['is_admin_answered', '=', false]
  },
  p3: {
    way: 'compare',
    data: ['is_admin_read', '=', false]
  },
  r: 'p1 && (p2 || p3)',
  page: commen.page,
  limit: commen.limit,
  order_by: '-created_at',
  expand: ['created_by']
})

其中抖坪,p參數(shù)為每一個(gè)小條件萍鲸,r為小條件的and、or擦俐,page為翻頁脊阴,limit為每頁數(shù)量,order_by為排序蚯瞧。雖然此時(shí)看著是比較清晰了嘿期,但它還是有不足的地方。首先埋合,p條件寫法备徐,還是有些繁瑣;其次甚颂,就是r規(guī)則里面蜜猾,不支持括號(hào)嵌套秀菱;再就是,它支持的方法也不多蹭睡。

面對(duì)上面的種種問題衍菱,當(dāng)然是解決了。經(jīng)過后面的努力肩豁,minapp-fetch才有了現(xiàn)在的寫法:
其中脊串,p參數(shù)對(duì)應(yīng)的定義是這樣的:p*: ['字段', '查尋方法', '查尋內(nèi)容'],數(shù)組第一個(gè)參數(shù)為表里的字段清钥,第二個(gè)參數(shù)為查尋方法琼锋,第三個(gè)參數(shù)及后面的,就是查尋的內(nèi)容循捺。

let rule = 'p3 || p7'

minapp.find(table, {
  p1: ['cat_label1', 'in', userChannels=[]],
  p2: ['cat_label2', 'stringLength', 23], //查尋字符串長(zhǎng)度為23的
  p4: ['cat_label2', 'stringLength', 23, 100], //查尋字符串長(zhǎng)度在23到100的
  p3: ['id', 'notIn', history],
  p7: ['status', '=', 20],
  p8: ['name', 'matches', /^foo/i],
  p15: ['geo_point', 'include', [15, 15]], //坐標(biāo)點(diǎn)斩例,經(jīng)緯[longitude, latitude]
  p21: ['geo_point', 'withinCircle', [15, 15], r], //r 單位 km
  p23: ['geo_point', 'withinRegion', [15, 15], max_r], //max_r, min_r 單位為 m
  p28: ['geo_point', 'within', [0, 0], [6, 0], [6, 9], [0, 9], [0, 0]], //坐標(biāo)點(diǎn)集,首點(diǎn)=尾點(diǎn)从橘,經(jīng)緯[longitude, latitude]
  p63: ['content', 'isNull', true],
  p93: ['content', 'isExists', false],

  r: isSelect ? rule : '(p1 && (p2 || p3)) && (p57 && p93)',
  page: 1, //默認(rèn)值
  limit: 20, //默認(rèn)值
  orderBy: '-created_at', //默認(rèn)值
  expand: [], //默認(rèn)值
  select: [], //默認(rèn)值
  withCount: false, //默認(rèn)值
})

可以看到念赶,上面的find方法,已經(jīng)相當(dāng)復(fù)雜了恰力,但它給人的感覺叉谜,還是很清。你甚至可以隨意更換r規(guī)則踩萎,進(jìn)行不同情況的查尋停局。(查尋最終是按r規(guī)則來的)

access-db 出現(xiàn)

再后來,由于云服務(wù)商的一些不足香府,外加我們自己也對(duì)業(yè)務(wù)靈活性有更多要求董栽,所以決定自己寫后臺(tái)了。慢慢的企孩,我們逐漸開始放棄云服務(wù)商锭碳,自己開發(fā)。此時(shí)問題也來了勿璃,數(shù)據(jù)庫(kù)的連接各不相同擒抛,習(xí)慣了minapp-fetch寫法的我,再去單獨(dú)用數(shù)據(jù)庫(kù)的連接方法补疑,感覺確實(shí)不習(xí)慣歧沪。并且,不同類型的數(shù)據(jù)庫(kù)莲组,方法也不一樣诊胞,維護(hù)和轉(zhuǎn)化,成了一大難題胁编。你肯定也猜到了厢钧,沒錯(cuò)鳞尔,就是把數(shù)據(jù)庫(kù)的連接,也封裝起來早直!

從node.js最火的非關(guān)系型數(shù)據(jù)庫(kù)mongodb入手寥假,開始了數(shù)據(jù)庫(kù)方法封裝的旅程。說實(shí)在的霞扬,mongodb的基本方法和之前云服務(wù)商的webapi很相似糕韧,也沒費(fèi)太多的功夫就完成了常用方法的封裝。但后面加入第二個(gè)數(shù)據(jù)庫(kù)mysql時(shí)喻圃,問題就來了萤彩。因?yàn)?code>mysql是sql語句進(jìn)行查尋的,和之前的完全不一樣斧拍。也就是說雀扶,必須要通過算法,將封裝的寫法肆汹,轉(zhuǎn)換成sql語句愚墓。你可能會(huì)覺得,應(yīng)該不復(fù)雜昂勉,就是一個(gè)簡(jiǎn)單的組成字符串而已浪册。當(dāng)初我也是這么認(rèn)為的,但當(dāng)我開始入手研發(fā)時(shí)岗照,才發(fā)現(xiàn)村象,問題遠(yuǎn)比這個(gè)復(fù)雜。對(duì)mysql了解的同學(xué)應(yīng)該知道攒至,sql語句可以重命名厚者、可以連表查尋、可以嵌套查詢迫吐、聚合查尋等籍救,并且為了使查尋正確,往往還要對(duì)表和字段進(jìn)行更名渠抹,再引用等等,這些問題就使得轉(zhuǎn)化難度大大提高了闪萄∥嗳矗可能有時(shí)候,你滿足了其中一種查尋败去,卻讓另一種查尋出了問題放航。但為了平時(shí)開發(fā)得更爽,更高效圆裕;我還是硬著頭皮去實(shí)現(xiàn)它广鳍。

經(jīng)過一段時(shí)間的苦熬荆几,她終于開始有個(gè)樣子了,我又重新發(fā)了一個(gè)npm包赊时,給了她一個(gè)全新的名字:access-db吨铸,至此,你甚至可以同時(shí)引用多種數(shù)據(jù)庫(kù)祖秒,進(jìn)行關(guān)聯(lián)使用:

import {mysql, mongodb, fastdb} from 'access-db'

async function exp() {
  let {data} = await mongodb.get('table11', id)
  
  await mysql.find('table2', {
    p0: ['num', '=', data.num],
    r: 'p0'
  })
}

因?yàn)槊恳环N數(shù)據(jù)庫(kù)诞吱,都有自己的特點(diǎn),所以竭缝,封裝的方法里面房维,肯定會(huì)有個(gè)體差異,這也無法避免抬纸。

Fastdb 出現(xiàn)

細(xì)心的同學(xué)可能發(fā)現(xiàn)了上面的代碼中咙俩,引入了一種新的數(shù)據(jù)庫(kù)fastdb,是的湿故,它是access-db內(nèi)置的阿趁,本地json數(shù)據(jù)庫(kù)。也是我發(fā)現(xiàn)有類似的本地?cái)?shù)據(jù)庫(kù)后晓锻,自己開發(fā)的歌焦。它的優(yōu)點(diǎn)就是,完全使用access-db語法進(jìn)行增刪改查砚哆,同時(shí)独撇,不需要你安裝任何額外數(shù)據(jù)庫(kù),直接可以用躁锁,很方便纷铣。缺點(diǎn)也很明顯,存儲(chǔ)的形式是json文件战转,沒有數(shù)據(jù)庫(kù)密碼這些搜立,不安全,數(shù)據(jù)量大了槐秧,查尋效率也不是那么高啄踊。

結(jié)語

我希望通過記錄自己的這些經(jīng)歷,能帶給你些啟發(fā)或共鳴刁标。我不是什么大神颠通,可能你也不是,但只要自己不停下思考的腳步膀懈,并勇于去實(shí)現(xiàn)它顿锰,那你也一定能做出有意義東西出來!

將這個(gè)方法庫(kù),獻(xiàn)給那些需要的朋友:
access-db包
access-db文檔

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末硼控,一起剝皮案震驚了整個(gè)濱河市刘陶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌牢撼,老刑警劉巖匙隔,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異浪默,居然都是意外死亡牡直,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門纳决,熙熙樓的掌柜王于貴愁眉苦臉地迎上來碰逸,“玉大人,你說我怎么就攤上這事阔加《罚” “怎么了?”我有些...
    開封第一講書人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵胜榔,是天一觀的道長(zhǎng)胳喷。 經(jīng)常有香客問我,道長(zhǎng)夭织,這世上最難降的妖魔是什么吭露? 我笑而不...
    開封第一講書人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮尊惰,結(jié)果婚禮上讲竿,老公的妹妹穿的比我還像新娘。我一直安慰自己弄屡,他們只是感情好题禀,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著膀捷,像睡著了一般迈嘹。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上全庸,一...
    開封第一講書人閱讀 51,443評(píng)論 1 302
  • 那天秀仲,我揣著相機(jī)與錄音,去河邊找鬼壶笼。 笑死啄育,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的拌消。 我是一名探鬼主播,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼墩崩!你這毒婦竟也來了氓英?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤鹦筹,失蹤者是張志新(化名)和其女友劉穎铝阐,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體铐拐,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡徘键,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了遍蟋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吹害。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖虚青,靈堂內(nèi)的尸體忽然破棺而出它呀,到底是詐尸還是另有隱情,我是刑警寧澤棒厘,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布纵穿,位于F島的核電站,受9級(jí)特大地震影響奢人,放射性物質(zhì)發(fā)生泄漏谓媒。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一何乎、第九天 我趴在偏房一處隱蔽的房頂上張望句惯。 院中可真熱鬧,春花似錦宪赶、人聲如沸宗弯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蒙保。三九已至,卻和暖如春欲主,著一層夾襖步出監(jiān)牢的瞬間邓厕,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工扁瓢, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留详恼,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓引几,卻偏偏與公主長(zhǎng)得像昧互,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容