按照beego官方文檔練習ORM的使用,model創建完始終沒找到辦法創建表,於是使用gorm翻譯文檔和官方文檔進行了練習,使用起來還是比較簡單。
安裝:
方法一:Terminal打開,go get -u github.com/jinzhu/gorm
方法二:復制地址https://github.com/jinzhu/gorm,到GoLand直接會提示是否將gorm添加到GOPATH,確認添加會自動下載
建model,models.go內容如下:
package models
import (
"github.com/jinzhu/gorm"
)
type User struct {
gorm.Model
Name string
Profile Profile `gorm:"ForeignKey:UserRefer"` // 一個User包含一個Profile
Post []Post // 一個User包含多個Post UserID為外鍵
}
type Profile struct {
gorm.Model
Age int16
UserRefer uint
}
type Post struct {
gorm.Model
Title string
UserID uint
Tag []*Tag `gorm:"many2many:post_tag;"`
}
type Tag struct {
gorm.Model
Name string
Posts []*Post `gorm:"many2many:post_tag;"`
}
連接數據庫,main.go部分內容:
package main
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
"myproject/models"
_ "myproject/routers"
)
var db *gorm.DB
func main() {
// 連接數據庫
var err error
db, err = gorm.Open("mysql", "root:nola123456@/default?charset=utf8&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
defer db.Close()
...
}
創建表,main.go部分內容:
gorm文檔給出自動遷移模式,警告:自動遷移僅僅會創建表,缺少列和索引,並且不會改變現有列的類型或刪除未使用的列以保護數據。
db.AutoMigrate(&models.User{}, &models.Profile{}, &models.Post{}, &models.Tag{})
使用如下方式創建表(代碼有點繁瑣,還在探索中):
func main() {
...
// 創建表User
if !db.HasTable(&models.User{}) {
if err := db.Set("gorm:table_options", "ENGINE=InnoDB").CreateTable(&models.User{}).Error; err != nil {
panic(err)
}
}
// 創建表Profile
if !db.HasTable(&models.Profile{}) {
if err := db.Set("gorm:table_options", "ENGINE=InnoDB").CreateTable(&models.Profile{}).Error; err != nil {
panic(err)
}
}
// 創建表Post
if !db.HasTable(&models.Post{}) {
if err := db.Set("gorm:table_options", "ENGINE=InnoDB").CreateTable(&models.Post{}).Error; err != nil {
panic(err)
}
}
// 創建表Tag
if !db.HasTable(&models.Tag{}) {
if err := db.Set("gorm:table_options", "ENGINE=InnoDB").CreateTable(&models.Tag{}).Error; err != nil {
panic(err)
}
}
...
}
運行main.go,數據庫表創建完畢:

CRUD,main.go插入部分:
func main() {
...
// 插入
profile := models.Profile{Age: 30}
profile1 := models.Profile{Age: 25}
db.Create(&profile)
db.Create(&profile1)
fmt.Println(profile)
fmt.Println(profile1)
db.Create(&models.User{Profile: profile, Name: "silence"})
db.Create(&models.User{Profile: profile1, Name: "silence 2"})
db.Create(&models.User{Profile: profile, Name: "nola"})
db.Create(&models.User{Profile: profile1, Name: "alice"})
...
}
CRUD,main.go查詢部分:
func main() {
...
//查詢
var count int
db.First(&models.User{}) // 第一條記錄
db.Last(&models.User{}) // 最后一條記錄
db.Find(&models.User{}) // 所有記錄
db.First(&models.User{}, 1) // 使用主鍵獲取記錄
db.Where("name = ?", "nola").First(&models.User{}) // where條件查詢第一個匹配記錄
db.Where("name = ?", "nola").Find(&models.User{}) // where條件查詢所有匹配記錄
db.Where("name <> ?", "nola").Find(&models.User{}) // where條件查詢name不為nola的所有user
db.Where("name in (?)", []string{"silence", "silence 2"}) // in
db.Where("name LIKE ?", "%sil%").Find(&models.User{}) // LIKE
db.Select([]string{"user_refer", "age"}).Find(&models.Profile{}) // 指定檢索字段
db.Select("name").Find(&models.User{}) // 指定檢索字段
db.Order("name desc").Find(&models.User{}) // 排序
db.Limit(3).Find(&models.User{}) // limit
counts := db.Where("name = ?", "rose").Find(&models.User{}).Count(&count) // count
fmt.Println(counts)
...
}
CRUD,main.go更新部分:
func main() {
...
// 更新
db.Table("users").Where("id in (?)", []int{30, 34}).Update(map[string]interface{}{"name":"hello"}) // 批量更新
affected_nums := db.Model(&models.User{}).Where("name = ?", "jack").Update(models.User{Name:"jim"}).RowsAffected // 返回影響行數
fmt.Println(affected_nums)
...
}
CRUD,main.go刪除部分:
func main() {
...
// 刪除
db.Where("name LIKE ?", "%len%").Delete(models.User{})
db.Delete(models.Profile{}, "age = ?", "30") // model存在deleted_at字段為軟刪除 記錄刪除時間
fmt.Println(db.Where("age = ?", "30").Find(&models.Profile{}).Value) // 軟刪除的記錄查詢被忽略
fmt.Println(db.Unscoped().Where("age = ?", "30").Find(&models.Profile{}).Value) // 查詢軟刪除的記錄
db.Unscoped().Delete(models.Profile{}, "age = ?", "30") // 永久刪除記錄
}


習慣Django那種建好model進行遷移,也有一些人習慣利用sql語句去生成models.go文件,個人感覺很別扭。gorm使用起來很舒服,它還有很多高級用法,值得慢慢研究。。。
着實不甘心,beego的orm連注冊model都有,怎能沒有創建同步表呢?參考csdn上一篇文章,再試一下:
創建項目:cd src工作間 - bee new useBeegoORM創建項目
useBeegoORM/models/models.go內容如下:
package models
type User struct {
Id int
Name string
Profile *Profile `orm:"rel(one)"` // 一對一關系
Post []*Post `orm:"reverse(many)"` // 設置一對多反向關系
}
type Profile struct {
Id int
Age int16
User *User `orm:"reverse(one)"` // 設置一對一反向關系(可選)
}
type Post struct {
Id int
Title string
User *User `orm:"rel(fk)"` // 設置一對多關系
Tags []*Tag `orm:"rel(m2m)"` // 設置多對多關系
}
type Tag struct {
Id int
Name string
Posts []*Post `orm:"reverse(many)"`
}
useBeegoORM/main.go內容如下:
package main
import (
_ "github.com/Go-SQL-Driver/MySQL" // 引入driver
"github.com/astaxie/beego"
"github.com/astaxie/beego/orm"
"useBeegoORM/models" // 引入model
_ "useBeegoORM/routers"
)
func init() {
// 注冊driver
orm.RegisterDriver("mysql", orm.DRMySQL)
// 需要在init中注冊定義的model
orm.RegisterModel(new(models.User), new(models.Profile), new(models.Post), new(models.Tag))
// 注冊數據庫 ORM必須注冊一個別名為default的數據庫作為默認使用
orm.RegisterDataBase("default", "mysql", "root:nola123456@/orm_test?charset=utf8")
// 自動創建表 參數二開啟創建表 參數三開啟更新表【此句重點】
orm.RunSyncdb("default", true, true)
}
func main() {
beego.Run()
}
運行會自動創建表,同步到數據庫,效果如下:



創建的表終於同步到數據庫了~。~
接着看看CRUD的使用:
package main
import (
_ "github.com/Go-SQL-Driver/MySQL" // 引入driver
//"github.com/astaxie/beego"
"github.com/astaxie/beego/orm"
"fmt"
"useBeegoORM/models" // 引入model
_ "useBeegoORM/routers"
)
func init() {
// 注冊driver
orm.RegisterDriver("mysql", orm.DRMySQL)
// 需要在init中注冊定義的model
orm.RegisterModel(new(models.User), new(models.Profile), new(models.Post), new(models.Tag))
// 注冊數據庫 ORM必須注冊一個別名為default的數據庫作為默認使用
orm.RegisterDataBase("default", "mysql", "root:nola123456@/orm_test?charset=utf8")
// 自動創建表 參數二開啟創建表 參數三開啟更新表【此句重點】
//orm.RunSyncdb("default", true, true)
}
func main() {
// 對象的CRUD
o := orm.NewOrm() // 創建一個Ormer
user := new(models.User)
profile := new(models.Profile)
profile.Age = 30
user.Name = "silence"
user.Profile = profile
fmt.Println(o.Insert(user)) // Insert
fmt.Println(o.Insert(profile))
user.Name = "Your"
fmt.Println(o.Update(user)) // Update
fmt.Println(o.Read(user)) // Read
fmt.Println(o.Delete(user)) // Delete
//beego.Run()
}
查看數據:
可增減數據,第2步submit,相應的會打印console。

ORM的操作還需慢慢研究。有關GoLand配置數據庫以及配置遠程host,用過jetbrains公司的產品如PyCharm等,配置風格都類似。
明天有時間寫個詳細步驟留存,供大家參考~
