zoukankan      html  css  js  c++  java
  • goweb-mysql连接

    操作 数据库

    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
    1. 测试文件中的测试函数为 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
    }
    
    
  • 相关阅读:
    Codeforces 1184C1. Heidi and the Turing Test (Easy)题解
    CodeChef Chef and Digit Jumps 题解
    CodeChef Squirrel and chestnut 题解
    Atcoder Beginner Contest 082 C
    Atcoder Beginner Contest 081 C
    Atcoder Beginner Contest 080 C
    Atcoder Beginner Contest 079 C
    Atcoder Beginner Contest 078 C
    Topcoder 10524(SRM451 Div.1 C) BrickPuzzle题解
    广义表是非线性结构
  • 原文地址:https://www.cnblogs.com/ygjzs/p/12048375.html
Copyright © 2011-2022 走看看