golang Xorm操作
1.下載xorm包
go get github.com/go-xorm/xorm
go get github.com/go-xorm/cmd
2.安裝驅動
go get github.com/go-sql-driver/mysql //Mysql
go get github.com/ziutek/mymysql/godrv //MyMysql
go get github.com/lib/pq //Postgres
go get github.com/mattn/go-sqlite3 //SQLite
go get github.com/denisenkom/go-mssqldb //MSSQL
3.xorm reverse將數據庫表生成golang結構體
安裝xorm : go install github.com/go-xorm/xorm
database | command |
---|---|
sqlite | xorm reverse sqite3 test.db templates/goxorm C:\temp |
mysql | xorm reverse mysql "root:123456@(127.0.0.1:3306)/test?charset=utf8" templates/goxorm C:\temp |
mymysql | xorm reverse mymysql xorm_test2/root/ templates/goxorm C:\temp |
postgres | xorm reverse postgres "user=postgres password=123456 dbname=test host=127.0.0.1 port=5432 sslmode=disable" templates/goxorm C:\temp |
mssql | xorm reverse mssql "server=127.0.0.1;user id=testid;password=testpwd;database=testdb" templates/goxorm C:\temp |
參考鏈接:xorm-reverse
4.xorm引擎
Engine 引擎用於對單個數據庫進行操作
Engine Group 引擎用於對讀寫分離的數據庫或者負載均衡的數據庫進行操作
4.1 創建引擎
import (
_ "github.com/go-sql-driver/mysql"
"xorm.io/xorm"
)
var engine *xorm.Engine
func main() {
var err error
engine, err = xorm.NewEngine("mysql", "root:123@/test?charset=utf8")
engine.Ping() //連接測試
defer engine.Close() //延遲關閉數據庫
}
4.2 打印日志
engine.ShowSQL(true),則會在控制台打印出生成的SQL語句;
engine.Logger().SetLevel(core.LOG_DEBUG),則會在控制台打印調試及以上的信息;
--------------------------------------------------------------------
f, err := os.Create("sql.log")
if err != nil {
println(err.Error())
return
}
engine.SetLogger(xorm.NewSimpleLogger(f))
4.3 連接池
如果需要設置連接池的空閑數大小,使用 engine.SetMaxIdleConns() 來實現。
如果需要設置最大打開連接數,則使用 engine.SetMaxOpenConns() 來實現。
如果需要設置連接的最大生存時間,則使用 engine.SetConnMaxLifetime() 來實現。
4.4 名稱映射規則
xorm 內置了三種 Mapper 實現:names.SnakeMapper , names.SameMapper和names.GonicMapper。
SnakeMapper 支持struct為駝峰式命名,表結構為下划線命名之間的轉換,這個是默認的Maper;
SameMapper 支持結構體名稱和對應的表名稱以及結構體field名稱與對應的表字段名稱相同的命名;
GonicMapper 和SnakeMapper很類似,但是對於特定詞支持更好,比如ID會翻譯成id而不是i_d。
當前 SnakeMapper 為默認值,如果需要改變時,在 engine 創建完成后使用
engine.SetMapper(names.GonicMapper{})
// 給表加前綴
tbMapper := names.NewPrefixMapper(names.SnakeMapper{}, "prefix_")
engine.SetTableMapper(tbMapper)
// 加后綴
names.NewSuffixMapper(names.SnakeMapper{}, "suffix")
4.5 表名和字段名
表名的優先級順序如下:
engine.Table() 指定的臨時表名優先級最高
TableName() string 其次
Mapper 自動映射的表名優先級最后
字段名的優先級順序如下:
結構體tag指定的字段名優先級較高 xorm:"'column_name'"
Mapper 自動映射的表名優先級較低
4.6 表操作
engine.DBMetas() 可以獲取到數據庫中所有的表,字段,索引的信息。
engine.CreateTables() 創建表,參數為一個或多個空的對應Struct的指針。
IsTableEmpty() 判斷表是否為空,參數和 CreateTables 相同
IsTableExist() 判斷表是否存在
engine.DropTables() 刪除表 參數為一個或多個空的對應Struct的指針或者表的名字。如果為string傳入,則只刪除對應的表,如果傳入的為Struct,則刪除表的同時還會刪除對應的索引。
CreateIndexes 根據struct中的tag來創建索引
CreateUniques 根據struct中的tag來創建唯一索引
err := engine.Sync(new(User), new(Group)) 同步數據庫結構
err := engine.Sync2(new(User), new(Group))
4.7 導入和導出SQL
// 導出數據庫的結構和數據
engine.DumpAll(w io.Writer)
engine.DumpAllToFile(fpath string)
// 執行SQL腳本
engine.Import(r io.Reader)
engine.ImportFile(fpath string)
4.8 插入數據
type User struct {
Id int64
Name string
//xorm標記中使用created標記,在數據插入到數據庫時自動將對應的字段設置為當前時間
CreatedAt time.Time `xorm:"created"` // 類型也可以為:int64
}
----------------------------------------
//插入單條記錄
user := new(User)
user.Name = "myname"
affected, err := engine.Insert(user)
// INSERT INTO user (name) values (?)
-------------------------------------------
//插入多條記錄
users := make([]*User, 1)
users[0] = new(User)
users[0].Name = "name0"
...
affected, err := engine.Insert(&users) // 批量插入,無法被自動賦予id值
affected, err := engine.Insert(users...) // 生成多條插入語句,每條記錄均會自動賦予Id值
4.9 查詢
engine.Alias("o").Where("o.name = ?", name).Get(&order) // 別名
engine.Asc("id").Desc("time").Find(&orders) // 排序
------------------------
var user User
engine.ID(1).Get(&user) //主鍵查詢
has, err := engine.Id(id).Get(user)
has, err := engine.Where("name=?", "xlw").Get(user)
等價:
user := &User{Id:1}
has, err := engine.Get(user)
---------------------------------------
engine.SQL("select * from table").Find(&beans) // 執行指定的Sql語句,並把結果映射到結構體
---------------------------------------------------
// select from table where column in (1,2,3)
engine.In("column", []int{1, 2, 3}).Find()
---------------------------------------------------
// SELECT DISTINCT age, department FROM user
engine.Distinct("age", "department").Find(&users)
---------------------------------------------------
everyone := make([]Userinfo, 0)
err := engine.Find(&everyone)
users := make(map[int64]Userinfo)
err := engine.Find(&users)
var ints []int64
err := engine.Table("user").Cols("id").Find(&ints)
----------------------------------------------------
err := engine.Where("age > ? or name=?)", 30, "xlw").Iterate(new(Userinfo), func(i int, bean interface{})error{
user := bean.(*Userinfo)
//do somthing use i and user
})
問題記錄:
pgpool連接后報錯:pq driver: prepared statement does not exist 或者: pq: 未命名的准備語句不存在
解決辦法:
如果使用PgBouncer(不支持預編譯) 需要設置數據庫連接參數binary_parameters=yes
DB, err = sql.Open("postgres", "user=user password=pwd dbname=mydb sslmode=disable, binary_parameters=yes")
參考鏈接:https://stackoverflow.com/questions/17614441/pq-driver-prepared-statement-does-not-exist
相關鏈接
https://blog.xorm.io/2014/1/1/1-7-weapons.html
https://gobook.io/read/gitea.com/xorm/manual-zh-CN/
https://books.studygolang.com/xorm/