32

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

 4 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.

准备

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等。改天会写下教程。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK