Go中的MySQL

328 阅读3分钟

这是我参与8月更文挑战的第22天,活动详情查看:8月更文挑战

下载mysql数据库驱动

go get github.com/go-sql-driver/mysql

包的导入

在go中我们在操作数据库时, 不使用驱动提供的方法, 而是使用sql.DB实例提供的方法

因此在导入数据库驱动时使用匿名方式导入

import (
   "database/sql"
   _ "github.com/go-sql-driver/mysql"
)

Go中的sql采用预编译的方式进行sql语句的执行, 这种方式比拼接字符串高效, 可以防止sql注入攻击

sql.DB

提供我们对关系型数据库的访问

提供我们对数据库连接池的管理

var (
	// 定义一个全局sql.DB实例
   db *sql.DB
)

数据库操作流程

  1. sql.Open打开数据库连接
// 该方法接收一个驱动名称和数据库名称, 返回一个DB实例
func Open(driverName, dataSourceName string) (*DB, error)
  1. 操作数据库, CURD
  2. db.Close关闭数据库连接

打开数据库连接

// 打开数据库
dsn := "root:root@tcp(localhost:3306)/go_mysql?charset=utf8mb4"

// 以什么样的方式打开数据库
dn := "mysql"

// 数据库实例
db1, err := sql.Open(dn, dsn)

// db1为局部变量, 要将它赋值给全局变量db
db = db1

// 数据库打开失败
if err != nil {
   fmt.Println("sql open failed: ", err)
   return
}

// 数据库打开成功
fmt.Println("sql open successed!")

// 关闭数据库
defer func() {
  fmt.Println("sql closed!")
  err := db.Close()
  if err != nil {
  fmt.Println("db close failed: ", err)
  return
  }
}()

添加数据

func insertData() {
   // 添加数据的sql语句
   inSql := "insert user (username, password, age) values (?, ?, ?)"

   // 准备好要执行的sql语句
   stmt, err := db.Prepare(inSql)

   // 关闭stmt
   defer func() {
      fmt.Println("stmt closed!")
      err := stmt.Close()
      if err != nil {
         fmt.Println("stmt close failed: ", err)
         return
      }
   }()

   // 预编译失败
   if err != nil {
      fmt.Println("db prepare failed: ", err)
   }

   // 执行sql语句
   /*
   type Result interface {
      // 添加数据时, 插入当前行时的id
      LastInsertId() (int64, error)

      // 执行语句时受影响的行数
      RowsAffected() (int64, error)
   }
   */
   res, err := stmt.Exec("shaosiming", "123456", 18)

   // 添加数据失败
   if err != nil {
      fmt.Println("insert data failed: ", err)
      return
   }

   // 添加数据成功
   fmt.Println("insert data successed!")

   // 受影响的行数
   rows, _ := res.RowsAffected()
   fmt.Println("受影响行数: ", rows)

   // 添加当前行时, id
   lastId, _ := res.LastInsertId()
   fmt.Println("LastInsertId: ", lastId)
}

删除数据

func deleteData() {

   // 删除数据的sql语句
   deleteSql := "delete from user where username = ?"

   // 预编译
   stmt, err := db.Prepare(deleteSql)

   // 关闭stmt
   defer func() {
      fmt.Println("stmt closed!")
      err := stmt.Close()
      if err != nil {
         fmt.Println("stmt close failed: ", err)
         return
      }
   }()

   // 预编译失败
   if err != nil {
      fmt.Println("db prepare failed: ", err)
      return
   }

   // 以预编译成功, 执行删除语句
   res, err := stmt.Exec("shaosiming")

   // 执行删除语句失败
   if err != nil {
      fmt.Println("delete data failed: ", err)
      return
   }

   // 执行删除语句成功
   fmt.Println("delete data successed!")

   // 受影响的行数
   rows, _ := res.RowsAffected()
   fmt.Println("受影响行数: ", rows)

   lastId, _ := res.LastInsertId()
   fmt.Println("LastInsertId: ", lastId)
}

更新数据

func updateData() {
   // 更新数据的sql语句
   updateSql := "update user set age = ? where username = ?"

   // 预编译
   stmt, err := db.Prepare(updateSql)

   // 关闭stmt
   defer func() {
      fmt.Println("stmt closed!")
      err := stmt.Close()
      if err != nil {
         fmt.Println("stmt close failed: ", err)
         return
      }
   }()

   // 预编译失败
   if err != nil {
      fmt.Println("db prepare failed: ", err)
      return
   }

   // 以预编译成功, 执行更新语句
   res, err := stmt.Exec(20, "shaosiming")

   // 执行更新语句失败
   if err != nil {
      fmt.Println("update data failed: ", err)
      return
   }

   // 执行删除语句成功
   fmt.Println("update data successed!")

   // 受影响的行数
   rows, _ := res.RowsAffected()
   fmt.Println("受影响行数: ", rows)

   lastId, _ := res.LastInsertId()
   fmt.Println("LastInsertId: ", lastId)
}

查找单条数据

func queryFirstData() {
   // 查询一条数据
   qSql := "select username, password, age from user where username = ?"

   // 预执行
   stmt, err := db.Prepare(qSql)

   // 预执行失败
   if err != nil {
      fmt.Println("db prepare failed: ", err)
      return
   }

   // 关闭stmt
   defer func() {
      fmt.Println("stmt closed!")
      err := stmt.Close()
      if err != nil {
         fmt.Println("stmt close failed: ", err)
         return
      }
   }()

   // 执行查询单条数据的sql
   row := stmt.QueryRow("shaosiming")


   var username string
   var password string
   var age int

   // 将查询出来的数据保存到变量中
   err = row.Scan(&username, &password, &age)
   if err != nil {
      fmt.Println("row scan failed: ", err)
   }

   // 输出保存到变量中的数据
   fmt.Println("username: ", username, "password: ", password, "age: ", age)
}

查找多条数据

func queryMultiData()  {
   // 查询语句
   qSql := "select username, password from user where age = ?"

   // 预执行
   stmt, err := db.Prepare(qSql)
   if err != nil {
      fmt.Println("db prepare failed: ", err)
      return
   }

   // 关闭stmt
   defer func() {
      fmt.Println("stmt closed!")
   }()

   // 执行查询语句
   rows, err := stmt.Query(18)
   if err != nil {
      fmt.Println("query data failed: ", err)
   }

   defer func() {
      fmt.Println("rows closed!")
      err := rows.Close()
      if err != nil {
         fmt.Println("rows close failed: ", err)
         return
      }
   }()

   var username string
   var password string

   // 遍历查询出来的多条数据
   for rows.Next() {
      err := rows.Scan(&username, &password)
      if err != nil {
         fmt.Println("scan failed: ", err)
      }
      fmt.Println("username: ", username, ", password: ", password)
   }
}