golang操作mysql

首先安装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包的用法

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&…&paramN=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

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