0 简介
Go 语言中
- database/sql包定义了对数据库的一系列操作
- database/sql/driver包定义了应被数据库驱动实现的接口,这些接口会被 sql 包使用。
- 但是 Go 语言没有提供任何官方的数据库驱动,所以我们需要导入第三方的数据库驱动。
- 连接数据库之后对数据库操作的大部分代码都使用 sql 包
1 获取数据库连接
package utils
import (
"database/sql"
_ "go-sql-driver/mysql"
)
var (
Db *sql.DB
err error
)
func init() {
Db, err = sql.Open("mysql", "root:123456@tcp(localhost:3306)/mydata")
if err != nil {
panic(err.Error())
}
}
- 第一步:创建utils文件夹下的test.go,导入 database/sql 包以及第三方驱动包go-sql-driver/mysql(导入goroot下的src)
- 第二步:定义两个全局变量
- 第三步:创建 init 函数,在函数体中调用 sql 包的 Open 函数获取连接
2 增删改操作
- 第一步: 在mysql数据库中创建表,在Navicat可视化如下:
- 第二步: 创建model文件夹下user.go文件,prepare方法 或者 直接执行方法
package model
import (
"fmt"
"go/testsql1206/utils"
)
type firsts struct {
num string
name string
class string
}
//AddUser1 添加user way1
func (user *firsts) AddUser1() error {
//xie yu ju
sqlStr := "insert into users(num,name,class) values(?,?,?)"
//yubianyi
inStmt, err := utils.Db.Prepare(sqlStr)
if err != nil {
fmt.Println("yubianyi yi chang", err)
return err
}
//zhixing
_, err2 := inStmt.Exec("149064340", "admin", "5")
if err2 != nil {
fmt.Println("zhixing yi chang", err2)
return err2
}
return nil
}
//AddUser2 添加user way1
func (user *firsts) AddUser2() error {
//xie yu ju
sqlStr := "insert into users(num,name,class) values(?,?,?)"
_, err := utils.Db.Exec(sqlStr, "149064430", "admin_fu", "6")
if err != nil {
fmt.Println("zhixing yi chang", err)
return err
}
return nil
}
方法一:
方法二:
3 单元测试
单元测试( unit test),就是一种为验证单元的正确性而设置的自动化测试,一个单元就是程序中的一个模块化部分。一般来说,一个单元通常会与程序中的一个函数或者一个方法相对应, 但这并不是必须的。
Go 的单元测试需要用到
- testing 包
- go test 命令
而且对测试文件也有以下要求:
- 被测试的源文件和测试文件必须位于同一个包下
- 测试文件必须要以 _test.go 结尾
- 虽然 Go 对测试文件_test.go 的前缀没有强制要求,不过一般我们都设置为被测试的文件的文件名,如:要对 user.go 进行测试,那么测试文件的名字我们通常设置为 user_test.go
- 测试文件中的测试函数为 TestXxx(t *testing.T)
- 其中 Xxx 的首字母必须是大写的英文字母
- 函数参数必须是 test.T 的指针类型(Benchmark 测试则参数是
testing.B 的指针类型),main则是m类型)
package model
import (
"fmt"
"testing"
)
func TestAddUser(t *testing.T) {
fmt.Println("test add user ing...")
user := &firsts{}
user.AddUser1()
user.AddUser2()
}
选择终端,采用go test 或者 go test -v,即可查看测试结果
直接测试则以大写的TestXxx写函数即可,若希望自己定义方法然后进行测试,则采用run方法
即:如果一个测试函数的函数名的不是以 Test 开头,那么在使用 go test 命令时默认不会执行,不过我们可以设置该函数是一个子测试函数,可以在其他测试函数里通过 t.Run 方法来执行子测试函数,具体代码如下
package model
import (
"fmt"
"testing"
)
func TestUser(t *testing.T) {
fmt.Println("test main pro...")
t.Run("test add ing...", testAddUser)
}
func testAddUser(t *testing.T) {
fmt.Println("test add user ing...")
user := &firsts{}
user.AddUser1()
user.AddUser2()
}
我们还可以通过 TestMain(m *testing.M)函数在测试之前和之后做一些其他的操作
package model
import (
"fmt"
"testing"
)
func TestMain(m *testing.M) {
fmt.Println("ceshi kaishi:")
m.Run()
}
func TestUser(t *testing.T) {
fmt.Println("test main pro...")
t.Run("test add ing...", testAddUser)
}
func testAddUser(t *testing.T) {
fmt.Println("test add user ing...")
user := &firsts{}
user.AddUser1()
user.AddUser2()
}
4 查询一条数据
func (user *firsts) GetUserByNum() (*firsts, error) {
sqlStr := "select num,name,class from users where num = ?"
row := utils.Db.QueryRow(sqlStr, user.num)
var num1 string
var name1 string
var class1 string
err := row.Scan(&num1, &name1, &class1)
if err != nil {
return nil, err
}
u := &firsts{
num: num1,
name: name1,
class: class1,
}
return u, nil
}
5 获取多条记录
从数据库中查询出所有的记录
func (user *firsts) GetAllUserByNum() ([]*firsts, error) {
sqlStr := "select num,name,class from users"
rows, err := utils.Db.Query(sqlStr)
if err != nil {
return nil, err
}
//create return slice
var userslice []*firsts
for rows.Next() {
var num1 string
var name1 string
var class1 string
err := rows.Scan(&num1, &name1, &class1)
if err != nil {
return nil, err
}
u := &firsts{
num: num1,
name: name1,
class: class1,
}
userslice = append(userslice, u)
}
return userslice, nil
}
总代码
user.go
package model
import (
"fmt"
"go/testsql1206/utils"
)
type firsts struct {
num string
name string
class string
}
//AddUser1 添加user way1
func (user *firsts) AddUser1() error {
//xie yu ju
sqlStr := "insert into users(num,name,class) values(?,?,?)"
//yubianyi
inStmt, err := utils.Db.Prepare(sqlStr)
if err != nil {
fmt.Println("yubianyi yi chang", err)
return err
}
//zhixing
_, err2 := inStmt.Exec("149064340", "admin", "5")
if err2 != nil {
fmt.Println("zhixing yi chang", err2)
return err2
}
return nil
}
//AddUser2 添加user way1
func (user *firsts) AddUser2() error {
//xie yu ju
sqlStr := "insert into users(num,name,class) values(?,?,?)"
_, err := utils.Db.Exec(sqlStr, "149064430", "admin_fu", "6")
if err != nil {
fmt.Println("zhixing yi chang", err)
return err
}
return nil
}
//get 1 id
func (user *firsts) GetUserByNum() (*firsts, error) {
sqlStr := "select num,name,class from users where num = ?"
row := utils.Db.QueryRow(sqlStr, user.num)
var num1 string
var name1 string
var class1 string
err := row.Scan(&num1, &name1, &class1)
if err != nil {
return nil, err
}
u := &firsts{
num: num1,
name: name1,
class: class1,
}
return u, nil
}
//get all id
func (user *firsts) GetAllUserByNum() ([]*firsts, error) {
sqlStr := "select num,name,class from users"
rows, err := utils.Db.Query(sqlStr)
if err != nil {
return nil, err
}
//create return slice
var userslice []*firsts
for rows.Next() {
var num1 string
var name1 string
var class1 string
err := rows.Scan(&num1, &name1, &class1)
if err != nil {
return nil, err
}
u := &firsts{
num: num1,
name: name1,
class: class1,
}
userslice = append(userslice, u)
}
return userslice, nil
}
user_test.go
package model
import (
"fmt"
"testing"
)
func TestMain(m *testing.M) {
fmt.Println("ceshi kaishi:")
m.Run()
}
func TestUser(t *testing.T) {
fmt.Println("test main pro...")
//t.Run("test add ing...", testAddUser)
//t.Run("test add ing...", testGetUserByNum)testGetAllUserByNum
t.Run("test add ing...", testGetAllUserByNum)
}
//直接测试则以Test开头
//如果测试函数想要用自己的方法,则不Test开头,以t.run方法进行测试
func testAddUser(t *testing.T) {
fmt.Println("test add user ing...")
//user := &firsts{}
//
//user.AddUser1()
//user.AddUser2()
}
func testGetUserByNum(t *testing.T) {
fmt.Println("query 1 ")
user := firsts{
num: "149064392",
}
u, _ := user.GetUserByNum()
fmt.Println("get : ", u)
}
func testGetAllUserByNum(t *testing.T) {
fmt.Println("query all")
user := &firsts{}
us, _ := user.GetAllUserByNum()
for k, v := range us {
fmt.Printf("num: %v is %v \n", k+1, v)
}
}
utils下的go文件
package utils
import (
"database/sql"
_ "go-sql-driver/mysql"
)
var (
Db *sql.DB
err error
)
func init() {
Db, err = sql.Open("mysql", "root:123456@tcp(localhost:3306)/mydata")
if err != nil {
panic(err.Error())
}
}