目前Go语言中支持MySQL的驱动较多,部分是支持database/sql标准,部分是采用自己实现的接口。
常用的驱动有如下几种:
https://github.com/go-sql-driver/mysql支持database/sql,全部采用Go语言编写。
https://github.com/ziutek/mymysql支持database/sql,也支持自定义的接口,全部采用Go语言编写。
https://github.com/Philio/GoMySQL不支持database/sql,自定义接口,全部采用Go语言编写。这里采用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:
不用数据库链接后考虑关掉数据库链接。