go 原生提供了对数据库的支持,就是 database/sql 包,对关系型的数据库进行了通用的抽象,轻量、面向行的接口,所以使用这个包还需要下载对相应的数据库驱动,比如 mysql 的驱动包 github.com/go-sql-driver/mysql,执行:

由于不需要调用驱动包的含糊,只需要其执行一次 init 函数,imoprt 部分往往是:

不引入驱动,调用 sql 包的函数的时候会收到提示:

为什么引入 mysql 的包后就可以工作了呢?  这是因为 mysql 包里的 init 函数里执行了 sql.Register 函数:

查看 Register 函数的实现,会发现内部把驱动类型和驱动实例做了一个映射保存在 drivers 中,对 MySQLDriver 来说,就是 "mysql" => &MySQLDriver{},Register 函数的第二个参数是 driver.Driver 接口对象,它只要求实现 1 个方法:

Open 函数返回一个 driver.Conn 对象,根据注释得知该 Conn 对象在同一时间只会被一个 goroutine 所占用,通过查看 MySQLDriver 的 Open 函数发现它使用了内部的 connector 对象来实现,而 connector 对象又将功能更委托给了 mysqlConn 对象,该连接对象负责和 mysql 之间交互的协议。

sql 包使用 sql.Open 来获得一个数据库操作对象 sql.DB,而这个 DB 结构体中最重要的就是 driver.Connector,它要求实现 2 个方法:

1. Connect(context.Context) (Conn, error)

2. Driver() Driver

问题是这个 sql.Open 里的 connector 是怎么和 mysql 驱动的 connector 连接上的呢? F12 进入 sql.Open 函数,发现它会尝试从 dirvers 获取 MySQLDriver 的实例,尝试转换成 driver.DriverContext 后调用其 OpenConnector 函数,如果转换失败了也会构造一个内部的 dsnconnector 对象,调用 driver 上的 Open 方法。

而 MySQLDriver 对 Open 和 OpenConnector 都提供了实现:

sql 包依靠 Open、Register 2 个函数实现了驱动包的注入,获得 driver.Conn 对象后,主要工作就是解析 sql 查询和获得结果了(mysql 交互协议),因为查询通常分为 2 种类型:

1. query 查询带结果,比如 select 等

2. exec 只需执行,比如 update、delete 等

具体 sql 包在调用时会尝试把 driver.Conn 对象转换成 Queryer、QueryerContext 和 Execer、ExecerContext 执行其对应的方法,不过这一切使用 sql.DB 做为中间对象来操作,在 DB 内部它对 driver.Conn 对象做了进一层带锁的包装 driverConn,在任何查询前都会使用 db.conn 内部方法里获取 driverConn,它从加锁以后从 freeConn 里取出一个并标记为 inUse 在使用,否则就检测是否达到最大连接数,没有就就调用 connector 对象的 Connect 方法获得 driver.Conn 后构造一个新的 driverConn,用完了后都会调用它的 relaseConn 把连接对象重新 put 回 freeConn 列表里。至此,go sql 驱动包的加载和执行的流程都清楚了。

mysql 的 go hello 版本如下:

批量查询和会用预编译的查询:

怎么遍历 rows 呢? 需要使用 Next() 来判断,当遇到 io.EOF 或者 rows 被 close 会结束遍历。

插入时使用 LastInsertId 来获取最后一行的 id:

使用 begin 和 beginTx 开启一个事务,begin 使用默认的 context.Background() 来调用 beginTx,事务会独占数据库连接,但是 Tx 对象上的方法和 sql.DB 都是一一对应,调用 commit 或者 rollback 后,Tx 对象才被 Close 掉。

NULL 字段有时候会很麻烦,处理 NULL 有两个办法:

1. 使用数据库函数 COALESCE 让可能 NULL 的字段不可能返回 NULL

2. 使用 sql.NullString、sql.NullInt32 等类型

对于第二种办法,Scan 操作后需要先用 Valid 判断一下,为 true 则调用 String 或者 Value 方法,值得注意的并没有 sql.NullUint32 等类型,可以自定义 NULL  类型,实现 Scan 和 Value 方法。比如 NullInt32 的实现如下:

