前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >GO-操作数据库

GO-操作数据库

作者头像
cwl_java
发布2020-04-08 15:21:58
1.5K0
发布2020-04-08 15:21:58
举报
文章被收录于专栏:cwl_Javacwl_Java

第 4 章:操作数据库

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

4.1 获取数据库连接

  1. 创建一个 db.go 文件,导入 database/sql 包以及第三方驱动包
代码语言:javascript
复制
import (
	"database/sql"
	_ "github.com/go-sql-driver/mysql")
  1. 定义两个全局变量
代码语言:javascript
复制
var (
Db *sql.DB
err error
)
  • DB 结构体的说明
在这里插入图片描述
在这里插入图片描述
  1. 创建 init 函数,在函数体中调用 sql 包的 Open 函数获取连接
代码语言:javascript
复制
func init() {
	Db,
	err = sql.Open("mysql", "root:root@tcp(localhost:3306)/test")
	if err != nil {
		panic(err.Error())
	}
}
  • Open 函数的说明
在这里插入图片描述
在这里插入图片描述
  • 参数 dataSourceName 的格式: 数据库用户名:数据库密码@[tcp(localhost:3306)]/数据库名
  • Open 函数可能只是验证其参数,而不创建与数据库的连接。如果要检查数据源的名称是否合法,应调用返回值的 Ping 方法。
在这里插入图片描述
在这里插入图片描述
  • 返回的 DB 可以安全的被多个 go 程同时使用,并会维护自身的闲置连接池。这样一来,Open 函数只需调用一次。很少需要关闭 DB

4.2 增删改操作

  1. 在连接的 test 数据库中创建一个 users 表
代码语言:javascript
复制
CREATE TABLE users(
	id INT PRIMARY KEY AUTO_INCREMENT,
	username VARCHAR(100) UNIQUE NOT NULL,
	PASSWORD VARCHAR(100) NOT NULL,
	email VARCHAR(100)
)
  1. 向 users 表中插入一条记录
  • 创建 user.go 文件,文件中编写一下代码
代码语言:javascript
复制
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
}
  • Prepare 方法的说明
在这里插入图片描述
在这里插入图片描述
  • Stmt 结构体及它的方法的说明
在这里插入图片描述
在这里插入图片描述
  • DB 结构体中也有 Exec、Query 和 QueryRow 方法
在这里插入图片描述
在这里插入图片描述
  • 所以还可以通过调用 DB 的 Exec 方法添加用户(以下只展示了 user.go 文件修改之后的 AddUser 方法)
代码语言:javascript
复制
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
}
  • 请同学们仿照着添加操作将删除和更新完成

4.3 单元测试

4.3.1 简介

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

  1. 被测试的源文件和测试文件必须位于同一个包下
  2. 测试文件必须要以_test.go 结尾
  • 虽然 Go 对测试文件_test.go 的前缀没有强制要求,不过一般我们都设置为被测试的文件的文件名,如:要对 user.go 进行测试,那么测试文件的名字我们通常设置为 user_test.go
  1. 测试文件中的测试函数为 TestXxx(t *testing.T)
  • 其中 Xxx 的首字母必须是大写的英文字母
  • 函数参数必须是 test.T 的指针类型(如果是 Benchmark 测试则参数是testing.B 的指针类型)

4.3.2 测试代码:

  1. 在 user_test.go 中测试添加员工的方法
代码语言:javascript
复制
func TestAddUser(t * testing.T) {
	fmt.Println("测试添加用户:")
	user: = & User {
		Username: "admin3",
		Password: "123456",
		Email: "admin3@atguigu.com",
	}
	//将 user 添加到数据库中
	user.AddUser()
}
  • testing 包的说明
在这里插入图片描述
在这里插入图片描述
  1. 如果一个测试函数的函数名的不是以 Test 开头,那么在使用 go test 命令时默认不会执行,不过我们可以设置该函数时一个子测试函数,可以在其他测试函数里通过 t.Run 方法来执行子测试函数,具体代码如下
代码语言:javascript
复制
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)
}
  1. 我们还可以通过 TestMain(m *testing.M)函数在测试之前和之后做一些其他的操作 a) 测试文件中有 TestMain 函数时,执行 go test 命令将直接运行 TestMain函数,不直接运行测试函数,只有在 TestMain 函数中执行 m.Run()时才会执行测试函数 b) 如果想查看测试的详细过程,可以使用 go test -v 命令 c) 具体代码
代码语言:javascript
复制
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()
}
  • Main 的说明
在这里插入图片描述
在这里插入图片描述

4.4 获取一条记录

  • 根据用户的 id 从数据库中获取一条记录
  • 代码实现:
代码语言:javascript
复制
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
}
  • Row 结构体及 San 方法的说明
在这里插入图片描述
在这里插入图片描述

4.5 获取多条记录

  • 从数据库中查询出所有的记录
  • 代码实现:
代码语言:javascript
复制
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
}
  • Rows 结构体说明
在这里插入图片描述
在这里插入图片描述
  • Next 方法和 Scan 方法说明
在这里插入图片描述
在这里插入图片描述
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-04-06 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 第 4 章:操作数据库
    • 4.1 获取数据库连接
      • 4.2 增删改操作
        • 4.3 单元测试
          • 4.3.1 简介
          • 4.3.2 测试代码:
        • 4.4 获取一条记录
          • 4.5 获取多条记录
          相关产品与服务
          数据库
          云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档