Go 语言中的 database/sql 包定义了对数据库的一系列操作。database/sql/driver包定义了应被数据库驱动实现的接口,这些接口会被 sql 包使用。但是 Go 语言没有提供任何官方的数据库驱动,所以我们需要导入第三方的数据库驱动。不过我们连接数据库之后对数据库操作的大部分代码都使用 sql 包。
import (
"database/sql"
_ "github.com/go-sql-driver/mysql")
var (
Db *sql.DB
err error
)
func init() {
Db,
err = sql.Open("mysql", "root:root@tcp(localhost:3306)/test")
if err != nil {
panic(err.Error())
}
}
CREATE TABLE users(
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(100) UNIQUE NOT NULL,
PASSWORD VARCHAR(100) NOT NULL,
email VARCHAR(100)
)
package model
import (
"fmt"
"webproject/utils"
)
type User struct {
ID int
Username string
Password string
Email string
}
func(user * User) AddUser() error {
// 写 sql 语句
sqlStr: = "insert into users(username , password , email) values(?,?,?)" //预编译
stmt,
err: = utils.Db.Prepare(sqlStr)
if err != nil {
fmt.Println("预编译出现异常:", err)
return err
}
//执行
_,
erro: = stmt.Exec(user.Username, user.Password, user.Email)
if erro != nil {
fmt.Println("执行出现异常:", erro)
return erro
}
return nil
}
func(user * User) AddUser() error {
// 写 sql 语句
sqlStr: = "insert into users(username , password , email)
values( ? , ? , ? )
"//执行
_,
erro: = utils.Db.Exec(sqlStr, user.Username, user.Password,
user.Email)
if erro != nil {
fmt.Println("执行出现异常:", erro)
return erro
}
return nil
}
顾名思义,单元测试( unit test),就是一种为验证单元的正确性而设置的自动化测试,一个单元就是程序中的一个模块化部分。一般来说,一个单元通常会与程序中的一个函数或者一个方法相对应,但这并不是必须的。Go 的单元测试需要用到 testing 包 以及 go test 命令,而且对测试文件也有以下要求
func TestAddUser(t * testing.T) {
fmt.Println("测试添加用户:")
user: = & User {
Username: "admin3",
Password: "123456",
Email: "admin3@atguigu.com",
}
//将 user 添加到数据库中
user.AddUser()
}
func TestUser(t * testing.T) {
t.Run("正在测试添加用户:", testAddUser)
t.Run("正在测试获取一个用户:", testGetUserById)
} //子测试函数
func testAddUser(t * testing.T) {
fmt.Println("测试添加用户:")
user: = & User {
Username: "admin5",
Password: "123456",
Email: "admin5@atguigu.com",
}
//将 user 添加到数据库中
user.AddUser()
} //子测试函数
func testGetUserByID(t * testing.T) {
u: = & User {}
user,
_: = u.GetUserByID(1)
fmt.Println("用户的信息是:", * user)
}
func TestMain(m * testing.M) {
fmt.Println("开始测试") m.Run()
}
func TestUser(t * testing.T) {
t.Run("正在测试添加用户:", testAddUser)
}
func testAddUser(t * testing.T) {
fmt.Println("测试添加用户:")
user: = & User {
Username: "admin5",
Password: "123456",
Email: "admin5@atguigu.com",
}
//将 user 添加到数据库中
user.AddUser()
}
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
}