如你所见,上面的 Scan 的用法其实非常的不方便,实际项目里用 struct tag + orm 来做比较多,下面是使用 sqlx (go get https://github.com/jmoiron/sqlx) 的例子:

除了好用的 Get、Select、StructScan,还有 MapScan、SliceScan 分别对应 map[string]interface{} 和 []interface{},如果需要数据库 ORM 可以关注下 https://github.com/go-gorm/gorm。

本章节的代码 https://github.com/developdeveloper/go-demo/tree/master/22-access-rdb-sql

mysql用大白话解释_大白话 golang 教程-22-关系型数据库访问相关推荐

  1. mysql用大白话解释_大白话解释给小白如何看别人的源码(一)数据库部分

    1.解决数据库还原问题. 为什么要把这个东西放到最前面来说呢,因为很多项目如果没有数据,就是白扯.尤其是web项目.我在看了几位大佬的源码以后,我发现很多大佬都喜欢用sql脚本来还原数据库,很多人刚入 ...

  2. mysql用大白话解释_Java基础--2021Java面试题系列教程--大白话解读

    前言 序言 再高大上的框架,也需要扎实的基础才能玩转,高频面试问题更是基础中的高频实战要点. 适合阅读人群 Java 学习者和爱好者,有一定工作经验的技术人,准面试官等. 阅读建议 本教程是系列教程, ...

  3. golang mysql连接池原理_[Go] golang实现mysql连接池

    golang中连接mysql数据库,需要使用一个第三方类库github.com/go-sql-driver/mysql,在这个类库中就实现了mysql的连接池,并且只需要设置两个参数就可以实现 一般连 ...

  4. mysql 游戏服务器设计_游戏服务器之基于文件数据库和mysql数据库的db服务器设计...

    设计上: (1)文件数据库是用于处理游戏逻辑业务请求. (2)mysql数据库是用于处理运营后台查询请求. (3)备份业务是用于定时备份文件数据库文件. 本文目录: 1.角色数据更新请求 2.mysq ...

  5. mysql数据库模型相应解释_数据库事务系列-MySQL跨行事务模型

    说来和MySQL倒是有缘,毕业的第一份工作就被分配到了RDS团队,主要负责把MySQL弄到云上做成数据库服务.虽说整天和MySQL打交道,但说实话那段时间并没有很深入的理解MySQL内核,做的事情基本 ...

  6. 用大白话解释什么是Socket

    好好学习,天天向上 本文已收录至我的Github仓库DayDayUP:github.com/RobodLee/DayDayUP,欢迎Star,更多文章请前往:目录导航 前言 我在去年就学习过Java中 ...

  7. mysql使用psm登录_倾向匹配得分教程(附PSM操作应用、平衡性检验、共同取值范围、​核密度函数图)...

    原标题:倾向匹配得分教程(附PSM操作应用.平衡性检验.共同取值范围.​核密度函数图) 本文主要包括倾向匹配得分命令简介.语法格式.倾向匹配得分操作步骤 思路,涉及倾向匹配得分应用.平衡性检验.共同取 ...

  8. [转载] 用大白话解释Java的方法重载和方法覆盖

    参考链接: Java中方法重载的不同方法 本文原创首发CSDN,本文链接https://blog.csdn.net/qq_41464123/article/details/107656852 ,作者博 ...

  9. 用大白话解释“什么是ERP?” 看完这篇就全明白了

    ERP的本质就是信息集成 信息集成是指同样的数据或者信息不再需要第二个部门.或者其他任何员工再重复录入一遍. 原则就是:信息来源唯一,而不是多头的. 这也就是在一些书中定义: ERP是企业内部所有业务 ...

最新文章

  1. Altium Designer /DXP无网络铺铜:
  2. 从0开始学Java——@override的作用
  3. 怎样调整XenServer下面Linux虚拟机的磁盘大小
  4. 高德推出查岗功能_新型「查岗」工具?高德推出「家人地图」新功能
  5. 一分钟了解react
  6. [收藏]实践参考:parted创建硬盘分区并创建LVM
  7. H.264标准(二)FLV封装格式详解
  8. windows VC++获取磁盘名称和序列号
  9. android绘图软件推荐,动漫绘画辅助软件有哪些-7款绘画软件推荐
  10. Metasplotable3 简易安装教程
  11. 数据挖掘导论课后习题答案-第二章
  12. MacBook安装jdk8
  13. 脑电和脑磁图的非线性动力学分析
  14. cad卸载_解决CAD小白入门的第一个难题,三招任你选
  15. mysql系列之十一许可更新及对象搜索
  16. 泛泰长短信修改教程(供其他泛泰机型参考)
  17. 关于n阶线性齐次常微分的特征方程特征根相同时解的推导
  18. 计时+事件倒计时网页源码分享
  19. T-SQL动态查询(2)——关键字查询
  20. 理解 Visual Studio 解决方案文件格式(.sln)

热门文章

  1. Project 'king.commons' is missing required library: 'lib/plweb.jar' Build path Build Path Problem
  2. 从学校到现在的一个总结
  3. linux 环境变量设置错误导致 command not found
  4. 双启利器EasyBCD帮你找回消失了的Windows
  5. 利用python编写祝福_手把手|教你用Python换个姿势,送狗年祝福语
  6. 从零开始学前端:复习课程 --- 今天你学习了吗?(CSS:Day11)
  7. 希尔排序不稳定例子_Python实现希尔排序(已编程实现)
  8. 微课|中学生可以这样学Python(例4.2):打印九九乘法表
  9. Python内置函数max()高级用法
  10. java mian 方法_Java mian函数