36

golang 操作mysql示例(增、删、改、查、事务)

 5 years ago
source link: https://studygolang.com/articles/26458
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的系统包里是没有数据库驱动的,首先先从git上下载mysql包,golang下载资源包相当方便,打开命令行,输入命令: go get -u github.com/go-sql-driver/mysql (使用git命令下载资源包,需要先安装git,没安装git的同学可以手动下载后放入src目录下)。!

ZBRVfmM.png!web

下载完成会在GOPATH下的src里多了资源包

732eMbA.png!web

下载完成后,在项目里import mysql包,用下划线_是表示我们只需要用到包里的init()函数,而不需要调用里面的方法。

import (  
    "database/sql"  
    "fmt"  
    _ "github.com/go-sql-driver/mysql" //导入mysql包  
    "time"  
)

准备数据表

我们来准备一张医生表doctor_tb,包含姓名、年龄、性别、添加时间等,后面我们会对这张表做增删改查的操作。建表语句如下:

CREATE TABLE `doctor_tb` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) DEFAULT '' COMMENT '姓名',
  `age` int(11) DEFAULT '0' COMMENT '年龄',
  `sex` int(11) DEFAULT '0' COMMENT '性别',
  `addTime` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='医生表';

1、打开数据库链接

db, err := sql.Open("mysql", "root:112233@tcp(127.0.0.1:3305)/test?charset=utf8&parseTime=True")
mysql数据库的链接字符串组织: 用户名:密码@tcp(数据库IP:端口)/数据库名?charset=utf8&parseTime=True ,如果你的表里有应用到datetime字段,记得要加上parseTime=True,不然解析不了这个类型。

//-------1、打开数据库--------  
db, err := sql.Open("mysql", "root:112233@tcp(127.0.0.1:3305)/test?charset=utf8&parseTime=True")  
if err != nil {  
   fmt.Println("数据库链接错误", err)  
   return  
}  
//延迟到函数结束关闭链接  
defer db.Close()

2、查询单条数据

代码:

//-------2、查询单条数据--------  
//定义接收数据的结构  
var doc Doctor  
//执行单条查询  
rows := db.QueryRow("select * from doctor_tb where id = ?", 1)  
rows.Scan(&doc.ID, &doc.Name, &doc.Age, &doc.Sex, &doc.AddTime)  
fmt.Println("单条数据结果:", doc)

执行结果:

nMbQ3me.png!web

解析:

查询id=1的数据

rows := db.QueryRow("select * from doctor_tb where id = ?", 1)

rows.Scan 用于把读取的数据赋值到Doctor对象的属性上,要注意字段顺序。

3、查询数据列表

代码:

//-------3、查询数据列表--------  
rows2, err := db.Query("select * from doctor_tb where age > ?", 18)  
if err != nil {  
   fmt.Println("多条数据查询错误", err)  
   return  
}  
//定义对象数组,用于接收数据  
var docList []Doctor  
for rows2.Next() {  
    var doc2 Doctor  
    rows2.Scan(&doc2.ID, &doc2.Name, &doc2.Age, &doc2.Sex, &doc2.AddTime)  
    //加入数组  
    docList = append(docList, doc2)  
}  
fmt.Println("多条数据查询结果", docList)

执行结果:

3uIBNrn.png!web

解析:

查询年龄age大于18岁的成年医生

rows2, err := db.Query("select * from doctor_tb where age > ?", 18)

迭代数据查询

rows2.Next()

赋值

rows2.Scan(&doc2.ID, &doc2.Name, &doc2.Age, &doc2.Sex, &doc2.AddTime)

加入数组

docList = append(docList, doc2)

4、新增数据

代码:

//-------4、新增数据--------  
result, err := db.Exec("insert into doctor_tb(name,age,sex,addTime) values(?,?,?,Now())", "林医生", 40, 2)
if err != nil {  
   fmt.Println("新增数据错误", err)  
   return  
}  
newID, _ := result.LastInsertId() //新增数据的ID  
i, _ := result.RowsAffected()     //受影响行数  
fmt.Printf("新增的数据ID:%d , 受影响行数:%d \n", newID, i)

执行结果:

yIBVnqf.png!web

解析:

新增一位40岁的女性林医生

result, err := db.Exec("insert into doctor_tb(name,age,sex,addTime) values(?,?,?,Now())", "林医生", 40, 2)

新增数据的ID

result.LastInsertId()

受影响行数

result.RowsAffected()

5、修改数据

代码:

