目录
一、驱动介绍
二、go-sql-driver/mysql 介绍与应用
2.1 采用理由
2.2 实践与应用
建表语句
增删改查
运行结果
三、补充说明
3.1 sql.Open函数
3.2 db.Prepare()函数
3.3 db.Query()函数
3.4 stmt.Exec()
目前Go语言中支持MySQL的驱动较多,部分是支持database/sql标准,部分是采用自己实现的接口。
常用的驱动有如下几种:
这里采用go_test数据库、user表。
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键自增',
`user_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户名',
`depart_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`create_at` date NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
)
type User struct {
id int64
username string
departName string
createAt string
}
func main() {
db, err := sql.Open("mysql", "root:123456@tcp(192.168.158.328:33066)/go_test?charset=utf8")
checkErr(err)
// 插入数据
userId := insertUserOne(db)
// 查询数据
queryUserOne(db)
// 更改数据
updateUserOne(db, userId)
// 查询数据
queryUserOne(db)
// 删除数据
deleteUserOne(db, userId)
}
// 插入用户数据
func insertUserOne(db *sql.DB) (userId int64) {
stmt, err := db.Prepare("INSERT user set user_name=?,depart_name=?,create_at=?")
checkErr(err)
res, err := stmt.Exec("李四", "运营部", "2000-10-10")
checkErr(err)
// 得到插入后的主键id
id, err := res.LastInsertId()
checkErr(err)
fmt.Println("插入后返回主键id", id)
return id
}
// 更新用户数据
func updateUserOne(db *sql.DB, id int64) {
stmt, err := db.Prepare("update user set user_name= ? where id=?")
checkErr(err)
res, err := stmt.Exec("李四改", id)
checkErr(err)
affected, err := res.RowsAffected()
checkErr(err)
fmt.Println("作用的更新记录数", affected)
}
// 查询用户,暂时就不返回list了
func queryUserOne(db *sql.DB) {
// 这里查询出来的字段顺序需要与结构体字段顺序吧保持一致
rows, err := db.Query("SELECT * FROM user")
checkErr(err)
for rows.Next() {
user := User{}
err := rows.Scan(&user.id, &user.username, &user.departName, &user.createAt)
checkErr(err)
fmt.Println("查询到的用户数据", user.id, user.username, user.departName, user.createAt)
}
}
// 删除用户数据
func deleteUserOne(db *sql.DB, id int64) {
stmt, err := db.Prepare("delete from user where id=?")
checkErr(err)
res, err := stmt.Exec(id)
checkErr(err)
affected, err := res.RowsAffected()
checkErr(err)
fmt.Println("删除作用行数", affected)
db.Close()
}
// 检查错误
func checkErr(err error) {
if err != nil {
panic(err)
}
}
插入后返回主键id 4
查询到的用户数据 4 李四 运营部 2000-10-10
作用的更新记录数 1
查询到的用户数据 4 李四改 运营部 2000-10-10
删除作用行数 1
该函数旨在打开一个注册过的数据库驱动,需要引入 _ "github.com/go-sql-driver/mysql" ,不然程序会报错。
该函数第一个参数是数据库驱动名称,这里是 mysql。
该函数第二个参数是Data Source Name,及链接和配置信息,支持格式如:
源代码如下:
func Open(driverName, dataSourceName string) (*DB, error) {
driversMu.RLock()
driveri, ok := drivers[driverName]
driversMu.RUnlock()
if !ok {
return nil, fmt.Errorf("sql: unknown driver %q (forgotten import?)", driverName)
}
if driverCtx, ok := driveri.(driver.DriverContext); ok {
connector, err := driverCtx.OpenConnector(dataSourceName)
if err != nil {
return nil, err
}
return OpenDB(connector), nil
}
return OpenDB(dsnConnector{dsn: dataSourceName, driver: driveri}), nil
}
用来返回准备要执行的SQL操作,然后返回准备完毕的执行状态。源代码如下:
func (db *DB) Prepare(query string) (*Stmt, error) {
return db.PrepareContext(context.Background(), query)
}
用来直接执行SQL返回Rows结果,源代码如下:
func (db *DB) Query(query string, args ...interface{}) (*Rows, error) {
return db.QueryContext(context.Background(), query, args...)
}
用来执行stmt准备好的语句,源代码如下:
// Exec executes a prepared statement with the given arguments and
// returns a Result summarizing the effect of the statement.
//
// Exec uses context.Background internally; to specify the context, use
// ExecContext.
func (s *Stmt) Exec(args ...interface{}) (Result, error) {
return s.ExecContext(context.Background(), args...)
}
PS:
不用数据库链接后考虑关掉数据库链接。