xorm操作
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/