database/sql
原生支持连接池,是并发安全的。
下载驱动
go get -u github.com/go-sql-driver/mysql
连接
dsn := "root:[email protected](127.0.0.1:3306)/go_test"
db, err = sql.Open("mysql", dsn)
if err != nil {
return err
}
err = db.Ping()
if err != nil {
return err
}
// 配置
// 最大连接数
db.SetMaxOpenConns(100)
// 最大闲置连接数
db.SetMaxIdleConns(10)
查询
- 单条查询
func sel() {
var u1 user
sqlStr := `select i_d,user_name,password from s_user where i_d=1;`
rowObj := db.QueryRow(sqlStr)
fmt.Println(rowObj)
rowObj.Scan(&u1.id, &u1.userName, &u1.password)
fmt.Println(u1)
}
- 多条查询
func selall() {
sqlStr := `select i_d,user_name,password from s_user;`
rows, err := db.Query(sqlStr)
if err != nil {
fmt.Println("error", err)
return
}
defer rows.Close()
for rows.Next() {
u1 := user{}
err := rows.Scan(&u1.id, &u1.userName, &u1.password)
if err != nil {
fmt.Println("scan error")
return
}
fmt.Printf("%#v\n", u1)
}
}
插入
func insert() {
sqlStr := `insert into s_user (user_name,password) values("哈喽",20)`
ret, err := db.Exec(sqlStr)
if err != nil {
fmt.Println("exec error:", err)
return
}
id, err := ret.LastInsertId()
if err != nil {
fmt.Println("get last id error:", err)
return
}
fmt.Println("id:", id)
}
更新
func update(password string, id int) {
sqlStr := `update s_user set password=? where i_d=?`
ret, err := db.Exec(sqlStr, password, id)
if err != nil {
fmt.Println("update error:", err)
return
}
n, err := ret.RowsAffected()
if err != nil {
fmt.Println("update error:", err)
return
}
fmt.Printf("更新了%d行数据\n", n)
}
删除
func deleteRow(id int) {
sqlStr := `delete from s_user where i_d=?`
ret, err := db.Exec(sqlStr, id)
if err != nil {
fmt.Println("delete error:", err)
return
}
n, err := ret.RowsAffected()
if err != nil {
fmt.Println("update error:", err)
return
}
fmt.Printf("删除了%d行数据!", n)
}
MySQL预处理
- 优化MySQL服务器重复执行SQL语句,可以提升服务器性能,节省编译成本
- 避免SQL注入问题
func preInsert() {
sqlStr := `insert into s_user (user_name,password) values(?,?)`
stmt, err := db.Prepare(sqlStr)
if err != nil {
fmt.Println("prepare error:", err)
return
}
defer stmt.Close()
// 通过stmt进行操作
m := map[string]string{
"test1": "console.log(321)",
"test2": "console.log(654)",
"test3": "wangxiangji",
"test4": "tianyue",
}
for k, v := range m {
ret, err := stmt.Exec(k, v)
if err != nil {
fmt.Println("insert error:", err)
continue
}
_, err = ret.RowsAffected()
if err != nil {
fmt.Println("insert error:", err)
continue
}
fmt.Printf("%sinsert success\n", k)
}
}
MySQL事务处理
事务:一个最小的不可再分的工作单元。通常一个事务对应一个完整的业务,同时这个完整的业务需要执行多次的DML(insert、update、delete)语句共同联合完成。Innndb引擎数据库才支持事务。
相关方法
tx.Begin()
tx.Rollback()
tx.Commit()
func transactionDemo() {
tx, err := db.Begin()
if err != nil {
fmt.Println("begin error:", err)
return
}
sqlStr1 := `update s_user set password="18" where i_d=8`
sqlStr2 := `update s_user set password="22" where i_d=9`
_, err = tx.Exec(sqlStr1)
if err != nil {
// 错误回滚
tx.Rollback()
fmt.Println("sql1 running error:", err)
return
}
_, err = tx.Exec(sqlStr2)
if err != nil {
tx.Rollback()
fmt.Println("sql2 running error:", err)
return
}
err = tx.Commit()
if err != nil {
tx.Rollback()
fmt.Println("commit running error:", err)
return
}
fmt.Println("事务执行成功")
}