由於gorm不僅支持數據庫讀寫操作,且以面向對象的編碼方式實現數據庫讀寫。本片文章從實際開發中所遇問題和新的需要,對gorm進行一次封裝操作,以此來加快開發速度。
首先介紹代碼架構:
|-----------------------
|- component
|-- db.go
|-- model.go
|-- test.go
|- include
|-- container.go
|-- db.go
|- init
|-- init.go
|- model
|-- bean
|--- messageRegister.go
|-- messageRegister.go
|- test
|-- messageRegister.go
|- main.go
|-----------------------
a. 入口文件: main.go
package main
import _ "./init"
import "./test"
func main() {
test.TMessageRegister()
}
b. 編寫基礎結構體和接口(component)
(1) 數據庫連接相關, db.go
package component
import "github.com/jinzhu/gorm"
type SwyModel struct {
*gorm.DB //鏈接實例
TableName string //數據庫名
}
(2) 數據實體相關, model.go
package component
import (
"encoding/json"
"github.com/jinzhu/gorm"
)
//數據庫增刪改查操作封裝
type Curd interface {
}
type Transaction interface {
}
type DpModel struct {
Curd
Transaction
gorm.Model
}
func translate(out interface{}, v interface{}) (interface{}, error) {
var (
err error
ms = make([]byte, 0, 64)
)
ms, err = json.Marshal(v)
if err != nil {
return nil, err
}
err = json.Unmarshal(ms, out)
if err != nil {
return nil, err
}
return out, nil
}
func (s *DpModel) Translate(out interface{}, v interface{}) (interface{}, error) {
return translate(out, v)
}
(3) 測試相關, test.go
package component
type DpTest struct {
}
c. 系統初始化,init.go
package init
import (
_ "../include"
)
d. 依賴包加載(include)
(1)初始化容器
//容器, 用於管理中間件
package include
import (
"fmt"
"sync"
)
type Container struct {
mux sync.Mutex
mds map[string]interface{}
}
var Cont *Container = &Container{
sync.Mutex{},
make(map[string]interface{}, 8),
}
func (c *Container) Register(n string, sl interface{}) {
c.mux.Lock()
defer c.mux.Unlock()
_, ok := c.mds[n]
if !ok {
c.mds[n] = sl
}
}
func (c *Container) Get(n string) (interface{}, error) {
sl, ok := c.mds[n]
if !ok {
return nil, fmt.Errorf("未找到單例`%v`", n)
}
return sl, nil
}
(2)初始化數據庫連接實例
package include
import (
"fmt"
_ "github.com/jinzhu/gorm/dialects/mysql"
"github.com/jinzhu/gorm"
)
func init() {
dc := struct {
User string
Password string
Host string
Port string
DBName string
Option string
}{
`root`,
`chuyinwl01`,
`localhost`,
`3306`,
`go`,
`charset=utf8mb4&parseTime=true`,
}
//依賴配置項
dsn := fmt.Sprintf(
"%s:%s@(%s:%s)/%s?%s",
dc.User,
dc.Password,
dc.Host,
dc.Port,
dc.DBName,
dc.Option,
)
db, err := gorm.Open("mysql", dsn)
if err != nil {
panic(fmt.Sprintf("數據庫初始化異常, error:`%v`", err))
}
Cont.Register("db", db)
}
func GetDB(db interface{}) *gorm.DB {
if db == nil {
panic("獲取gorm.DB對象失敗, 傳入nil!")
}
gd := db.(*gorm.DB)
return gd
}
e. 編寫數據實體(model)
(1) 編寫數據實體(bean)
package bean
import (
"../../component"
)
type MessageRegister struct {
component.DpModel
Type int `gorm:"column:type" json:"type"`
Desc string `gorm:"column:desc" json:"desc"`
}
func (s *MessageRegister) TranslateSelf(v interface{}) *MessageRegister {
var m interface{}
var err error
var ok bool
var message *MessageRegister
if m, err = s.Translate(s, v); err != nil {
//todo log
return nil
}
if message, ok = m.(*MessageRegister); !ok {
//todo log
}
return message
}
(2) 編寫實體操作對象
package model
import (
"fmt"
"../component"
"../include"
)
type MessageRegisterModel struct {
component.SwyModel
}
func NewMessageRegister() *MessageRegisterModel {
db, err := include.Cont.Get("db")
if err != nil {
panic(fmt.Sprintf("內部錯誤, error:`%v`", err))
}
gd := include.GetDB(db)
if gd == nil {
panic("內部錯誤, 數據庫單例類型異常")
}
tableName := "go_register"
return &MessageRegisterModel{
component.SwyModel{
gd.Table(tableName),
tableName,
},
}
}
f. 編寫測試用例, messageRegister.go
package test
import (
"../component"
"fmt"
"github.com/jinzhu/gorm"
)
import "../model"
import "../model/bean"
type MessageRegisterTest struct {
component.DpTest
}
func (s *MessageRegisterTest) Test() {
var modelMessageRegister = model.NewMessageRegister()
var messageRegister = &bean.MessageRegister{}
//----------------------- 創建一條記錄
messageRegister.Type = 1
messageRegister.Desc = `dora hope`
if err := modelMessageRegister.Create(messageRegister).Error; err != nil {
panic(fmt.Sprintf("數據庫寫測試失敗, err:`%v`\n", err))
}
fmt.Println(`數據庫寫測試成功`)
//----------------------- 查看一條記錄
//id := 1
//if err := modelMessageRegister.Where(`id = ?`, id).First(messageRegister).Error; err != nil {
// if gorm.IsRecordNotFoundError(err) {
// panic(fmt.Sprintf("未找到記錄, err:`%v`\n", err))
// }
// panic(fmt.Sprintf("數據庫讀測試失敗, err:`%v`\n", err))
//}
//fmt.Printf("message is `%v`\n", messageRegister)
//----------------------- json轉移處理(並沒有對記錄的生成等時間進行轉移)
//_ = modelMessageRegister
//j := map[string]interface{} {
// `id`: 1,
// `type`: 1,
// `desc`: `dora hope`,
//}
//if messageRegister.Translate(messageRegister, j); messageRegister == nil {
// panic(fmt.Sprintf("數據實體轉義失敗\n"))
//}
//fmt.Printf("數據庫實體轉移成功, message:`%v`\n", messageRegister)
}
func TMessageRegister() {
t := &MessageRegisterTest{}
t.Test()
}
以上就是本篇文章的所介紹的內容,從測試中可看出,開發時,對某張表數據的操作起來還是很簡單的,雖然只是對gorm簡單的封裝,但是還是挺實用的。所以,參考本文章,編寫數據實體時,只需要實現數據實體結構和數據實體操作對象。