Go使用MySQL数据库

312 阅读2分钟

简介

Go官方并不提供数据库驱动,而只是为开发数据库驱动定义了一些标准接口。我们操作MySQL数据库得需要使用第三方维护的MySQL驱动,推荐使用github.com/go-sql-driver/mysql,主要理由如下:

  • 维护的比较好
  • 完全支持database/sql接口
  • 支持keepalive,保持长连接

有了驱动,其实Go使用MySQL和其他语言差不多,只是具体的方法调用和API组织结构不太一样。

准备工作

use golang;

CREATE TABLE `user` (
	`id` int(11) NOT NULL AUTO_INCREMENT,
	`username` varchar(100) NOT NULL DEFAULT '' COMMENT '用户名',
	`email` varchar(50) NOT NULL DEFAULT '' COMMENT '用户邮箱',
	`ctime` int(11) NOT NULL COMMENT '创建时间',
	`utime` int(11) NOT NULL COMMENT '更新时间',
	PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

先通过ssh登录服务器(因为安全考虑,不开放MySQL的root用户的远程登录权限),用root用户本地登录mysql新建一个用于测试的可远程登录的用户:

mysql> GRANT ALL PRIVILEGES ON golang.* to 'golang'@'%' IDENTIFIED BY '123456';
mysql> GRANT ALL PRIVILEGES ON golang.* to 'golang'@'localhost' IDENTIFIED BY '123456';
mysql> FLUSH PRIVILEGES;

接下来就可以通过golang用户登录新建的数据库进行操作了。

操作MySQL

先get数据库驱动,命令行运行go get github.com/go-sql-driver/mysql会自动将驱动下载到$GOPATH/src中。

package main

import (
	"database/sql"
	"fmt"
	"time"

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

func checkError(e error) {
	if e != nil {
		panic(e)
	}
}

func main() {
	// 打开MySQL连接
	db, err := sql.Open("mysql", "golang:123456@tcp(127.0.0.1:3306)/golang?charset=utf8")
	checkError(err)
	fmt.Println("connected")
	// ?为占位符,防止SQL注入
	stmt, err := db.Prepare("insert into user(username, gender, email, ctime, utime) values(?, ?, ?, ?, ?)")
	checkError(err)
	timestamp := time.Now().Unix()
	// 向占位符传参,Exec是一个不定参数函数,传入的参数与Prepare阶段设置的占位符相等
	res, err := stmt.Exec("zhangsan", 1, "zhangsan@qq.com", timestamp, timestamp)
	checkError(err)
	// 获取生成的数据id
	id, err := res.LastInsertId()
	checkError(err)
	fmt.Println(id)

	stmt, err = db.Prepare("update user set email=? where id=?")
	checkError(err)
	res, err = stmt.Exec("zhangsan@163.com", id)
	checkError(err)
	aff, err := res.RowsAffected()
	checkError(err)
	fmt.Println("affected", aff)

	rows, err := db.Query("select id, username, email from user")
	for rows.Next() {
		var id int
		var username string
		var email string
		err = rows.Scan(&id, &username, &email)
		checkError(err)
		fmt.Println(id, username, email)
	}

	stmt, _ = db.Prepare("delete from user where id>?")
	res, _ = stmt.Exec(1)
	aff, _ = res.RowsAffected()
	fmt.Println("affected", aff)
}

整个数据库操作的流程大概如下:

  • sql.Open()函数用来打开一个注册过的数据库驱动;
  • db.Prepare()函数用来返回准备要执行的sql操作,然后返回准备完毕的执行状态;
  • stmt.Exec()函数用来执行stmt准备好的SQL语句;
  • db.Query()函数用来直接执行Sql返回Rows结果。

数据库驱动的注册在数据库驱动包导入时执行,注册的逻辑写在包的init函数中。导入驱动包只需要import _ "driver/package",只需要执行其init(),而不需要调用包中导出的方法,调用的是Go语言规定的sql接口。