Golang能够通过Gorm包来操作数据库,所谓ORM,即Object Relational Mapping(数据关系映射),说白了就是通过模式化的语法来操作数据库的行对象或者表对象,比照绝对灵便简约的SQL语句,ORM上手简略,通用性较高,然而在性能层面略有损耗,Gorm的底层是构造体对象,对于构造体,请移玉步至:你有对象类,我有构造体,Go lang1.18入门精炼教程,由白丁入鸿儒,go lang构造体(struct)的应用EP06。

Gorm的装置与配置

首先如果要应用Gorm操作数据库,得先有数据库才行,这里为了全平台统一标准,咱们应用Docker来装置Mysql数据库,Docker的装置请参见:一寸宕机一寸血,十万容器十万兵|Win10/Mac零碎下基于Kubernetes(k8s)搭建Gunicorn+Flask高可用Web集群,运行命令运行mysql容器:

docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -d mysql:8.0.19

留神这里如果宿主机曾经有Mysql服务了,须要将:右边的端口号错开,改成3307或者其余什么端口。

随后在终端运行命令装置Gorm包:

go get -u github.com/jinzhu/gorm

这里-u参数的意思是为以后用户装置,并不局限于某个我的项目。

随后装置Mysql数据库链接驱动包:

go get -u github.com/go-sql-driver/mysql

接着在任意地位编写test.go脚本:

package main    import (      "fmt"      "github.com/jinzhu/gorm"      _ "github.com/jinzhu/gorm/dialects/mysql"  )    func main() {      db, err := gorm.Open("mysql", "root:root@(localhost)/mytest?charset=utf8mb4&parseTime=True&loc=Local")        if err != nil {                fmt.Println(err)               fmt.Println("连贯数据库出错")          return      }        defer db.Close()        fmt.Println("链接Mysql胜利")  }

这里导入输入包和Gorm包,同时通过下划线的模式导入mysql驱动包,这样做的益处是mysql驱动的init()函数会在被导入时执行,因为咱们并不需要驱动包的具体模块或者函数,而仅仅是用它连一下数据库而已。

随后,创立构造体变量db,留神Open函数对应的Mysql参数是否正确。

留神,构造体变量赋值过程中如果报错,须要判断err变量内容,并且应用return关键字提前结束逻辑,对于golang的错误处理,可参见:人非圣贤孰能无过,Go lang1.18入门精炼教程,由白丁入鸿儒,Go lang错误处理机制EP11

最初,应用defer关键字在所有逻辑执行后敞开Mysql数据库链接。

编译执行后,程序返回:

链接Mysql胜利

当然Gorm并不仅仅只能操作Mysql,其余支流数据库也都反对,比方说Sqllite3,事实上,在老本无限或者缓存体系比拟齐备的状况下,Sqllite3齐全能够代替Mysql,首先装置sqllite3驱动:

go get -u github.com/jinzhu/gorm/dialects/sqlite

而后批改test.go文件:

package main    import (      "fmt"        "github.com/jinzhu/gorm"      //_ "github.com/jinzhu/gorm/dialects/mysql"      _ "github.com/jinzhu/gorm/dialects/sqlite"  )    func main() {      //db, err := gorm.Open("mysql", "root:root@(localhost)/mytest?charset=utf8mb4&parseTime=True&loc=Local")        db, err := gorm.Open("sqlite3", "/tmp/gorm.db")        if err != nil {          fmt.Println(err)          fmt.Println("连贯数据库出错")          return      }        defer db.Close()        fmt.Println("链接sqllite3胜利")  }

编译执行后返回:

链接sqllite3胜利

数据库操作

连贯好数据库之后,咱们就能够做一些数据库层面的操作了,比方程序层面的数据库迁徙操作:

// 文章信息  type ArticleInfo struct {      ID     uint      Title  string      Author string  }

这里建设文章表的构造体数据,随后编写迁徙逻辑:

//数据迁徙  db.AutoMigrate(&ArticleInfo{})  fmt.Println("表创立胜利")

进入Mysql命令行,输出命令:

MySQL [(none)]> use mytest;  Database changed  MySQL [mytest]> desc article_infos      -> ;  +--------+------------------+------+-----+---------+----------------+  | Field  | Type             | Null | Key | Default | Extra          |  +--------+------------------+------+-----+---------+----------------+  | id     | int(10) unsigned | NO   | PRI | NULL    | auto_increment |  | title  | varchar(255)     | YES  |     | NULL    |                |  | author | varchar(255)     | YES  |     | NULL    |                |  +--------+------------------+------+-----+---------+----------------+  3 rows in set (0.03 sec)    MySQL [mytest]>

没有问题。

创立数据:

a1 := ArticleInfo{1, "iris", "iris"}  a2 := ArticleInfo{2, "iris", "女"}  // 创立记录  db.Create(&a1)  db.Create(&a2)

这里咱们申明两个构造体变量,而后将其指针传递给db变量的Create函数,编译运行后,键入命令进行查问操作:

MySQL [mytest]> select * from article_infos\g  +----+-------+--------+  | id | title | author |  +----+-------+--------+  |  1 | iris  | iris   |  |  2 | iris  | 女     |  +----+-------+--------+

随后,将方才入库的数据查问进去:

// 查问  a := new(ArticleInfo)  db.First(a)  fmt.Println(a)

这里通过new关键字初始化构造体,而后应用First函数获取第一条记录。

程序返回:

链接mysql胜利  &{1 iris iris}

查出来的构造体指针能够间接用来做批改操作:

// 查问      a := new(ArticleInfo)      db.First(a)      fmt.Println(a)        //批改      db.Model(&a).Update("Author", "123")        fmt.Println(a)

程序返回:

链接mysql胜利  &{1 iris iris}  &{1 iris 123}

十分不便。

最初,是删除操作:

// 删除  db.Delete(&a)

这里通过指针传入Delete函数即可:

MySQL [mytest]> select * from article_infos\g  +----+-------+--------+  | id | title | author |  +----+-------+--------+  |  2 | iris  | 女     |

该条记录曾经被物理删除。

执行原生SQL

如果咱们须要执行原生的sql语句,Gorm也提供了对应的函数:

var articles []ArticleInfo  //   查问 执行用Scan 和Find 一样  db = db.Raw("select * from article_infos ").Scan(&articles)  fmt.Println(articles)

这里只须要申明文章的构造体变量,而后执行Scan函数即可:

[{2 iris 女} {3 iris iris} {4 iris 女}]

这里会返回一个切片嵌套构造体的后果集。

除此之外,更新和删除操作:

//  更新和删除.插入用 Exec  db = db.Exec("update article_infos set author='123' where id = 2")  fmt.Println("更新了", db.RowsAffected, "条数据")  db = db.Exec("delete from article_infos where id=4")  fmt.Println("更新了", db.RowsAffected, "条数据")

程序返回:

[]main.ArticleInfo更新了 1 条数据  更新了 1 条数据

结语

目前Golang的比拟风行的ORM包除了Gorm,还有Xorm,比照Python数据库ORM的百花齐放,百家争鸣,Go lang还有很长的一段路须要走,实在环境下的数据库操作也不仅仅是增删改查,更多操作请移步Gorm官网文档:https://gorm.io/zh\_CN/docs/