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