Go语言操作MySQL语言基础知识

数据库 MySQL
本次主要讲述了Go如何操作Mysql,如何进行增删改查,最后还讲了以下什么是事物,如何操作事物。

 前言

通常情况下,我们程序员和数据库打交道是最多的。要然我们怎么会被称为码农呢。

存用户信息需要数据库,存订单需要数据库,等等等等,现在真是数据驱动着发展。

但是数据库种类有很多,有Mysql,Oracle,SQL Server。

本篇就示例如何Go操作Mysql。

准备工作

本次使用的是go mod进行包依赖管理,还不会使用的向上爬梯子,找go mod用法。

使用的库是第三方库go-sql-driver/mysql。

准备工作之连接数据库

代码

  1. func main() { 
  2.     var username = "root" 
  3.     var password = "rootroot" 
  4.     var ip = "127.0.0.1" 
  5.     var port = "3306" 
  6.     var data = "go_mysql_demo" 
  7.     var dsn = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s", username, password, ip, port, data) 
  8.     //Open只会验证dsb的格式是否正确,不会验证是否连接成功,同理,密码是否正确也不知道 
  9.     db, err := sql.Open("mysql", dsn) 
  10.     if err != nil { 
  11.         panic(err) 
  12.     //关闭连接在 err 之后,因为可能直接就打开不成功,关闭一个没有打开的连接??? 
  13.     defer db.Close() 
  14.     // 此时尝试连接数据库,会判断用户,密码,ip地址,端口是否正确 
  15.     err = db.Ping() 
  16.     if err != nil { 
  17.         fmt.Println("连接数据库失败,",err) 
  18.         return 
  19.     //设置与数据库建立连接的最大数目,一般不管 
  20.     db.SetMaxOpenConns(100) 
  21.     //设置连接池中的最大闲置连接数,一般不管 
  22.     db.SetMaxIdleConns(50) 

注意

  • sql.Open只会验证格式是否正确,不会连接数据库。
  • db.Close在err之后,是因为可能打开不成功,关闭一个没有打开的连接。
  • db.Ping会连接数据库,判断用户,密码,ip地址,端口是否正确。

准备工作之创建表

我们创建一个简单的用户表。

  1. CREATE TABLE `userinfo` ( 
  2.   `id` int(11) NOT NULL AUTO_INCREMENT, 
  3.   `namevarchar(10) DEFAULT NULL, 
  4.   `phone` char(11) DEFAULT NULL, 
  5.   `address` varchar(64) DEFAULT NULL, 
  6.   PRIMARY KEY (`id`) 
  7. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 

准备工作之创建结构体

假设上述工作都完成了啊。

不知道有没有想过,我们查询的数据,存成啥?,字符串?map?切片?,似乎都不是太好。

只有结构体是最清晰的,最好认识的。

结构体

  1. type Userinfo struct { 
  2.     Id      int64  `json:"id"
  3.     Name    string `json:"name"
  4.     Phone   string `json:"phone"
  5.     Address string `json:"address"

查询单条

单条查询使用QueryRow方法。

代码

  1. //查询单条 
  2. sqlStr := "SELECT id,`name`,phone,address from userinfo where id = ?;" 
  3. var user Userinfo 
  4. /* 
  5.     QueryRow 第二个参数可以接收多个参数,同理,sqlStr可以有多个 ?占位符 进行匹配 
  6.     QueryRow 之后必须调用Scan方法进行数据绑定,进行数据库链接释放 
  7. */ 
  8. err = db.QueryRow(sqlStr, 1).Scan(&user.Id, &user.Name, &user.Phone, &user.Address) 
  9. if err != nil { 
  10.     fmt.Println("查询失败", err) 
  11.     return 
  12. fmt.Println(user

执行结果


查询多条

多行查询使用Query。

代码

  1. //查询多条 
  2. sqlStr := "SELECT id,`name`,phone,address from userinfo where id >= ?" 
  3. //参数同 QueryRow 
  4. rows, err := db.Query(sqlStr, 1) 
  5. if err != nil { 
  6.     fmt.Println("查询失败:", err) 
  7.     return 
  8. // 此处使用rows释放所有链接 
  9. defer rows.Close() 
  10. //循环整理所有数据 
  11. var userList = make([]Userinfo, 0, 10) 
  12. for rows.Next() { 
  13. var user Userinfo 
  14. err = rows.Scan(&user.Id, &user.Name, &user.Phone, &user.Address) 
  15. if err != nil { 
  16.     fmt.Println("绑定数据失败", err) 
  17.     return 
  18. userList = append(userList, user
  19. fmt.Println(userList) 

执行结果


插入数据

插入数据需要用到Exec。

代码

  1. //插入数据 
  2. sqlStr := "INSERT into userinfo(name,phone,address) values(?,?,?);" 
  3. result, err := db.Exec(sqlStr, "吴彦祖", 555, "不知道哪的"
  4. if err != nil { 
  5.     fmt.Println("插入失败", err) 
  6.     return 
  7. //受影响的行数 
  8. row_affect, err := result.RowsAffected() 
  9. if err != nil { 
  10.     fmt.Println("受影响行数获取失败:", err) 
  11.     return 
  12. fmt.Println("受影响的行数:", row_affect) 
  13. lastId, err := result.LastInsertId() 
  14. if err != nil { 
  15.     fmt.Println("新增行id获取失败:", err) 
  16.     return 
  17. fmt.Println("新增行id:", lastId) 
  18. fmt.Println("插入成功"

执行结果


Mysql


更新数据

更新和添加差不多,用的都是Exec。

代码

  1. //更新数据 
  2. sqlStr := `UPDATE userinfo set name=? where id=?;` 
  3. result, err := db.Exec(sqlStr, "吴彦祖666", 3) 
  4. if err != nil { 
  5.     fmt.Println("更新失败", err) 
  6.     return 
  7. //受影响的行数 
  8. row_affect, err := result.RowsAffected() 
  9. if err != nil { 
  10.     fmt.Println("受影响行数获取失败:", err) 
  11.     return 
  12. fmt.Println("受影响的行数:", row_affect) 
  13. fmt.Println("更新成功"

执行结果


Mysql


删除数据

删除数据用的还是Exec。

代码

  1. //删除数据 
  2. sqlStr := "delete from userinfo where id = ?;" 
  3. result, err := db.Exec(sqlStr, 3) 
  4. if err != nil { 
  5.     fmt.Println("删除失败", err) 
  6.     return 
  7. //受影响的行数 
  8. row_affect, err := result.RowsAffected() 
  9. if err != nil { 
  10.     fmt.Println("受影响行数获取失败:", err) 
  11.     return 
  12. fmt.Println("受影响的行数:", row_affect) 
  13. fmt.Println("删除成功"

执行结果


Mysql


事物

事物,这个用的就比较多了,通常用在关键的场景。

尤其是转账,张三-10块,李四+10块,这个动作动作是要在一起完成的。

如果任何一个失败了,就要恢复上一次的状态。

我们通常也叫这个操作叫做原子操作,要成功,都成功,要完蛋,都完蛋。

新建表

  1. CREATE TABLE `bill` ( 
  2.   `id` int(11) NOT NULL AUTO_INCREMENT, 
  3.   `namevarchar(8) NOT NULL, 
  4.   `money` int(11) NOT NULL, 
  5.   PRIMARY KEY (`id`) 
  6. ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4; 

表数据

张三和李四都剩余100块


Go Mysql 关于事物相关方法

Go 关于事物有三个方法

  • Begin()开始事物。
  • Commit()提交事物。
  • Rollback()失败回滚。

模拟转账:张三-10块,李四+十块

代码

  1. func main() { 
  2.     //事物 
  3.     //开启事物 
  4.     tx, err := db.Begin() 
  5.     if err != nil { 
  6.         //释放事物 
  7.         if tx != nil { 
  8.             tx.Rollback() 
  9.         } 
  10.         fmt.Println("事物开启失败"
  11.         return 
  12.  
  13.     张三减10块Sql := `UPDATE bill set money=money - 10 where name = ?;` 
  14.     result, err := tx.Exec(张三减10块Sql, "张三"
  15.     if err != nil { 
  16.         //有错误表示更是失败,回滚原来状态 
  17.         tx.Rollback() 
  18.         fmt.Println(err) 
  19.         return 
  20.     张三受影响行数, err := result.RowsAffected() 
  21.     if err != nil { 
  22.         tx.Rollback() // 回滚 
  23.         return 
  24.  
  25.     李四加10块Sql := `UPDATE bill set money=money + 10 where name = ?;` 
  26.     result, err = tx.Exec(李四加10块Sql, "李四"
  27.     if err != nil { 
  28.         //有错误表示更是失败,回滚原来状态 
  29.         tx.Rollback() 
  30.         fmt.Println(err) 
  31.         return 
  32.     李四受影响行数, err := result.RowsAffected() 
  33.     if err != nil { 
  34.         tx.Rollback() // 回滚 
  35.         return 
  36.     //都等于1表示成功,可以提交事务,修改数据 
  37.     if 张三受影响行数==1 && 李四受影响行数==1{ 
  38.         //提交事务 
  39.         fmt.Println("提交事务"
  40.         tx.Commit() 
  41.     }else
  42.         //有一个!=1表示没有更新成功,可能用户不存在 
  43.         fmt.Println("失败了,事物回滚了"
  44.         tx.Rollback() 
  45.     fmt.Println("事物执行成功"

执行结果


Mysql

一加一减


假如出错了


Mysql

如果使用事物,出错了数据还是没变。


总结

本次主要讲述了Go如何操作Mysql,如何进行增删改查,最后还讲了以下什么是事物,如何操作事物。

当然,这种是最原始的方法,过程有些繁琐,了解入门就好,后面还有更方便的方法。

 

责任编辑:姜华 来源: Go语言进阶学习
相关推荐

2024-01-07 19:54:51

2010-01-19 14:45:35

C++语言

2020-07-02 16:20:36

MySQLCURD数据库

2011-07-21 17:18:52

java

2011-07-22 10:38:04

java

2011-07-22 10:02:07

java

2011-07-21 17:33:27

JAVA

2011-07-22 09:43:37

java

2011-07-21 17:45:02

java

2021-01-27 10:01:46

MySQL数据库SQLX

2023-07-03 00:44:26

Go语言MySQL

2023-12-30 10:22:57

Go语言函数开发

2021-04-19 08:35:44

PythonPython语言Python基础

2010-04-13 18:24:14

Unix操作系统

2018-03-12 22:13:46

GO语言编程软件

2010-04-07 15:59:29

Unix操作系统

2021-06-09 09:06:52

Go语言算法

2021-02-06 18:19:54

TimeGo语言

2023-01-31 08:48:49

Go语言文件

2013-04-08 15:52:06

Go语言
点赞
收藏

51CTO技术栈公众号