开发者

详解Go语言如何使用xorm实现读取mysql

开发者 https://www.devze.com 2022-12-12 12:03 出处:网络 作者: 海生
目录一、介绍二、安装使用xorm,注意连接的关闭!关于连接数的坑以及engine.Close()常用方法介绍三、mysql生产struct四、xorm常用操作示例--insert数据4.1 insert 增加1条数据4.2 insert 增加多条数据4.3 insert 增加
目录
  • 一、介绍
  • 二、安装使用xorm,注意连接的关闭!
    • 关于连接数的坑以及engine.Close()
    • 常用方法介绍
  • 三、mysql生产struct
    • 四、xorm常用操作示例--insert数据
      • 4.1 insert 增加1条数据
      • 4.2 insert 增加多条数据
      • 4.3 insert 增加不同表数据
    • 五、xorm常用操作示例--删除某行
      • 5.1 通过id删除
      • 5.2 通过where条件删除
      • 5.3 软删除,通过某个字段实现软删除,比如status=0
    • 六、xorm常用操作示例--update更新操作
      • 6.1 以结构体的参数,传递要更新的字段
      • 6.2 以map做为参数,传递要更新的字段
      • 6.3指定字段更新,未指定的将不更新,指定了的即使为0也会更新。
      • 6.4指定字段更新,未指定的根据值是否是有值来更新。
    • 七、xorm常用操作示例--查询单条
      • 7.1 根据主键Id来获得单条数据:
      • 7.2 根据where来获得单条数据:
      • 7.3 根据user机构体中非空数据来获得单条数据:
    • 八、xorm常用操作示例--查询多条数据
      • 8.1 返回结果为 结构体slice:
      • 8.2 返回结果为 结构体map:
    • 九、xorm常用操作示例--FindAndCount 分页
      • 十、xorm常用操作示例--事务操作

        一、介绍

        xorm是go语言的常用orm之一,用来操作数据库。

        主要特性特性:

        • 支持根据数据库自动生成xorm的结构体
        • 支持Struct和数据库表之间的灵活映射, 并支持自动同步
        • 支持事务
        • 支持使用Id, In, Where, Limit, Join, Having, Table, Sql, Cols等函数和结构体等方式作为条件
        • 支持查询结果集导出csv、tsv、XML、json、xlsx、yaml、html功能

        二、安装使用xorm,注意连接的关闭!

        import (
            _ "github.com/go-sql-driver/mysql"
            "xorm.io/xorm"
        )

        然后我们就可以构造一个new方法来初始化使用 orm客户端了。

        我们在下面的代码,会通过一个函数返回 xorm.EngineInterface,以及一个 engine.Close()函数供使用者调用,之所以这样是因为,有些比如开发者_DB2脚本脚本之类的

        当执行完,就需要把 mysql连接关闭掉,以用来节省连接数。

        如果都不关闭的话,在高并发的情况下,连接数很多,会把mysql打爆!

        type MysqlClient xorm.EngineInterface
        func NewMysqlClient() (MysqlClient, func(), error) {
            // 创建 engine 对象
            engine, err := xorm.NewEngine("mysql", "user:pwd@tcp(ip:port)/dbname?charset=utf8")
            if err != nil {
                fmt.Printf("init engine fail! err:%+v", err)
            }
            // 连接池配置
            engine.SetMaxOpenConns(30)                  // 最大 db 连接
            engine.SetMaxIdleConns(10)                  // 最大 db 连接空闲数
            engine.SetConnMaxLifetime(30 * time.Minute) // 超过空闲数连接存活时间
        
            // 日志相关配置
            engine.ShowSQL(true)                    // 打印日志
            engine.Logger().SetLevel(log.LOG_DEBUG) // 打印日志级别
            engine.SetLogger(log.SimpleLogger{})    // 设置日志输出 (控制台, 日志文件, 系统日志等)
        
            // 测试连通性
            if err = engine.Ping(); err != nil {
                fmt.Printf("ping to db fail! err:%+v", err)
            }
            return engine, func() {
                engine.Close()
            }, err
        }

        关于连接数的坑以及engine.Close()

        engine可以通过engine.Close来手动关闭,但是一般情况下可以不用关闭,在程序退出时会自动关闭。

        但是如果,每个连接都是新建了一个 client的话,一般http服务不会退出,如果此时高并发,就会增加无数的mysql连接数,打爆mysql。

        在这个NewMysqlClient函数里我们创建了一个 全局的变量 MysqlClient,全局共用一个连接。

        常用方法介绍

        engine.SetMaxOpenConns(30) 创建连接池

        engine.ShowSQL(true) 在控制台打印sql语句

        engine.Logger().SetLevel(log.LOG_DEBUG) 在控制台打印调试及以上的信息

        engine.SetLogger(log.DiscardLogger{}) 把日志写入到文件,或者专门的日志收集系统里。

        三、mysql生产struct

        使用官方自带的reverse工具 https://gitea.com/xorm/reverse比如我们现在在有一个表

        CREATE TABLE `user` (
          `id` int(11) NOT NULL AUTO_INCREMENT,
          `name` varchar(45) DEFAULT NULL,
          `status` smallint(6) DEFAULT NULL,
          PRIMARY KEY (`id`)
        ) ENGINE=InnoDB

        我们使用 reverse -f sql_reverse.yaml 来生成 struct

        sql_reverse.yaml的代码如下:

        # 步骤1:安装 go get xorm.io/reverse
        # 步骤2:修改上面文件中的conn_str以及include_tables的表
        # 步骤3:执行reverse -f sql_reverse.yaml
        
        kind: reverse
        name: mydb
        source:
          database: mysql
          conn_str: 'user:pasword@tcp(localhost:3306)/test?charset=utf8mb4'
        targets:
          - type: codes
            language: golang
            include_tables: # 需要生成的表的结构
              - user //我们要生产的表明
            multiple_files: true
            output_dir: ./internal/domain/flow/repository/po
            template编程: |
              package po
        
              {{$ilen := len .Imports}}
              {{if gt $ilen 0}}
              import (
                {{range .Imports}}"{{.}}"{{end}}
              )
              {{end}}
        
              {{range编程 .Tables}}
              type {{TableMapper .Name}} struct {
              {{$table := .}}
              {{range .ColumnsSeq}}{{$col := $table.GetColumn .}}    {{ColumnMapper $col.Name}}    {{Type $col}} `{{Tag $table $col}}`
              {{end}}
              }
        
              func (m *{{TableMapper .Name}}) TableName() string {
                  return "{{$table.Name}}"
              }
              {{end}}
            template_path: ./template/goxorm.tmpl # template path for code file, it has higher perior than template field on language

        生成对应的go代码为

        type User struct {
            Id     int64  `json:"id" xorm:"'id' int(11) not null pk autoincr  "`
            Name   string `json:"name" xorm:"'name' varchar(45) null   "`
            Status int64  `json:"status" xorm:"'status' smallint(3) null   "`
        }
        
        func (m *User) TableName() string {
            return "user"
        }

        四、xorm常用操作示例--insert数据

        4.1 insert 增加1条数据

        增加一条对象。

        engine, _, _ := NewMysqlClient()
            u := User{
                Name:   "hisheng",
                Status: 0,
            }
            affected, err := engine.Insert(&u)
            t.Log(affected, err)

        4.2 insert 增加多条数据

        多条数据,还是Insert方法,参数为slice就行。

        func TestInsertUsers(t *testing.T) {
            engine, _, _ := NewMysqlClient()
            us := []User{{Name: "hi", Status: 1}, {Name: "shGMqVXReeeng", Status: 1}}
            affected, err := engine.Insert(&us)
            t.Log(affected, err)
        }

        当插入多条数据的时候,官方建议我们少于150条数据,多余150条数据的时候,容易插入失败。

        4.3 insert 增加不同表数据

        user := new(User)
        user.Name = "myname"
        ...
        questions := make([]Question, 1)
        questions[0].Content = "whywhywhwy?"
        affected, err := engine.Insert(user, &questions)

        五、xorm常用操作示例--删除某行

        5.1 通过id删除

        user := new(User)
        affected, err := engine.ID(id).Delete(user)

        5.2 通过where条件删除

        user := new(User)
        affected, err := engine.Where("id = ?",1).Delete(user)

        5.3 软删除,通过某个字段实现软删除,比如status=0

        这个用更新的方法

        u := User{
                Status: 0,
            }
            affected, err := engine.Where("id = ?",1).MustCols("status").Update(&u)
            t.Log(affected, err)

        注意这里,增加了一个MustCols,因为xorm默认是有值自动更新的,而status和默认值,是一样的,默认值会被忽略而不被更新,此时要更新,需要加一个 MustCols字段。

        六、xorm常用操作示例--update更新操作

        6.1 以结构体的参数,传递要更新的字段

        func TestUpdate(t *testing.T) {
            engine, _, _ := NewMysqlClient()
            u := User{
                Name: "1111",
            }
            affected, err := engine.ID(1).Update(&u)
        }

        这个会Update的参数是更新字段。这里会更新Name字段。

        6.2 以map做为参数,传递要更新的字段

        以map作为要更新的字段,传递方式,map的格式为 map[string]interface{}

        func TestUpdateMap(t *testing.T) {
            engine, _, _ := NewMysqlClient()
            u := map[string]interface{}{"name": "111"}
            affected, err := engine.ID(1).Update(u)
        }

        6.3指定字段更新,未指定的将不更新,指定了的即使为0也会更新。

        我们通过添加Cols函数指定需要更新结构体中的值。

        affected, err := engine.ID(id).Cols("age").Update(&user)

        6.4指定字段更新,未指定的根据值是否是有值来更新。

        有时候希望能够指定必须更新某些字段,而其它字段根据值的情况自动判断,可以使用 MustCols 来组合 Update 使用。

        affected, err := engine编程.ID(id).MustCols("age").Update(&user)

        七、xorm常用操作示例--查询单条

        查询单条数据使用Get方法,在调用Get方法时需要传入一个对应结构体的指针,同时结构体中的非空field自动成为查询的条件和前面的方法条件组合在一起查询。

        7.1 根据主键Id来获得单条数据:

        user := new(User)
        has, err := engine.ID(id).Get(user)js

        7.2 根据where来获得单条数据:

        user := new(User)
        has, err := engine.Where("name=?", "xlw").Get(user)

        7.3 根据user机构体中非空数据来获得单条数据:

        user := &User{Id:1}
        has, err := engine.Get(user)

        八、xorm常用操作示例--查询多条数据

        查询多条数据使用Find方法,Find方法的第一个参数为slice的指针或Map指针,即为查询后返回的结果,第二个参数可选,为查询的条件struct的指针。

        8.1 返回结果为 结构体slice:

        everyone := make([]User, 0)
        err := engine.Find(&everyone)

        8.2 返回结果为 结构体map:

        users := make(map[int64]User)
        err := engine.Find(&users)

        九、xorm常用操作示例--FindAndCount 分页

        FindAndCount 返回结果为 结构体slice 以及总数:

        everyone := make([]User, 0)
        count,err := engine.Limit(1,20).FindAndCount(&everyone)

        十、xorm常用操作示例--事务操作

        func TestTransaction(t *testing.T) {
            engine, _, _ := NewMysqlClient()
            session := engine.NewSession()
            defer session.Close()
            if err := session.Begin(); err != nil {
                fmt.Println(err)
                return
            }
            if _, err := session.Insert(&User{Name: "11", Status: 0}); err != nil {
                fmt.Println(err)
                _ = session.Rollback()
                return
            }
            _ = session.Commit()
        }

        以上就是详解Go语言如何使用xorm实现读取mysql的详细内容,更多关于Go语言 xorm读取mysql的资料请关注我们其它相关文章!

        0

        精彩评论

        暂无评论...
        验证码 换一张
        取 消

        关注公众号