最近要做个数据库课设,就打算用 Golang 来做个 RESTful 后端,就来学学怎么用 Golang 操作 MariaDB

准备工作

下载驱动

我们需要让 Golang 能够与 MariaDB/MySQL 进行交互,因此要下载与其匹配的数据库驱动。这里我使用的是 Go-MySQL-Driver

安装 go-mysql-driver :

1
$ go get -u github.com/go-sql-driver/mysql

引用驱动包

下载之后,我们需要在 Go 中引用相关数据库驱动包:

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

连接数据库

使用 sql.Open() 来连接数据库,并通过 .SetMaxIdleConns().SetMaxOpenConns() 指定最大连接数。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
db, err := sql.Open("mysql", "root:@tcp(127.0.0.1:3306)/pdbs_course")

if err != nil {
	panic(err.Error())
}

defer db.Close()

db.SetMaxIdleConns(20)
db.SetMaxOpenConns(20)

if err := db.Ping(); err != nil{
	log.Fatalln(err)
} else {
	fmt.Println("Connection successful!")
}

数据库操作

由于是为了测试基本 CRUD 功能,因此我们使其一个测试用的数据库及测试表。

1
2
3
4
5
6
func checkTable(db *sql.DB) {
	db.Exec("create database if not exists pdbs_course")
	fmt.Println("Database checked!")
	db.Exec("create table if not exists test_go_sql(id int primary key, number char(9), name char(10))")
	fmt.Println("Table checked!")
}

新增记录

我们来增加一条数据,执行的就是基本的 INSERT 语句:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
func Create (db *sql.DB, id int, number string, name string) int {
	statement, err := db.Prepare("insert into test_go_sql(id, number, name) values (?, ?, ?)")
	if err != nil {
		log.Fatal(err.Error())
	}
	res, err := statement.Exec(id, number, name)
	if err != nil {
		log.Fatal(err.Error())
	}
	cur_id, err := res.LastInsertId()
	if err != nil {
		log.Fatal(err.Error())
	}
	return int(cur_id)
}

查找记录

使用 .Query() 和基本 SELECT 语句进行查找,这里要注意,使用 .Scan() 进行扫描的时候最好要使用 sql 库中的 Null 系列类型,否则提取时遇到 NULL 会报错。

忽略 Error 也是一种解决方案,但是得到的值就是默认值,无法分辨 NULL,不建议。

 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
type record struct {
	id int
	number sql.NullString
	name sql.NullString
}

func Retrive (db *sql.DB, id int) {
	rows, err := db.Query("select * from test_go_sql where id = ? ", id)
	if err != nil {
		panic(err.Error())
	}
	defer rows.Close()

	var rec record

	for rows.Next() {
		err = rows.Scan(&rec.id, &rec.number, &rec.name)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(rec.id, rec.number.String, rec.name.String)
	}
	if err != nil {
		log.Fatal(err)
	}
}

更改记录

更改一条数据,使用基本的 UPDATE 语句:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
func Update (db *sql.DB, id int, number string, name string) int {

	stmt, err := db.Prepare("update test_go_sql set number = ?, name = ? where id = ?")
	if err != nil {
		log.Fatal(err)
	}
	res, err := stmt.Exec(number, name, id)
	if err != nil {
		log.Fatal(err)
	}
	num, err := res.RowsAffected()
	if err != nil {
		log.Fatal(err)
	}
	return int(num)
}

删除记录

删除一条记录,使用 DELETE 语句:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
func Delete (db *sql.DB, id int) int {
	stmt, err := db.Prepare("delete from test_go_sql where id = ?")
	if err != nil {
		log.Fatal(err)
	}
	res, err := stmt.Exec(id)
	if err != nil {
		log.Fatal(err)
	}
	num, err := res.RowsAffected()
	if err != nil {
		log.Fatal(err)
	}
	return int(num)
}

总结

其实 go-mysql-driver 还是很简单易用的,常用的就以下几个 API :

方法作用
.Exec()在数据库中执行指定指令
.Prepare()准备要执行的指令
.Query()查询操作,可返回集合

全部代码:


知识共享许可协议
本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。