【笔记】Go语言操作Mysql数据库

前言

Go语言操作Mysql数据库

下载依赖

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

引入模块

1
2
3
4
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
)

连接数据库

<username>:用户名
<password>:密码
<host>:数据库地址
<port>:数据库端口
<database>:需要连接的数据库名

1
db, err := sql.Open("mysql", "<username>:<password>@tcp(<host>:<port>)/<database>")

执行SQL

<sql>:SQL语句

1
_, err := db.Exec("<sql>")
  • 通过?作为可变参数的占位符

即便占位符得到的数据是字符串,也不要用成对的单引号将占位符引起来

1
_, err := db.Exec("SELECT * FROM user WHERE username=?", "name")

其他数据库的占位符

MySQL:?
PostgreSQL:$1
SQLite:?$1
Oracle::name

新增数据

  • 如果新增数据成功,可以获取id字段
1
2
result, err := db.Exec("INSERT INTO user VALUES(null, username, password)")
id, err := result.LastInsertId()

修改数据

  • 如果修改数据成功,可以获取受影响的行数
1
2
result, err := db.Exec("UPDATE user SET key=value")
rows, err := result.RowsAffected()

删除数据

  • 如果删除数据成功,可以获取受影响的行数
1
2
result, err := db.Exec("DELETE FROM user WHERE key=value")
rows, err := result.RowsAffected()

执行有数据返回的SQL

查询单条数据

  • 在执行Scan()函数后,会自动将数据库连接放回池中
  • 根据SELECT后拼接的字段名,按顺序解析结果,要注意使用对应的数据类型
1
2
3
4
var username string
var password string
row := db.QueryRow("SELECT username, password FROM user WHERE id=1")
row.Scan(username, password)
1
2
3
var username string
var password string
row := db.QueryRow("SELECT username, password FROM user WHERE id=1").Scan(username, password)
  • 也可以将结果直接封装到结构体

查询多条数据

执行查询语句

1
2
rows, err := db.Query("SELECT username, password FROM user")
defer rows.Close()

创建结构体

  • 创建映射数据表的结构体
1
2
3
4
type User struct {
Username string
Password string
}

遍历查询结果集

  • 将结果集封装到结构体中
1
2
3
4
for rows.Next() {
user := new(User)
err := rows.Scan(&user.Username, $user.Password)
}

设置数据库连接池最大连接数

<num>:最大连接数,大于0且小于最大闲置连接数

1
db.SetMaxOpenConns(<num>)

设置数据库连接池最大闲置连接数

  • 将不使用的连接自动关闭
1
db.SetMaxIdleConns(<num>)

封装数据库获取连接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package tool

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

var db *sql.DB

// 初始化数据库连接
func DatabaseInit() (err error) {
// 获取配置文件
cfg := GetConfig()
// 获取数据库连接
db, err = sql.Open("mysql", "<username>:<password>@tcp(<ip>:<port>)/<database>")
if err != nil {
fmt.Println("数据库初始化时DSN格式有误")
return err
}
// 尝试与数据库建立连接,检测密码是否正确
err = db.Ping()
if err != nil {
fmt.Println("数据库初始化时登录失败")
return err
}
fmt.Println("连接数据库成功")
return
}

// 获取数据库连接
func DatabaseGetConnect() *sql.DB {
if db != nil {
return db
}
err := DatabaseInit()
if err != nil {
return nil
}
return db
}

Go语言实现Mysql预处理

  • 提前让服务器编译SQL,一次编译多次执行,提升性能
  • 避免SQL注入问题
1
2
3
4
5
6
7
8
9
10
// 先编译SQL
stmt, err := db.Perpare("SELECT * FROM user WHERE username=?")
defer stms.Close()
// 再添加参数
rows, err := stmt.Query("user")
defer rows.Close()
for rows.Next() {
var user User
err := rows.Scan(&user.username)
}

Go语言实现Mysql事务

1
2
3
4
5
6
7
8
9
// 开启事务
tx, err := db.Begin()
result, err := tx.Exec("<sql>")
if err != nil {
// 回滚事务
tx.Rollback()
}
// 提交事务
err = tx.Commit()

完成

参考文献

哔哩哔哩——80技术
哔哩哔哩——地鼠文档