go操作MySQL
目录
- go操作MySQL
- 依赖
- 实例
go操作MySQL
依赖
go get github.com/go-sql-driver/mysql
实例
CREATE DATABASE IF NOT EXISTS `go_db` charset=utf8mb4;
package daily
import (
"context"
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql" // 数据库驱动
)
var (
DB *sql.DB
)
func InitMysqlDB() error {
var err error
dsn := "root:python@tcp(127.0.0.1:3306)/go_db?charset=utf8mb4&parseTime=True&loc=Local"
db, err := sql.Open("mysql", dsn)
//defer db.Close()
if err != nil {
//panic(errors.New(
// "initError:" + err.Error()))
return err
}
if err = db.Ping(); err != nil {
//panic(errors.New(
// "pingError:" + err.Error()))
return err
} // 校验数据库连接可用性
/**
SetConnMaxLifetime: 设置一个连接的最长生命周期,因为数据库本身对连接有一个超时时间的设置,如果超时时间到了数据库会单方面断掉连接,此时再用连接池内的连接进行访问就会出错, 因此这个值往往要小于数据库本身的连接超时时间
SetMaxIdleConns: 连接池里面允许Idel的最大连接数, 这些Idel的连接 就是并发时可以同时获取的连接,也是用完后放回池里面的互用的连接, 从而提升性能。
SetMaxOpenConns: 设置最大打开的连接数,默认值为0表示不限制。控制应用于数据库建立连接的数量,避免过多连接压垮数据库。
*/
db.SetConnMaxLifetime(time.Minute) // 最大连接时间
db.SetMaxOpenConns(10) // 最大连接数
db.SetMaxIdleConns(10) // 最大空闲连接数
DB = db
return err
}
func MysqlOp() {
/**
mysql操作
go-sql 默认使用原生sql操作
1. 下载依赖:go get github.com/go-sql-driver/mysql
2. open函数验证其参数是否正确 需要通过ping校验通过连接是否正确 且建议只调用一次open 多个goroutine并发使用db
3. db连接
db.Ping() 调用完毕后会马上把连接返回给连接池
db.Exec() 调用完毕后会马上把连接返回给连接池 但是它返回的Result对象还保留这连接的引用 当后面的代码需要处理结果集的时候连接将会被重用
db.Query() 调用完毕后会将连接传递给sql.Rows类型 当然后者迭代完毕或者显示的调用.Close()方法后 连接将会被释放回到连接池
db.QueryRow()调用完毕后会将连接传递给sql.Row类型 当.Scan()方法调用之后把连接释放回到连接池
db.Begin() 调用完毕后将连接传递给sql.Tx类型对象 当.Commit()或.Rollback()方法调用后释放连接
*/
err := InitMysqlDB()
if err != nil || DB == nil {
fmt.Println("数据库初始化失败=" + err.Error())
return
} else {
fmt.Println("数据库初始化成功")
}
// 1. 新建数据表
table_delete := `DROP TABLE IF EXISTS user`
if _, err := DB.Exec(table_delete); err != nil {
fmt.Println("删除表失败="+ err.Error())
return
} else {
fmt.Println("删除表成功")
}
table_create := `CREATE TABLE IF NOT EXISTS user (
id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '用户编号',
name VARCHAR(8) NOT NULL COMMENT '用户名称',
age TINYINT(3) UNSIGNED NOT NULL DEFAULT 0 COMMENT '用户年龄',
PRIMARY KEY (id))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_general_ci
COMMENT = '用户表'`
if _, err := DB.Exec(table_create); err != nil {
fmt.Println("创建表失败=", err.Error())
return
} else {
fmt.Println("创建表成功")
}
// 2.1 新增
stmt, err := DB.Prepare(`insert into user(name, age)values(?,?)`)
defer stmt.Close()
if err != nil {
fmt.Println("新增Pre失败=", err.Error())
return
} else {
if r, err := stmt.Exec("陈一", 10); err != nil {
fmt.Println("1-新增Exc失败=", err.Error())
} else {
if id, err := r.LastInsertId(); err != nil {
fmt.Println("1-新增失败LastInsertId1=", err.Error())
} else {
fmt.Println("1-新增成功id=", id)
}
}
}
// 2.2 新增
r, err := DB.Exec(`insert into user(name, age)values(?,?)`, "王二", 12)
if err != nil {
fmt.Println("2-新增失败Exec=" + err.Error())
return
}
if id, err := r.LastInsertId(); err != nil {
fmt.Println("2-新增失败LastInsertId=", err.Error())
} else {
fmt.Println("2-新增成功id=", id)
}
type myUser struct {
id uint
name string
age uint8
}
// 3.1 单行查询
var u myUser
if err = DB.QueryRow(`select * from user where id=?`, 1).Scan(&u.id, &u.name, &u.age); err != nil {
fmt.Println("单行查询错误=" + err.Error())
return
}
fmt.Println("单行查询成功=", u)
// 3.2 多行查询
rows, err := DB.Query(`SELECT * FROM user`)
if err != nil {
fmt.Println("多行查询错误=" + err.Error())
return
}
defer rows.Close()
for rows.Next() {
err := rows.Scan(&u.id, &u.name, &u.age)
if err != nil {
fmt.Println("多行查询scan错误=" + err.Error())
return
}
fmt.Printf("多行查询(%T)=%v\n", u, u)
}
// 4. 更新
if res, err := DB.Exec(`update user set age=? where id=?`, 22, 2); err != nil {
fmt.Println("更新失败=", err.Error())
return
} else {
affected, _ := res.RowsAffected()
fmt.Println("更新成功行数=", affected)
}
// 5. 删除
if res, err := DB.Exec(`delete from user where id=?`, 1); err != nil {
fmt.Println("删除失败=", err.Error())
return
} else {
affected, _ := res.RowsAffected()
fmt.Println("删除成功行数=", affected)
}
// 6. 事务
tx := sql.TxOptions{sql.LevelRepeatableRead, false}
mTx, err := DB.BeginTx(context.Background(), &tx)
if err != nil {
fmt.Println("事务开始失败=", err.Error())
return
}
res, err := mTx.Exec(`delete from user`)
if err != nil {
fmt.Println("事务执行失败=", err.Error())
}
affected, _ := res.RowsAffected()
fmt.Println("影响行数=", affected)
if err := mTx.Rollback(); err != nil {
fmt.Println("事务回滚失败=", err.Error())
return
} else {
fmt.Println("事务回滚成功")
} // 回滚
if err := mTx.Commit(); err != nil {
fmt.Println("事务提交失败=", err.Error())
} else {
fmt.Println("事务提交失成功")
} // 提交(提交和回滚只能存在一个)
}