打赏

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://xorm.io/

https://blog.xorm.io/2014/1/1/1-7-weapons.html

https://gitea.com/xorm

https://gobook.io/read/gitea.com/xorm/manual-zh-CN/

https://books.studygolang.com/xorm/

https://www.kancloud.cn/xormplus/xorm/167077

https://www.kancloud.cn/kancloud/xorm-manual-zh-cn/56017

posted @ 2021-10-22 11:31  苍山落暮  阅读(1344)  评论(0编辑  收藏  举报