1. 創建Orm引擎
xorm支持同時存在多個orm引擎,一個引擎一般對應一個數據庫,調用xorm.NewEngine(driverName, dataSourceName)
方法創建引擎,示例如下:
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
}
一般情況下,如果只操作一個數據庫則創建一個engine即可,engine是GoRoutine安全的。engine創建完成後並沒有立即連接數據庫,此時可以通過engine.Ping()
來進行數據庫的連接測試。
2. 連接參數設置
en.ShowSQL(true)
en.SetMaxIdleConns(maxIdleConn)
en.SetMaxOpenConns(maxOpenConn)
如果需要顯示生成的SQL語句,可以通過engine.ShowSQL()
來實現。
如果需要設置連接池的空閒數大小,可以使用engine.SetMaxIdleConns()
來實現。
如果需要設置最大打開連接數,則可以使用engine.SetMaxOpenConns()
來實現。
3. 名稱映射規則
xorm由core.IMapper
接口的實現者來管理映射規則,內置的三種IMapper實現爲:core.SnakeMapper
(默認), core.SameMapper
和core.GonicMapper
。
如果需要改變時,在engine創建完成後使用
en.SetMapper(core.SameMapper{})
如果你使用了別的命名規則映射方案,也可以自己實現一個IMapper。
表名稱和字段名稱的映射規則默認是相同的,當然也可以設置爲不同,如:
en.SetTableMapper(core.SameMapper{})
en.SetColumnMapper(core.SnakeMapper{})
如果表名和字段名與映射規則不匹配時可以通過如下方法進行修改:
如果表名與映射規則不一致,則可以修改結構體,如果結構體中包含TableName() string
方法,那麼此方法的返回值就是對應的數據庫表名稱;也可以在操作數據庫時使用engine.Table()
指定操作的數據庫表。例如:
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 {
//方法一:指定數據庫表名稱爲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
}
如果字段名稱與映射規則不同,則可以在定義結構體時通過xorm:"'column_name'"
進行指定。(使用單引號防止名稱衝突)
映射規則優先級爲engin.Table()
>TableName() string
>IMapper
4. 字段屬性定義
我們在field對應的Tag中對Column的一些屬性進行定義,定義的方法基本和我們寫SQL定義表結構類似,比如:
type User struct {
Id int64
Name string `xorm:"varchar(25) notnull unique 'usr_name'"`
}
注意:Tag中的關鍵字均不區分大小寫,但字段名根據不同的數據庫是區分大小寫。詳細規則參考:Go語言中文網
5. 表結構操作
通常在項目啓動後我們需要對數據庫進行同步,我們可以使用Sync
或者Sync2
(推薦)方法進行同步操作,使用方法爲:
err := en.Sync2(new(User))
if err != nil {
log.Error("sync table error : ", err)
panic(err)
}
Sync2對Sync進行了改進,目前推薦使用Sync2。Sync2函數將進行如下的同步操作:
- 自動檢測和創建表,這個檢測是根據表的名字
- 自動檢測和新增表中的字段,這個檢測是根據字段名,同時對錶中多餘的字段給出警告信息
- 自動檢測,創建和刪除索引和唯一索引,這個檢測是根據索引的一個或多個字段名,而不根據索引名稱。因此這裏需要注意,如果在一個有大量數據的表中引入新的索引,數據庫可能需要一定的時間來建立索引。
- 自動轉換varchar字段類型到text字段類型,自動警告其它字段類型在模型和數據庫之間不一致的情況。
- 自動警告字段的默認值,是否爲空信息在模型和數據庫之間不匹配的情況
以上這些警告信息需要將engine.ShowWarn
設置爲 true
纔會顯示。
其他操作見:Go中文文檔
6. 數據操作
插入:
var user User
engine.Insert(&user)
查詢和統計主要使用Get, Find, Count, Rows, Iterate這幾個方法
//設置表別名
engine.Alias("o").Where("o.name = ?", name).Get(&order)
//And和Where函數中的條件基本相同,作爲條件
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)
//複合主鍵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)
詳細文檔見Go語言中文網