- 創(chuàng)建Orm引擎
xorm支持同時存在多個orm引擎绩脆,一個引擎一般對應(yīng)一個數(shù)據(jù)庫,調(diào)用xorm.NewEngine(driverName, dataSourceName)方法創(chuàng)建引擎姑躲,示例如下:
package model
import (
_ "github.com/go-sql-driver/mysql"
"github.com/go-xorm/xorm"
"github.com/micro/go-micro/util/log"
)
var engine *xorm.Engine
func init() {
en, err := xorm.NewEngine("mysql", "root:123@/test?charset=utf8")
if err != nil {
log.Error("connect to database error")
panic(err)
}
log.Info("connect success")
engine = en
}
一般情況下配乱,如果只操作一個數(shù)據(jù)庫則創(chuàng)建一個engine即可排抬,engine是GoRoutine安全的两踏。engine創(chuàng)建完成后并沒有立即連接數(shù)據(jù)庫逞怨,此時可以通過engine.Ping()來進(jìn)行數(shù)據(jù)庫的連接測試庶喜。
- 連接參數(shù)設(shè)置
en.ShowSQL(true)
en.SetMaxIdleConns(maxIdleConn)
en.SetMaxOpenConns(maxOpenConn)
如果需要顯示生成的SQL語句涩哟,可以通過engine.ShowSQL()來實現(xiàn)赡麦。
如果需要設(shè)置連接池的空閑數(shù)大小,可以使用engine.SetMaxIdleConns()來實現(xiàn)娩怎。
如果需要設(shè)置最大打開連接數(shù)搔课,則可以使用engine.SetMaxOpenConns()來實現(xiàn)。
- 名稱映射規(guī)則
xorm由core.IMapper接口的實現(xiàn)者來管理映射規(guī)則截亦,內(nèi)置的三種IMapper實現(xiàn)為:core.SnakeMapper(默認(rèn))爬泥, core.SameMapper和core.GonicMapper。
如果需要改變時魁巩,在engine創(chuàng)建完成后使用
en.SetMapper(core.SameMapper{})
如果你使用了別的命名規(guī)則映射方案,也可以自己實現(xiàn)一個IMapper姐浮。
表名稱和字段名稱的映射規(guī)則默認(rèn)是相同的谷遂,當(dāng)然也可以設(shè)置為不同,如:
en.SetTableMapper(core.SameMapper{})
en.SetColumnMapper(core.SnakeMapper{})
如果表名和字段名與映射規(guī)則不匹配時可以通過如下方法進(jìn)行修改:
如果表名與映射規(guī)則不一致卖鲤,則可以修改結(jié)構(gòu)體肾扰,如果結(jié)構(gòu)體中包含TableName() string方法,那么此方法的返回值就是對應(yīng)的數(shù)據(jù)庫表名稱蛋逾;也可以在操作數(shù)據(jù)庫時使用engine.Table()指定操作的數(shù)據(jù)庫表集晚。例如:
package model
import (
"github.com/micro/go-micro/util/log"
)
type (
User struct {
Id int64 `xorm:"id"`
Name string `xorm:"name"`
Age int64 `xorm:"age"`
}
)
func (User) TableName() string {
//方法一:指定數(shù)據(jù)庫表名稱為users
return "users"
}
func GetUserByName(name string) User {
user := User{}
//方法二:指定操作的表名稱為users
has, err := engine.Table("users").Where("name=?", name).Get(&user)
if err != nil {
log.Error("select user error:", err)
}
log.Info("res :", has)
return user
}
如果字段名稱與映射規(guī)則不同,則可以在定義結(jié)構(gòu)體時通過xorm:"'column_name'"進(jìn)行指定区匣。(使用單引號防止名稱沖突)
映射規(guī)則優(yōu)先級為engin.Table()>TableName() string>IMapper
- 字段屬性定義
我們在field對應(yīng)的Tag中對Column的一些屬性進(jìn)行定義偷拔,定義的方法基本和我們寫SQL定義表結(jié)構(gòu)類似,比如:
type User struct {
Id int64
Name string `xorm:"varchar(25) notnull unique 'usr_name'"`
}
注意:Tag中的關(guān)鍵字均不區(qū)分大小寫亏钩,但字段名根據(jù)不同的數(shù)據(jù)庫是區(qū)分大小寫莲绰。詳細(xì)規(guī)則參考:Go語言中文網(wǎng):https://books.studygolang.com/xorm/chapter-02/4.columns.html
- 表結(jié)構(gòu)操作
通常在項目啟動后我們需要對數(shù)據(jù)庫進(jìn)行同步,我們可以使用Sync或者Sync2(推薦)方法進(jìn)行同步操作姑丑,使用方法為:
err := en.Sync2(new(User))
if err != nil {
log.Error("sync table error : ", err)
panic(err)
}
Sync2對Sync進(jìn)行了改進(jìn)蛤签,目前推薦使用Sync2。Sync2函數(shù)將進(jìn)行如下的同步操作:
自動檢測和創(chuàng)建表栅哀,這個檢測是根據(jù)表的名字
自動檢測和新增表中的字段震肮,這個檢測是根據(jù)字段名,同時對表中多余的字段給出警告信息
自動檢測留拾,創(chuàng)建和刪除索引和唯一索引戳晌,這個檢測是根據(jù)索引的一個或多個字段名,而不根據(jù)索引名稱痴柔。因此這里需要注意躬厌,如果在一個有大量數(shù)據(jù)的表中引入新的索引,數(shù)據(jù)庫可能需要一定的時間來建立索引。
自動轉(zhuǎn)換varchar字段類型到text字段類型扛施,自動警告其它字段類型在模型和數(shù)據(jù)庫之間不一致的情況鸿捧。
自動警告字段的默認(rèn)值,是否為空信息在模型和數(shù)據(jù)庫之間不匹配的情況
以上這些警告信息需要將engine.ShowWarn 設(shè)置為 true 才會顯示疙渣。
其他操作見:Go中文文檔:https://books.studygolang.com/xorm/chapter-03/
- 數(shù)據(jù)操作
插入:
var user User
engine.Insert(&user)
查詢和統(tǒng)計主要使用Get, Find, Count, Rows, Iterate這幾個方法
//設(shè)置表別名
engine.Alias("o").Where("o.name = ?", name).Get(&order)
//And和Where函數(shù)中的條件基本相同匙奴,作為條件
engine.Where(...).And(...).Get(&order)
//指定字段名正序排序Asc,逆序Desc
engine.Asc("id").Find(&orders)
//傳入一個主鍵字段的值,作為查詢條件妄荔,如SELECT * FROM user Where id = 1
var user User
engine.Id(1).Get(&user)
//復(fù)合主鍵SELECT * FROM user Where id =1 AND name= 'name'
engine.Id(core.PK{1, "name"}).Get(&user)
//in
engine.In("cloumn", 1, 2, 3).Find()
engine.In("column", []int{1, 2, 3}).Find()
//指定部分查詢字段
engine.Select("a.*, (select name from b limit 1) as name").Find(&beans)
engine.Select("a.*, (select name from b limit 1) as name").Get(&bean)
//指定SQL語句
engine.Sql("select * from table").Find(&beans)
//指定字段
// SELECT age, name FROM user limit 1
engine.Cols("age", "name").Get(&usr)
// SELECT age, name FROM user
engine.Cols("age", "name").Find(&users)
更新:
user := new(User)
user.Name = "myname"
affected, err := engine.Id(id).Update(user)
// UPDATE user SET age=? AND name=?
engine.Cols("age", "name").Update(&user)
刪除:
user := new(User)
affected, err := engine.Id(id).Delete(user)
詳細(xì)文檔見Go語言中文網(wǎng):https://books.studygolang.com/xorm/