開發過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的開發效率。