//-------5、修改数据--------  
result2, err := db.Exec("update doctor_tb set age=20 where id = ?", 1)  
if err != nil {  
   fmt.Println("修改数据错误", err)  
   return  
}  
i2, _ := result2.RowsAffected() //受影响行数  
fmt.Printf("受影响行数:%d \n", i2)

执行结果:

i6rqEzQ.png!web

解析:

编号为1的医生年龄变为20岁

result2, err := db.Exec("update doctor_tb set age=20 where id = ?", 1)

6、删除数据

代码:

//-------6、删除数据--------  
result3, err := db.Exec("delete from doctor_tb where name = ?", "叶子")  
if err != nil {  
   fmt.Println("删除数据错误", err)  
   return  
}  
i3, _ := result3.RowsAffected()  
fmt.Printf("受影响行数:%d \n", i3)

执行结果:

i6rqEzQ.png!web

解析:

删除姓名叫叶子的医生

result3, err := db.Exec("delete from doctor_tb where name = ?", "叶子")

7、事务

代码:

//-------7、事务\--------  
tx, _ := db.Begin()  
result4, _ := tx.Exec("update doctor_tb set age = age + 1 where name = ?", "钟南山")  
result5, _ := tx.Exec("update doctor_tb set age = age + 1 where name = ?", "叶子")  
  
//影响行数,为0则失败
i4, _ := result4.RowsAffected()  
i5, _ := result5.RowsAffected()  
if i4 > 0 && i5 > 0 {  
   //2条数据都更新成功才提交事务  
  err = tx.Commit()  
   if err != nil {  
      fmt.Println("事务提交失败", err)  
      return  
  }  
   fmt.Println("事务提交成功")  
} else {  
   //否则回退事务  
  err = tx.Rollback()  
   if err != nil {  
      fmt.Println("回退事务失败", err)  
      return  
  }  
   fmt.Println("回退事务成功")  
}

执行结果:

z6nUJ3E.png!web

解析:

准备事务

tx, _ := db.Begin()

钟南山年龄加1岁

result4, _ := tx.Exec("update doctor_tb set age = age + 1 where name = ?", "钟南山")

叶子年龄加1岁

result5, _ := tx.Exec("update doctor_tb set age = age + 1 where name = ?", "叶子")

如果2条数据更新能成功则提交事务

err = tx.Commit()

否则回退事务,一切就当没发生过

tx.Rollback()

完整demo代码

package main  
  
import (  
    "database/sql"  
    "fmt"  
    _ "github.com/go-sql-driver/mysql" //导入mysql包  
    "time"  
)  
  
type Doctor struct {  
   ID      int64  
   Name    string  
   Age     int  
   Sex     int  
   AddTime time.Time  
}  
  
func main() {  
 //-------1、打开数据库--------  
  db, err := sql.Open("mysql", "root:112233@tcp(127.0.0.1:3305)/test?charset=utf8&parseTime=True")  
   if err != nil {  
      fmt.Println("数据库链接错误", err)  
      return  
  }  
   //延迟到函数结束关闭链接  
  defer db.Close()  
  
   //-------2、查询单条数据--------  
 //定义接收数据的结构  
  var doc Doctor  
  //执行单条查询  
  rows := db.QueryRow("select * from doctor_tb where id = ?", 1)  
   rows.Scan(&doc.ID, &doc.Name, &doc.Age, &doc.Sex, &doc.AddTime)  
   fmt.Println("单条数据结果:", doc)  
  
   //-------3、查询数据列表--------  
  rows2, err := db.Query("select * from doctor_tb where age > ?", 18)  
   if err != nil {  
      fmt.Println("多条数据查询错误", err)  
      return  
  }  
   //定义对象数组,用于接收数据  
  var docList []Doctor  
  for rows2.Next() {  
      var doc2 Doctor  
  rows2.Scan(&doc2.ID, &doc2.Name, &doc2.Age, &doc2.Sex, &doc2.AddTime)  
      //加入数组  
  docList = append(docList, doc2)  
   }  
   fmt.Println("多条数据查询结果", docList)  
  
   //-------4、新增数据--------  
  result, err := db.Exec("insert into doctor_tb(name,age,sex,addTime) values(?,?,?,Now())", "林医生", 40, 2)  
   if err != nil {  
      fmt.Println("新增数据错误", err)  
      return  
  }  
   newID, _ := result.LastInsertId() //新增数据的ID  
  i, _ := result.RowsAffected()     //受影响行数  
  fmt.Printf("新增的数据ID:%d , 受影响行数:%d \n", newID, i)  
  
   //-------5、修改数据--------  
  result2, err := db.Exec("update doctor_tb set age=20 where id = ?", 1)  
   if err != nil {  
      fmt.Println("修改数据错误", err)  
      return  
  }  
   i2, _ := result2.RowsAffected() //受影响行数  
  fmt.Printf("受影响行数:%d \n", i2)  
  
   //-------6、删除数据--------  
  result3, err := db.Exec("delete from doctor_tb where name = ?", "叶子")  
   if err != nil {  
      fmt.Println("删除数据错误", err)  
      return  
  }  
   i3, _ := result3.RowsAffected()  
   fmt.Printf("受影响行数:%d \\n", i3)  
  
   //-------7、事务--------  
  tx, _ := db.Begin()  
   result4, _ := tx.Exec("update doctor_tb set age = age + 1 where name = ?", "钟南山")  
   result5, _ := tx.Exec("update doctor_tb set age = age + 1 where name = ?", "叶子")  
  
   //影响行数,为0则失败  
   i4, _ := result4.RowsAffected()  
   i5, _ := result5.RowsAffected()  
   if i4 > 0 && i5 > 0 {  
      //2条数据都更新成功才提交事务  
  err = tx.Commit()  
      if err != nil {  
         fmt.Println("事务提交失败", err)  
         return  
  }  
      fmt.Println("事务提交成功")  
   } else {  
      //否则回退事务  
  err = tx.Rollback()  
      if err != nil {  
         fmt.Println("回退事务失败", err)  
         return  
  }  
      fmt.Println("回退事务成功")  
   }  
}

