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/

百亿数据百亿花, 库若恒河沙复沙,Go lang1.18入门精炼教程,由白丁入鸿儒,Go lang数据库操作实践EP12的更多相关文章

  1. 小D课堂 - 零基础入门SpringBoot2.X到实战_第8节 数据库操作之整合Mybaties和事务讲解_32..SpringBoot2.x持久化数据方式介绍

    笔记 1.SpringBoot2.x持久化数据方式介绍          简介:介绍近几年常用的访问数据库的方式和优缺点 1.原始java访问数据库             开发流程麻烦        ...

  2. 从SQL Server到MySQL,近百亿数据量迁移实战

    从SQL Server到MySQL,近百亿数据量迁移实战 狄敬超(3D) 2018-05-29 10:52:48 212 沪江成立于 2001 年,作为较早期的教育学习网站,当时技术选型范围并不大:J ...

  3. Redis基本使用及百亿数据量中的使用技巧分享(附视频地址及观看指南)

    作者:依乐祝 原文地址:https://www.cnblogs.com/yilezhu/p/9941208.html 主讲人:大石头 时间:2018-11-10 晚上20:00 地点:钉钉群(组织代码 ...

  4. [翻译] C# 8.0 新特性 Redis基本使用及百亿数据量中的使用技巧分享(附视频地址及观看指南) 【由浅至深】redis 实现发布订阅的几种方式 .NET Core开发者的福音之玩转Redis的又一傻瓜式神器推荐

    [翻译] C# 8.0 新特性 2018-11-13 17:04 by Rwing, 1179 阅读, 24 评论, 收藏, 编辑 原文: Building C# 8.0[译注:原文主标题如此,但内容 ...

  5. 掌握这些 Redis 技巧,百亿数据量不在话下!

    一.Redis封装架构讲解 实际上NewLife.Redis是一个完整的Redis协议功能的实现,但是Redis的核心功能并没有在这里面,而是在NewLife.Core里面. 这里可以打开看一下,Ne ...

  6. cassandra百亿级数据库迁移实践

    迁移背景 cassandra集群隔段时间出现rt飙高的问题,带来的影响就是请求cassandra短时间内出现大量超时,这个问题发生已经达到了平均两周一次的频率,已经影响到正常业务了.而出现这些问题的原 ...

  7. 【转载】TalkingData首席金融行业专家鲍忠铁:18亿数据解读移动互联网

    http://www.36dsj.com/archives/33417 鲍忠铁:大家下午好! 今天我会讲三个议题,一是用18亿数据解读现在移动互联网的生态圈.二是看看数据有什么样的应用.三是大数据的隐 ...

  8. 万亿数据下Hadoop的核心竞争力

    1.前言 在大数据时代,Hadoop有着得天独厚的优势.然而,每个企业的技术储备和需求特点不同,他们希望从海量的客户数据中挖掘真正的商业价值,像Google.Facebook.Twitter等这样的企 ...

  9. 这么设计,Redis 10亿数据量只需要100MB内存

    本文主要和大家分享一下redis的高级特性:bit位操作. 本文redis试验代码基于如下环境: 操作系统:Mac OS 64位 版本:Redis 5.0.7 64 bit 运行模式:standalo ...

随机推荐

  1. 三面阿里,被Java面试官虐哭!现场还原真实的“被虐”场景

    前言 人人都有大厂梦,我也不例外,从大三开始,就一直想进入阿里工作,大毕竟是大厂,想想也没那么容易,不过好在自己学历还过得去,项目经验也有得讲,所以今年也斗胆尝试了一下,直接就投了阿里云计算.简历是过 ...

  2. unittest自动化测试框架核心要素以及应用

    1. unittest核心要素 unittest介绍 测试框架,不仅仅用于单元测试 python自动的测试包 用法和django.test.TestCase类似 1.1.unitest介绍和核心要素 ...

  3. 微前端(qiankun)主应用共享React组件

    前言 最近需要重构一个老项目,定的方案用微前端去改造.主应用是老的项目,微应用是新的项目,由于重构时间比较紧张,子应用还需要使用父应用的一些组件.过程中遇到一些问题,记录一下. 方案 我们知道qian ...

  4. BUUCTF-另一个世界

    另一个世界 010editor 打开最下方发现011开头字符串,应该是二进制 得到flag 看也有师傅写的是说八个一组转ascii码,现在也不是很理解啥意思.贴一下其他师傅的python脚本,算出的结 ...

  5. Windows 2008R2 IIS环境配置(靶机)

    一.Windows 2008 R2系统安装 VMware Workstation 15安装包 链接:https://pan.baidu.com/s/11sYcZTYPqIV-pyvzo7pWLQ 提取 ...

  6. 又拍云 Redis 的改进之路

    作为推出国内首创可编程 CDN 服务的专业云服务提供商,又拍云利用 CDN 边缘网络规模和性能,允许客户自定义编写规则来满足常用业务场景.而为了保证这些源数据,如边缘重定向.请求限速.自定义错误页面. ...

  7. CentOS7下bash升级

    [1.查看系统版本][root@web ~]# uname -aLinux web 3.10.0-1160.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020 ...

  8. 讲透JAVA Stream的collect用法与原理,远比你想象的更强大

    大家好,又见面了. 在我前面的文章<吃透JAVA的Stream流操作,多年实践总结>中呢,对Stream的整体情况进行了细致全面的讲解,也大概介绍了下结果收集器Collectors的常见用 ...

  9. 【一本通提高博弈论】[ZJOI2009]取石子游戏

    [ZJOI2009]取石子游戏 题目描述 在研究过 Nim 游戏及各种变种之后,Orez 又发现了一种全新的取石子游戏,这个游戏是这样的: 有 n n n 堆石子,将这 n n n 堆石子摆成一排.游 ...

  10. 循环数组%操作下的一些解释(对于4.4UVA133的一些解释)

    1.循环数组一般不推荐通过建立相同的数组不断叠加来实现,虽然理论上是可行的,但是会浪费极大的空间,特别是对于大数据的情况下,程序一般会马上挂掉 2.循环数组的结构表示中的一种常用形式就是通过取余操作来 ...