GO操作Mysql数据库

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

引入包:

import (
    "database/sql"
    "github.com/go-sql-driver/mysql"
)

定义两个全局变量(我们需要在多个文件中使用到)

var (

    Db      *sql.Db
    Err      errror
)

type DB说明

DB是一个数据库操作的句柄(或者说指针),指向了一个具有0个或者多个连接的连接池。它可以安全的被多个go协程同时使用(猜测底层通过管道)。

        sql包会自动地创建和释放连接,维护一个闲置连接的连接池。如果一个数据库具有单链接状态的概念,该状态只有在事务中被观察时才可信。一旦调用DB.Begin,返回的Tx会绑定到单个连接。连接池的大小可以用SetMaxdleConns方法控制 

func init(){//init函数一般用于初始化工作,作用于main函数之前
    
    Db,err := sql.OPen("maysql","root:密码@tcp(IP:端口)/数据库名")
    if err != nil{
        panic(err.Error())        //抛出异常,常使用defer+recover捕捉
    }    

}

Open函数说明

        func Open(driverName,dataSourceName string)(*DB,error)

        Open打开一个dirverName指定的数据库,dataSourceName的数据源

        注1:Open函数可能只能验证其参数,而不创建与数据库的连接。如果需要检查数据源的名称是否合法,应调用返回值的Ping方法。

        func (*DB)Ping() error

         Ping检查与数据库的连接是否仍然有效,如果需要会创建连接

创建一个数据表       

CREATE TABLE users(
    
    id         INT PRIMARY  KEY  AUTO_INCREMENT,
    username   VARCHAR(100) NOT NULL UNIQUE,
    password   VARCHAR(100) NOT  NULL,
    email      VARCHAR(100)  
 
)

文件分布

        DB_mysql/model/user.go

        DB_mysql/model/user_test.go                 //测试文件

        DB_mysql/db.go

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:123123@tcp(localhost:3306)/mytest")
	if err != nil {
		panic(Err.Error())
	}
}
package model

import "goWorking/DBSql/utils"

//User字段应该与数据库中的users表的字段意义对应
type User struct {
	Id       int
	UserName string
	Password string
	Email    string
}

//给User绑定相应的操作方法

//增加用户
func (this *User) AddUser() error {

	//1.写sql语句
	str := "insert into users(id,username,password,email) values(?,?,?)" //?是占位符
	//2.预编译(建议预编译,防止sql注入)
	strTmt, err := utils.Db.Prepare(str)
	if err != nil {
		return err
	}
	//3.执行
	//Exec执行一次命令(包括查询、删除、更新、插入等),不返回任何执行结果。参数args表示query中的占位参数。
	_, err = strTmt.Exec("admin", "123123", "email") //id自动增长
	if err != nil {
		return err
	}

	return nil
}

//通过ID从数据库获取一条用户信息
func (this *User) GetUserById() (u *User, err error) {

	//1.写sql语句
	str := "select * from users where id = ?"
	//2.预编译
	strTmt, err := utils.Db.Prepare(str)
	//3.执行
	//QueryRow执行一次查询,并期望返回最多一行结果(即Row)。
	//QueryRow总是返回非nil的值,直到返回值的Scan方法被调用时,才会返回被延迟的错误
	row := strTmt.QueryRow(this.Id)
	var id int
	var username string
	var password string
	var email string
	err = row.Scan(&id, &username, &password, &email)
	if err != nil {
		return nil, err
	}

	user := &User{
		Id:       id,
		UserName: username,
		Password: password,
		Email:    email,
	}
	return user, err
}

//获取所有用户信息
func (this *User) GetUsers() (userSlice []*User, err error) {

	//写sql语句
	str := "select * from users"
	//执行
	rows, err := utils.Db.Query(str)

	//获取每一行信息
	var id int
	var username string
	var password string
	var email string
	for rows.Next() {
		err = rows.Scan(&id, &username, &password, &email)
		user := &User{
			Id:       id,
			UserName: username,
			Password: password,
			Email:    email,
		}

		userSlice = append(userSlice, user)
	}

	return
}

更多推荐