欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

goweb-mysql连接

程序员文章站 2022-04-30 12:03:09
操作 数据库 Go 语言中的 database/sql 包定义了对数据库的一系列操作。database/sql/driver 包定义了应被数据库驱动实现的接口,这些接口会被 sql 包使用。但是 Go 语言没有提 供任何官方的数据库驱动,所以我们需要导入第三方的数据库驱动。不过我们连接数据 库之后对 ......

操作 数据库

go 语言中的 database/sql 包定义了对数据库的一系列操作。database/sql/driver
包定义了应被数据库驱动实现的接口,这些接口会被 sql 包使用。但是 go 语言没有提
供任何官方的数据库驱动,所以我们需要导入第三方的数据库驱动。不过我们连接数据
库之后对数据库操作的大部分代码都使用 sql 包。

获取数据库连接

open 函数的说明

  • 参数 datasourcename 的格式:
    数据库用户名:数据库密码@[tcp(localhost:3306)]/数据库名
  • open 函数可能只是验证其参数,而不创建与数据库的连接。如果要检查数据
    源的名称是否合法,应调用返回值的 ping 方法。
  • 返回的 db 可以安全的被多个 go 程同时使用,并会维护自身的闲置连接池。
    这样一来,open 函数只需调用一次。很少需要关闭 db
package utils

import (
    "database/sql"

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

var (
    db  *sql.db
    err error
)

func init() {
    db, err = sql.open("mysql", "root:ygj1007502524@tcp(localhost:3306)/test")
    if err != nil {
        panic(err.error())
    }
}

增删改操作

在连接的 test 数据库中创建一个 users 表

create table users(
id int primary key auto_increment,
username varchar(100) unique not null,
password varchar(100) not null,
email varchar(100)
)

向 users 表中插入记录

package model

import (
    "fmt"
    "go_code/go-web/day01/web01_db/utils"
)

//user 结构体
type user struct {
    id       int
    username string
    password string
    email    string
}

//adduser 添加user的方法一
func (user *user) adduser() error {
    //1.写sql语句
    sqlstr := "insert into users(username,password,email) values(?,?,?)"
    //2.预编译
    instmt, err := utils.db.prepare(sqlstr)
    if err != nil {
        fmt.println("预编译出现异常:", err)
        return err
    }
    //3.执行
    _, err2 := instmt.exec("admin", "123456", "admin@atguigu.com")
    if err2 != nil {
        fmt.println("执行出现异常:", err2)
        return err
    }
    return nil
}

//adduser2 添加user的方法二
func (user *user) adduser2() error {
    //1.写sql语句
    sqlstr := "insert into users(username,password,email) values(?,?,?)"
    //2.执行
    _, err := utils.db.exec(sqlstr, "admin2", "666666", "admin2@sina.com")
    if err != nil {
        fmt.println("执行出现异常:", err)
        return err
    }
    return nil
}

单元测试

简介

顾名思义,单元测试( unit test),就是一种为验证单元的正确性而设置的自动化测
试,一个单元就是程序中的一个模块化部分。一般来说,一个单元通常会与程序中的一
个函数或者一个方法相对应,但这并不是必须的。go 的单元测试需要用到 testing 包
以及 go test 命令,而且对测试文件也有以下要求
1) 被测试的源文件和测试文件必须位于同一个包下
2) 测试文件必须要以_test.go 结尾

  • 虽然 go 对测试文件_test.go 的前缀没有强制要求,不过一般我们都设置
    为被测试的文件的文件名,如:要对 user.go 进行测试,那么测试文件的
    名字我们通常设置为 user_test.go
    3) 测试文件中的测试函数为 testxxx(t *testing.t)
  • 其中 xxx 的首字母必须是大写的英文字母
  • 函数参数必须是 test.t 的指针类型(如果是 benchmark 测试则参数是
    testing.b 的指针类型)

测试代码:

package model

import (
    "fmt"
    "testing"
)

//testmain函数可以在测试函数执行之前做一些其他操作
func testmain(m *testing.m) {
    fmt.println("测试开始:")
    //通过m.run()来执行测试函数
    m.run()
}

func testuser(t *testing.t) {
    fmt.println("开始测试user中的相关方法")
    //通过t.run()来执行子测试函数
    t.run("测试添加用户:", testadduser)
}

//如果函数名不是以test开头,那么该函数默认不执行,我们可以将它设置成为一个子测试函数
func testadduser(t *testing.t) {
    fmt.println("子测试函数执行:")
    user := &user{}
    //调用添加用户的方法
    user.adduser()
    user.adduser2()
}

testing 包的说明

如果一个测试函数的函数名的不是以 test 开头,那么在使用 go test 命令时默
认不会执行,不过我们可以设置该函数时一个子测试函数,可以在其他测试函

我们还可以通过 testmain(m *testing.m)函数在测试之前和之后做一些其他
的操作

a) 测试文件中有 testmain 函数时,执行 go test 命令将直接运行 testmain
函数,不直接运行测试函数,只有在 testmain 函数中执行 m.run()时才
会执行测试函数

b) 如果想查看测试的详细过程,可以使用 go test -v 命令

获取一条记录

func (user *user) getuserbyid(userid int) (*user, error) {
//写 sql 语句
sqlstr := "select id , username , password , email from users where id = ?"
//执行 sql
row := utils.db.queryrow(sqlstr, userid)
//声明三个变量
var username string
var password string
var email string
//将各个字段中的值读到以上三个变量中
err := row.scan(&userid, &username, &password, &email)
if err != nil {
return nil, err
}
//将三个变量的值赋给 user 结构体
u := &user{
id: userid,
username: username,
password: password,
email: email,
}
return u, nil
}

获取多条记录

func (user *user) getusers() ([]*user, error) {
//写 sql 语句
sqlstr := "select id , username , password , email from users"
//执行 sql
rows, err := utils.db.query(sqlstr)
if err != nil {
return nil, err
}
//定义一个 user 切片
var users []*user
//遍历
for rows.next() {
//声明四个个变量
var userid int
var username string
var password string
var email string
//将各个字段中的值读到以上三个变量中
err := rows.scan(&userid, &username, &password, &email)
if err != nil {
return nil, err
}
//将三个变量的值赋给 user 结构体
u := &user{
id: userid,
username: username,
password: password,
email: email,
}
//将 u 添加到 users 切片中
users = append(users, u)
}
return users, nil
}