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
)
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打开一个dirverName指定的数据库,dataSourceName的数据源
注1:Open函数可能只能验证其参数,而不创建与数据库的连接。如果需要检查数据源的名称是否合法,应调用返回值的Ping方法。
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
}