輕量級orm框架——gzero指南

冷豪發表於2022-01-22

開發過web系統人一定對大量的curd不陌生,為了提高效率我們通常會使用一些orm框架做輔助,而不會直接運算元據庫。但是現有的orm框架往往有兩個通病(各種語言的都一樣):1. API複雜:即使是有經驗的開發人員在使用前還是需要先寫出原始的SQL語句,再呼叫api。效率不高,排查問題也不夠透明。如果使用原生SQL,通常就需要自己再寫程式碼來處理結果集。2. 使用orm框架對資料庫的操作粒度比較粗,有時候為了提高資料庫的查詢效率,明明一條語句能夠完成的工作,通過框架會傳送多條語句。這樣也無形中增加了系統的負載,降低了系統的併發吞吐量。

所謂我才想能夠自己做一個框架,既能夠讓開發人員自由編寫sql,同時又保持了orm的特性,將查詢的結果集自動處理成我預先定義好的格式。關鍵,要使用方便,無外部依賴。經過了大概半個月的嘗試,我終於寫出了gzero。

一、如何引入

go get gitee.com/learnhow/gzero@v0.8.1

目前的最新版本是v0.8.1,原始碼只有400行,做了一些簡單的單元測試。後面也許會根據大家的反饋意見在這個版本的基礎上進一步完善。

二、開始使用

1. 定義模型

// 定義員工結構體,內部包含一個身份證資訊和登入資訊
type Emp struct {
    ID        uint `zero:"primaryKey"`
    Name      string
    JobNumber *string
    ILogin    Login         `zero:"prefix:login_"`
    IdCard    *IdentityCard `zero:"prefix:idcard_"`
}

// 登入資訊 
type Login struct {
    ID    uint
    Code  string
    EmpFk uint
}

// 身份證資訊
type IdentityCard struct {
    Code string
}

既然是orm就應該在我們的結構體內部體現出模型之間的關聯關係,gzero通過primaryKey標識主鍵,在處理結果集的時候會根據主鍵判斷,同時支援複合主鍵。主鍵欄位不支援指標型別。

2. 建立連線

ctx := Open("mysql", "root:123456@tcp(127.0.0.1:13306)/helloworld?charset=utf8&parseTime=True&loc=Local", Cfg{})

gzero內部呼叫database/sql,Ctx不是單例物件,你可以反覆呼叫Open方法。但是*sql.DB只會被建立一次,目前我只是做了簡單處理。

3. 編寫sql並安裝進物件

ctx.Sql("SELECT name, job_number FROM t_emp WHERE id = 1").Install(&emp)

gzero預設結構體欄位是駝峰型別,對映為表結構的蛇形欄位。例如:JobNumber在資料庫中對應job_number。你也可以通過“column”重新定義對映的欄位名。如果多個結構體都包含同名的欄位,你完全可以使用"prefix“為內部的結構體新增統一字首(這個特點參考了gorm)。

結果示例:

 

 

 三、獲取多條結果集

編寫sql並安裝進Slice

var emps []Emp
ctx.Sql("SELECT id, name FROM t_emp").Install(&emps)

多條結果集需要使用陣列或切片來接收,結果示例:

 

 四、根據物件的層次結構處理資料

程式碼:

var emp []Emp
ctx.Sql("SELECT e.id, e.name, e.job_number, l.emp_fk, l.code AS login_code FROM t_emp e, t_login l WHERE e.id = l.emp_fk").Install(&emp)

查詢出來的資料,gzero會根據結構體的層次對資料進行自動處理

 

 五、根據主鍵自動合併資料

定義結構體:

type Dept struct {
    ID   uint `zero:"primaryKey"`
    Name string
    Emps []Emp `zero:"prefix:emp_"`
}

查詢並安裝資料:

var depts []Dept
ctx.Sql("SELECT d.id, d.name, e.name AS emp_name, l.code AS login_code FROM t_dept d, t_emp e, t_login l WHERE d.id = e.dept_fk AND l.emp_fk = e.id").Install(&depts)

結構體的字首能夠在sql語句中通過別名指定,查詢結果如下:

 

 

 

 

 

 六、總結

目前gzero功能非常簡單,就是根據開發人員預先定義好的層次關係將查詢的結果集進行處理。之後,我打算增加物件到sql生成的功能,進一步提升crud的開發效率。

相關文章