4

百亿数据百亿花, 库若恒河沙复沙,Go lang1.18入门精炼教程,由白丁入鸿儒,Go lang数...

 2 years ago
source link: https://v3u.cn/a_id_237
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
百亿数据百亿花, 库若恒河沙复沙,Go lang1.18入门精炼教程,由白丁入鸿儒,Go lang数据库操作实践EP12

    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/


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK