当前位置: 首页 > news >正文

golang学习笔记18——golang 访问 mysql 数据库全解析

  • 推荐学习文档
    • golang应用级os框架,欢迎star
    • golang应用级os框架使用案例,欢迎star
    • 案例:基于golang开发的一款超有个性的旅游计划app经历
    • golang实战大纲
    • golang优秀开发常用开源库汇总
    • 想学习更多golang知识,这里有免费的golang学习笔记专栏

文章目录

    • 准备工作
      • 1.安装 MySQL 驱动
      • 2.导入必要的包
    • 建立数据库连接
      • 1.连接字符串
      • 2.建立连接
    • 执行 SQL 查询
      • 1.简单查询示例(查询单条记录)
      • 2.查询多条记录
    • 执行 SQL 更新操作(插入、更新、删除)
      • 1.插入数据示例
      • 2.更新数据示例
      • 3.删除数据示例
    • 事务处理
      • 1.事务的概念
      • 2.示例代码

在现代软件开发中,数据存储和访问是至关重要的环节。MySQL 作为一款流行的关系型数据库,经常需要与各种编程语言进行交互。Golang 以其高效、简洁的特性,在数据库访问方面也有着出色的表现。本文将详细介绍 Golang 如何访问 MySQL 数据库,并配合代码示例进行说明。

准备工作

1.安装 MySQL 驱动

  • 在 Golang 中,要访问 MySQL 数据库,首先需要安装相应的数据库驱动。Go - SQL - Driver 是一个广泛使用的 MySQL 驱动,我们可以使用go get命令来安装它:
     go get -u github.com/go - sql - driver/mysql

2.导入必要的包

  • 在 Go 代码中,我们需要导入database/sql包和刚刚安装的 MySQL 驱动包:
     import ("database/sql""fmt""github.com/go - sql - driver/mysql")

建立数据库连接

1.连接字符串

  • 连接 MySQL 数据库需要构建一个连接字符串,它包含了数据库的相关信息,如用户名、密码、主机地址、端口号和数据库名等。连接字符串的格式如下:
     user:password@tcp(127.0.0.1:3306)/your_database?charset=utf8mb4&parseTime=True&loc=Local
  • 其中,user是 MySQL 的用户名,password是对应的密码,tcp(127.0.0.1:3306)表示数据库的主机地址(这里是本地地址和默认端口),your_database是要连接的数据库名称,charset=utf8mb4指定字符集,parseTime=True用于自动解析时间类型,loc = Local设置时区。

2.建立连接

  • 使用sql.Open函数来打开一个数据库连接,它返回一个*sql.DB对象和一个可能的错误:
     func main() {db, err := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/your_database?charset=utf8mb4&parseTime=True&loc=Local")if err!= nil {fmt.Println("数据库连接失败:", err)return}defer db.Close()}
  • 这里的defer db.Close()语句确保在函数结束时关闭数据库连接,以释放资源。

执行 SQL 查询

1.简单查询示例(查询单条记录)

  • 以下是一个查询数据库中一条记录的示例。假设我们有一个名为users的表,包含id、name和age列:
     func main() {// 建立数据库连接db, err := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/your_database?charset=utf8mb4&parseTime=True&loc=Local")if err!= nil {fmt.Println("数据库连接失败:", err)return}defer db.Close()// 查询语句var name stringvar age interr = db.QueryRow("SELECT name, age FROM users WHERE id = 1").Scan(&name, &age)if err!= nil {fmt.Println("查询失败:", err)return}fmt.Printf("姓名: %s, 年龄: %d\n", name, age)}
  • 在这个示例中,我们使用QueryRow函数执行查询语句,它返回一个*sql.Row对象。然后使用Scan方法将查询结果映射到我们定义的变量name和age上。

2.查询多条记录

  • 当需要查询多条记录时,我们使用Query函数。以下是一个查询users表中所有记录的示例:
     func main() {db, err := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/your_database?charset=utf8mb4&parseTime=True&loc=Local")if err!= nil {fmt.Println("数据库连接失败:", err)return}defer db.Close()rows, err := db.Query("SELECT name, age FROM users")if err!= nil {fmt.Println("查询失败:", err)return}defer rows.Close()for rows.Next() {var name stringvar age interr = rows.Scan(&name, &age)if err!= nil {fmt.Println("扫描结果失败:", err)return}fmt.Printf("姓名: %s, 年龄: %d\n", name, age)}if err = rows.Err(); err!= nil {fmt.Println("迭代结果集时出错:", err)}}
  • 这里我们首先使用Query函数得到一个*sql.Rows对象,然后使用Next方法遍历结果集,通过Scan方法获取每一行的数据。最后,我们使用rows.Err()检查在遍历过程中是否出现错误。

执行 SQL 更新操作(插入、更新、删除)

1.插入数据示例

  • 假设我们要向users表中插入一条新记录:
     func main() {db, err := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/your_database?charset=utf8mb4&parseTime=True&loc=Local")if err!= nil {fmt.Println("数据库连接失败:", err)return}defer db.Close()// 插入语句result, err := db.Exec("INSERT INTO users (name, age) VALUES ('John', 25)")if err!= nil {fmt.Println("插入失败:", err)return}id, err := result.LastInsertId()if err!= nil {fmt.Println("获取插入的ID失败:", err)return}fmt.Printf("插入成功, 新记录的ID: %d\n", id)}
  • 在这个示例中,我们使用Exec函数执行插入语句,它返回一个sql.Result对象。我们可以通过LastInsertId方法获取新插入记录的自增 ID。

2.更新数据示例

  • 以下是更新users表中一条记录的示例:
     func main() {db, err := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/your_database?charset=utf8mb4&parseTime=True&loc=Local")if err!= nil {fmt.Println("数据库连接失败:", err)return}defer db.Close()// 更新语句result, err := db.Exec("UPDATE users SET age = 26 WHERE id = 1")if err!= nil {fmt.Println("更新失败:", err)return}rowsAffected, err := result.RowsAffected()if err!= nil {fmt.Println("获取受影响的行数失败:", err)return}fmt.Printf("更新成功, 受影响的行数: %d\n", rowsAffected)}
  • 这里使用Exec函数执行更新语句,通过RowsAffected方法获取更新操作影响的行数。

3.删除数据示例

  • 假设要删除users表中的一条记录:
     func main() {db, err := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/your_database?charset=utf8mb4&parseTime=True&loc=Local")if err!= nil {fmt.Println("数据库连接失败:", err)return}defer db.Close()// 删除语句result, err := db.Exec("DELETE FROM users WHERE id = 1")if err!= nil {fmt.Println("删除失败:", err)return}rowsAffected, err := result.RowsAffected()if err!= nil {fmt.Println("获取受影响的行数失败:", err)return}fmt.Printf("删除成功, 受影响的行数: %d\n", rowsAffected)}
  • 同样使用Exec函数执行删除语句,并通过RowsAffected方法获取受影响的行数。

事务处理

1.事务的概念

  • 事务是一组数据库操作,这些操作要么全部成功执行,要么全部失败回滚。在 Golang 中,我们可以方便地使用Begin、Commit和Rollback方法来处理事务。

2.示例代码

  • 以下是一个事务处理的示例,假设我们要向users表中插入两条记录,如果其中一条插入失败,则回滚整个操作:
     func main() {db, err := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/your_database?charset=utf8mb4&parseTime=True&loc=Local")if err!= nil {fmt.Println("数据库连接失败:", err)return}defer db.Close()tx, err := db.Begin()if err!= nil {fmt.Println("开始事务失败:", err)return}// 插入第一条记录_, err = tx.Exec("INSERT INTO users (name, age) VALUES ('Alice', 22)")if err!= nil {// 如果插入失败,回滚事务tx.Rollback()fmt.Println("插入第一条记录失败:", err)return}// 插入第二条记录_, err = tx.Exec("INSERT INTO users (name, age) VALUES ('Bob', 23)")if err!= nil {// 如果插入失败,回滚事务tx.Rollback()fmt.Println("插入第二条记录失败:", err)return}// 提交事务tx.Commit()fmt.Println("两条记录插入成功")}
  • 在这个示例中,我们首先使用Begin方法开始一个事务,得到一个*sql.Tx对象。然后执行两条插入语句,如果其中任何一条出现错误,我们使用Rollback方法回滚事务。如果两条插入语句都成功执行,我们使用Commit方法提交事务。

通过以上步骤,我们可以在 Golang 中有效地访问 MySQL 数据库,进行各种查询和操作。在实际应用中,我们可以根据具体的业务需求灵活运用这些方法,构建强大而高效的数据库应用程序。

关注我看更多有意思的文章哦!👉👉

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Amoco:一款针对二进制源码的安全分析工具
  • HC-SR04超声波传感器详解(STM32)
  • scantf
  • k8s介绍及部署
  • 【Kubernetes】常见面试题汇总(二十四)
  • PWN二进制安全修仙秘籍【第一章#工具篇01】WLS配置tmux分屏、oh-my-zsh命令补全
  • SOCKS4和SOCKS5的区别是什么?
  • Redis Universe: 探索无边界的数据处理星系
  • 上线跨境电商商城的步骤
  • 百度起诉知名站长工具5118
  • SEAFARING靶场漏洞攻略
  • STM32中的计时与延时
  • 多旅行商问题:鹈鹕优化算法(Pelican Optimization Algorithm,POA)求解多仓库多旅行商问题MD-MTSP(提供Matlab代码)
  • 1. 如何在Java中连接MySQL数据库?请解释使用JDBC连接的步骤。
  • 模拟+分类讨论,LeetCode 2332. 坐上公交的最晚时间
  • 2017-09-12 前端日报
  • Apache的基本使用
  • JS 面试题总结
  • PHP的Ev教程三(Periodic watcher)
  • 对话:中国为什么有前途/ 写给中国的经济学
  • 回顾 Swift 多平台移植进度 #2
  • 坑!为什么View.startAnimation不起作用?
  • 前端技术周刊 2019-01-14:客户端存储
  • 使用iElevator.js模拟segmentfault的文章标题导航
  • 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)
  • 学习笔记:对象,原型和继承(1)
  • 用jquery写贪吃蛇
  • 在electron中实现跨域请求,无需更改服务器端设置
  • 自制字幕遮挡器
  • 深度学习之轻量级神经网络在TWS蓝牙音频处理器上的部署
  • d²y/dx²; 偏导数问题 请问f1 f2是什么意思
  • ​中南建设2022年半年报“韧”字当头,经营性现金流持续为正​
  • # Swust 12th acm 邀请赛# [ E ] 01 String [题解]
  • ###51单片机学习(1)-----单片机烧录软件的使用,以及如何建立一个工程项目
  • #QT(TCP网络编程-服务端)
  • #单片机(TB6600驱动42步进电机)
  • (1综述)从零开始的嵌入式图像图像处理(PI+QT+OpenCV)实战演练
  • (2)Java 简介
  • (HAL库版)freeRTOS移植STMF103
  • (超详细)2-YOLOV5改进-添加SimAM注意力机制
  • (二)【Jmeter】专栏实战项目靶场drupal部署
  • (二)WCF的Binding模型
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (附源码)ssm经济信息门户网站 毕业设计 141634
  • (附源码)计算机毕业设计ssm高校《大学语文》课程作业在线管理系统
  • (三十)Flask之wtforms库【剖析源码上篇】
  • (四)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (一)C语言之入门:使用Visual Studio Community 2022运行hello world
  • (原創) 系統分析和系統設計有什麼差別? (OO)
  • (转)GCC在C语言中内嵌汇编 asm __volatile__
  • (转)JVM内存分配 -Xms128m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=512m
  • (转)自己动手搭建Nginx+memcache+xdebug+php运行环境绿色版 For windows版
  • ..回顾17,展望18
  • .bat文件调用java类的main方法
  • .NET CORE 2.0发布后没有 VIEWS视图页面文件