go-xorm入門教程

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.SameMappercore.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語言中文網

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章