go xorm 入门笔记
2021-03-13 tech go 9 mins 3490 字

xorm 是一个简单而强大的Go语言 ORM 库,目前支持了众多的数据库,包括:
- Mysql: github.com/go-sql-driver/mysql
- MyMysql: github.com/ziutek/mymysql/godrv
- Postgres: github.com/lib/pq
- Tidb: github.com/pingcap/tidb
- SQLite: github.com/mattn/go-sqlite3
- MsSql: github.com/denisenkom/go-mssqldb
- MsSql: github.com/lunny/godbc
- Oracle: github.com/mattn/go-oci8
最近使用它进行数据库操作,这篇文章简单记录使用情况。
官方网址:https://xorm.io/,官方手册:https://gobook.io/read/gitea.com/xorm/manual-zh-CN/
安装
go get xorm.io/xorm
使用相应的数据库,需要安装相应的驱动,如果使用的是MySQL,需要如下安装:
go get -u github.com/go-sql-driver/mysql
基本使用
package main
import (
    "fmt"
    "github.com/go-xorm/xorm"
    _ "github.com/go-sql-driver/mysql"  // 默认会执行init初始化一些操作的
    "xorm.io/core"
)
func main(){
    //1.创建数据库引擎对象
    engine,err := xorm.NewEngine("mysql","root:root@(127.0.0.1:3306)/elmcms?charset=utf8");
    if err != nil {
        panic(err.Error())
    }
    
    //2.数据库引擎关闭
    defer engine.Close()
    
    //3.数据库引擎设置
    engine.ShowSQL(true)  //设置显示sql语句  会在控制台当中展示
    engine.Logger().SetLevel(core.LOG_DEBUG)   //设置日志级别
    engine.SetMaxOpenConns(10)    //设置最大链接数量
    
    loc, _ := time.LoadLocation("Asia/Shanghai") //设置时区
  	Engine.DatabaseTZ = loc // 设置时区
  	Engine.TZLocation = loc // 设置时区
    //3.简单的一些使用
    //判断表结构是否存在
    exist, err := engine.IsTableExist(XxxObj{})
    if err != nil {
        panic(err.Error())
    }
    
    if ! exist {
        engine.CreateTables(XxxObj{})
    }
}
结构体映射
通过结构体映射自动创建数据库表以及判断表是否为空或者是否存在.
参考:https://gobook.io/read/gitea.com/xorm/manual-zh-CN/chapter-02/1.mapping.html
type XxxObj struct {
    Id         int64     `xorm:"pk autoincr"`   //主键自增
    PersonName string    `xorm:"varchar(24)"`   //可变字符
    PersonAge  int       `xorm:"int default 0"` //默认值
    PersonSex  int       `xorm:"notnull"`       //不能为空
    City       CityTable `xorm:"-"`             //不映射该字段 那就不会在数据库里面创建该字段
}
简单用法
查询
    var obj XxxObj
    var objList []XxxObj
    
    // id查询
    engine.Id(1).Get(&obj)
	// where多条件查询
 	engine.Where(" a = ? and b = ?", 30, 1).Get(&obj)
 	
 	// and or 查询
 	engine.Where(" a = ?", 30).And("b = ?", 1).Find(&objList)
 	engine.Where(" a = ?", 30).Or("b = ?", 1).Find(&objList)
 	
 	// 原生sql语句查询 支持like
 	engine.SQL(" select * from xxx_table where a like '%i%' ").Find(&objList)
 	
 	// orderby
 	engine.OrderBy(" a desc ").Find(&objList)
 	
 	// 特定字段
 	engine.Cols("a", "b").Find(&obj)
更新
 	//更新操作
    xxxUpdate := XxxObj{
        a: "name",
        b:  30,
        c:  1,
    }
    rowNum2, err := engine.Id(1).Cols("xxx","yyy").Update(&personUpdate) //bool类型的更新,有时候不能写入,所以要加上 Cols 强制指定更新的字段。
    fmt.Println(rowNum2) // rowNum2也是表示受影响的行数
    //统计功能count
    count, err := engine.Count(new(XxxObj))
    fmt.Println("persontable表总记录数:",count)
事务操作
    //事务操作
    xxxArray := []XxxObj{
        XxxObj{
            a: "Jack",
            b:  28,
            c:  1,
        },
        XxxObj{
            a: "Mali",
            b:  28,
            c:  1,
        },
        XxxObj{
            a: "Ruby",
            b:  28,
            c:  1,
        },
    }
    session := engine.NewSession()
    session.Begin()
    for i:=0;i<len(xxxArray);i++{
        _, err = session.Insert(xxxArray[i])
        if err != nil {
            session.Rollback()
            session.Close()
        }
    }
    err = session.Commit()
    session.Close()
    if err != nil {
        panic(err.Error())
    }
分页
count, err := models.Engine.Cols("id", "name", "create_time").OrderBy("create_time").Limit(pageSize, skip).FindAndCount(&lists)
