首先安装mysql
安装完成后,为了能够使得golang使用mysql 我们需要导入一个包,这个包可以在golang.org官网中找到,具体链接为
https://pkg.go.dev/github.com/go-sql-driver/mysql#section-readme
包的指令为
$ go get -u github.com/go-sql-driver/mysql
当我们安装好包了以后 就可以在项目中引用了,具体的引用方式为
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
因为我们只需要使用该包中的init方法,所以我们就使用下划线导入的方式
我们先在终端创建一个数据库
mysql -uroot -p //进入数据库命令行
create database go_db //创建名为go_db的数据库
use go_db //使用数据库
create table user_tbl//创建一个名为user_tbl的表
Go MySQL Driver是 Godatabase/sql/driver接口的实现。您只需导入驱动程序,即可使用完整的database/sqlAPI。
import (
"database/sql"
"time"
_ "github.com/go-sql-driver/mysql"
)
// ...
db, err := sql.Open("mysql", "user:password@/dbname")
if err != nil {
panic(err)
}
// See "Important settings" section.
db.SetConnMaxLifetime(time.Minute * 3)
db.SetMaxOpenConns(10)
db.SetMaxIdleConns(10)
db.SetConnMaxLifetime():因为mysql服务器、操作系统或者是其他的中间件关闭之前,我们要保证我们数据的安全,而中间件一般会设置在五分钟之后关闭,所以我们建议将此方法参数传递在五分钟之内,该设置对负载平衡和更改系统变量也很有帮助
db.SetMaxOpenConns():官方强烈建议限制应用程序的连接数量,但是没有明确的规定,因为这取决于应用程序以及sql服务器的性能
db.SetMaxIdleConns():很类似或者是优于上面的那个方法,但如果参数数量小于上一个的时候,关闭和打开的频率会更高
var db *sql.DB
func initDB() (err error) {
dsn := "root:1296729980@tcp(127.0.0.1:3306)/go_db"
db, err = sql.Open("mysql", dsn)
if err != nil {
return err
}
err = db.Ping()
if err != nil {
return err
}
return nil
}
DSN是数据源名称,具有自己的通用格式,格式为:
[username[:password]@][protocol[(address)]]/dbname[?param1=value1&…¶mN=valueN]
完整的DSN格式为
username:password@protocol(address)/dbname?param=value
这其中所有的参数除了数据库名称之外都是可选的 所以最小的DSN为
/dbname
func insert() {
s := "insert into user_tbl (username,password) values(?,?)"
r, err := db.Exec(s, "zhangsan", "zs123")
if err != nil {
fmt.Printf("err: %v\n", err)
} else {
i, _ := r.LastInsertId()
fmt.Printf("i: %v\n", i)
}
}
单行查询
type USER struct {
id int
username string
password string
}
func queryOneRow() {
s := "select * from user_tbl where id = ?"
var u USER
err := db.QueryRow(s, 1).Scan(&u.id, &u.username, &u.password)
if err != nil {
fmt.Printf("err: %v\n", err)
} else {
fmt.Printf("u: %v\n", u)
}
}
QueryRow代表着单行查询,第二个参数就是查询第几行,返回的查询数据为u,参数为查询参数
查询多行
func queryOneSome() {
s := "select * from user_tbl"
r, err := db.Query(s)
var u USER
// defer r.Close()
if err != nil {
fmt.Printf("err: %v\n", err)
} else {
for r.Next() {
r.Scan(&u.id, &u.username, &u.password)
fmt.Printf("u: %v\n", u)
}
}
}
在查询多行时,Query的sql语句参数就不用使用where,Query方法会返回两个值,第一个是行数,第二个是错误信息,建议在结束之前关闭
defer r.Close()
func queryUpdate() {
s := "update user_tbl set username=?,password=? where id=?"
r, err := db.Exec(s, "new kate", "123123", "2")
if err != nil {
fmt.Printf("err: %v\n", err)
} else {
i, _ := r.RowsAffected()
fmt.Printf("i: %v\n", i)
}
}
我们通过id来寻找更改哪一条数据,db.Exec返回两个数据,第一个为sql.Result,使用第一个数据调用RowsAffected()我们可以很清晰的获得更改的哪一行的数据
func queryDelete() {
s := "delete from user_tbl where id=?"
r, err := db.Exec(s, 3)
if err != nil {
fmt.Printf("err: %v\n", err)
} else {
i, _ := r.RowsAffected()
fmt.Printf("i: %v\n", i)
}
}
删除数据和更新数据非常相似,只是我们的sql语句调用方式不同,返回的依然是影响了几行 而不是第几行 db.Exec中跟随的参数是你想删除的id为多少,如果没有可以删除的id ,那么r.RowsAffected()返回的为0