1. 程式人生 > 其它 >裡面如何建立新的module_如何實現一個簡易的orm

裡面如何建立新的module_如何實現一個簡易的orm

技術標籤:裡面如何建立新的module

什麼是orm?

ORM 就是通過例項物件的語法,完成關係型資料庫的操作的技術,是"物件-關係對映"(Object/Relational Mapping) 的縮寫。不負責任的總結就是通過類似物件管理的模式,來管理資料庫,來避免直接操作資料庫,降低資料庫的學習成本。

如果還是不懂? 可以直接看看阮一峰的這篇文章 ORM例項教程

現有基於Node的ORM

  • sequelize
  • openrecord

為什麼要造輪子?

  • 瞭解某些語法是怎樣實現的
  • 鞏固基礎
  • 構造自己更滿意的語法糖
  • 好玩

所以這篇文章比較適合有這些相同想法的同學閱讀,並且整篇文章會比較基礎,大佬們可以在這裡止步了。

功能設計

要實現一個功能庫,首先我們得設計我們有哪些功能,回憶下大學資料庫課程裡面的那幾個大流程,我們要做的也不盡相同。

  • 連線

連線

連線當然是我們orm的最基礎的功能,所以我們設計如下:

module.exports.connect = config => {
    // create sql pool connect
}

一個對外暴露的config, 本質上就是將建立連線池所需引數對外再暴露一次,並且加上一些自己想要定製的引數即可。

比如我這裡是有個debug模式,開啟後會輸出所有執行的sql語句,當然你也可以再這裡埋一些callback,用於實現獲取記錄日誌的能力。

{
    limit:          : 10,
    host            : '127.0.0.1',
    port            : '3306',
    user            : 'root',
    password        : 'root',
    database        : 'test',
    debug           : true
}

具體連線池怎麼建立的就不說了,看看mysql的文件就行了,唯一要記得就是用單例模式建立連線,每次sql操作結束後記得釋放connect就行

增,刪,改,查

說白了這4個就是我們最核心的操作,但是如何設計呢?

看看相關的orm庫就知道了,每張表都看成一個物件,增刪改查是他的屬性方法,所以既然是orm,我們當然要把他設計成物件的操作模式,如下:

module.exports.model = data => {
  // return new instance
}
const student = orm.model(data)

我們在model 函式初始化時會給它傳一些引數,比如表名,狀態,表字段,主鍵欄位等,讓他初始化的時候可以儲存起來,最後再返回一個新的例項,比如下面這樣:

const student = orm.model('student', {
  name: String,
  sex: Number
})

然後model上就會有很多我們想要的屬性方法,並且每一類方法都對應一類sql,這樣就可以實現我們的增,刪,改,查了。

student.create()
student.find()
student.where()
student.update()
student.delete()

// create sql demo
create(data) {
    const keys = Object.keys(data).join(',')
    const values = Object.values(data).map(d => escape(d)).join(',')
    const SQL = `insert into ${table} (${keys}) VALUES (${values})`
}

結束或許是新的開始

到這裡大家根據上面的虛擬碼,應該可以建立一個最基礎的偽orm,勉勉強強的可以滿足你大部分基礎操作(當然我相信你在整合這些方法的時候一定會踩更多的坑,如果需要幫助可以看看我的實現)。

這裡再回到我們之前提的“為什麼要造輪子”,上面介紹的只是一些實現的大致流程和基礎的回顧。

但是如何構造我們更滿意的語法糖?如何更好玩?

比如下面的程式碼:

(async () => {
  console.log(await orm.Model('Post')) // 獲取到post表的資料
  console.log(await orm.Model('Post').find(1)) // 獲取到post表裡id=1的資料
})()

所以在最後丟擲一個問題,如何實現上述的這種類似惰性的鏈式呼叫功能?

下面是我的實現方案:

yuanhaoyu/h-orm​github.com db92561ff36e5337e885ed59dd0b45ff.png