总结

以上就是golang操作mysql的示例。当然还有很多优秀的golang的orm能更方便于我们日常的业务开发,例如grom,xorm等。改天会写下教程。


Recommend

  • 45
    • studygolang.com 6 years ago
    • Cache

    golang gorm 操作mysql

    golang 官方的那个操作mysql的有点麻烦所以就使用了gorm,下面就gorm的使用做下简单介绍 下载gorm: go get -u github.com/jinzhu/gorm 在项目中引入gorm: import ( "github.com/jinzhu/...

  • 21
    • studygolang.com 5 years ago
    • Cache

    golang 使用xorm操作mysql

    xorm 官方介绍:xorm是一个简单而强大的Go语言ORM库. 通过它可以使数据库操作非常简便。xorm的目标并不是让你完全不去学习SQL,我们认为SQL并不会为ORM所替代,但是ORM将可以解决绝大部分的简单SQL需求。xorm支持两种风格的...

  • 34
    • studygolang.com 4 years ago
    • Cache

    Go 语言操作 MySQL 之 事务操作

    友情提示:此篇文章大约需要阅读 5分钟 9秒,不足之处请多指教,感谢你的阅读。 订阅本站 事务 数据库事务( transaction )是访问并可能操作各种...

  • 29
    • studygolang.com 4 years ago
    • Cache

    golang gorm(一)---gorm入门示例

    gorm是go语言的一个orm框架,框架的原理和思想在这里就不做详细介绍了,我主要演示一下gorm的实际使用。 开启mysql连接 主要用到 gorm.open()这个方法 //参数含义:数据库用户名、密码、主...

  • 8

    Edge实现NodeJS与.NET互操作(包括UI界面示例)

  • 2
    • segmentfault.com 3 years ago
    • Cache

    go操作elasticsearch示例

    go操作elasticsearch示例这里我使用elasticsearch官方给的go语言包(

  • 19
    • segmentfault.com 3 years ago
    • Cache

    golang操作MySQL数据库总结

    golang操作MySQL数据库总结本文视频链接:https://www.bilibili.com/vide...关注公众号,下载课程资料和源...

  • 8
    • blog.51cto.com 3 years ago
    • Cache

    golang实现grpc的tcp示例

    golang实现grpc的tcp示例 原创 panguixiang 2022-04-21 16:46:39 ©...

  • 4
    • xiusin.github.io 3 years ago
    • Cache

    Golang AST语法树使用教程及示例

    Golang AST语法树使用教程及示例 2019-11-11 许多自动化代码生成工具都离不开语法树分析,例如goimport,gomock,

  • 8
    • ljlu1504.github.io 2 years ago
    • Cache

    go代码示例:操作文件获取路径目录

    go代码示例:操作文件获取路径目录 评分: 4.5 作者: Ryan Lu 类别: golang

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK