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 }