實現
增刪改查
package main
import (
"database/sql/driver"
"errors"
"fmt"
_ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
)
var db *sqlx.DB
var dsn = "root:Monica216@@@tcp(localhost:3306)/myblog?charset=utf8"
func initDB() (err error) {
// 數據庫信息
// 用戶名:密碼@tcp(ip:端口)/數據庫的名字
//dsn := "test:sdafdsf22@tcp(1.1.1.1:3306)/myblog?charset=utf8"
// 連接數據庫
db, err = sqlx.Connect("mysql", dsn)
if err != nil {
return
}
db.SetMaxOpenConns(10) // 設置數據庫連接池的最大連接數
db.SetMaxIdleConns(5) // 設置最大空閒連接數
return
}
type User struct {
ID int `db:"id"`
Name string `db:"name"`
Age int `db:"age"`
Status int `db:"status"`
}
func (u User) Value() (driver.Value, error) {
return []interface{}{u.Name, u.Age}, nil
}
func main() {
err := initDB()
if err != nil {
fmt.Printf("init DB failed, err:%v\n", err)
return
}
// 查詢單行數據
sqlStr1 := `select id, name, age from User where id=?`
var u User
db.Get(&u, sqlStr1, 1)
fmt.Printf("u:%#v\n", u)
var userList []User
sqlStr2 := `select id,name, age from User`
err = db.Select(&userList, sqlStr2)
if err != nil {
fmt.Printf("select failed, err:%v\n", err)
return
}
fmt.Printf("userList:%#v\n", userList)
queryMultiRowDemo()
//insertRowDemo()
//updateRowDemo()
deleteRowDemo()
//insertUserDemo()
//namedQuery()
//transactionDemo1()
//BatchInsertUsers()
}
func queryMultiRowDemo() {
sqlStr := "select id, name, age from User where id > ?"
var users []User
err := db.Select(&users, sqlStr, 1)
if err != nil {
fmt.Printf("query failed, err:%v\n", err)
return
}
fmt.Printf("users:%#v\n", users)
}
// 插入數據
func insertRowDemo() {
sqlStr := "insert into User(name, age) values (?,?)"
ret, err := db.Exec(sqlStr, "常見", 19)
if err != nil {
fmt.Printf("insert failed, err:%v\n", err)
return
}
theID, err := ret.LastInsertId() // 新插入數據的id
if err != nil {
fmt.Printf("get lastinsert ID failed, err:%v\n", err)
return
}
fmt.Printf("insert success, the id is %d.\n", theID)
}
func updateRowDemo() {
sqlStr := "update User set age=? where id = ?"
ret, err := db.Exec(sqlStr, 88, 4)
if err != nil {
fmt.Printf("update failed, err:%v\n", err)
return
}
n, err := ret.RowsAffected() // 操作影響的行數
if err != nil {
fmt.Printf("get RowsAffected failed, err:%v\n", err)
return
}
fmt.Printf("update success, affected rows:%d\n", n)
}
// 刪除數據
func deleteRowDemo() {
sqlStr := "delete from User where id > ?"
ret, err := db.Exec(sqlStr, 9)
if err != nil {
fmt.Printf("delete failed, err:%v\n", err)
return
}
n, err := ret.RowsAffected() // 操作影響的行數
if err != nil {
fmt.Printf("get RowsAffected failed, err:%v\n", err)
return
}
fmt.Printf("delete success, affected rows:%d\n", n)
}
// 插入數據
func insertUserDemo() (err error) {
sqlStr := "insert into User(name,age) values (:name,:age)"
_, err = db.NamedExec(sqlStr,
map[string]interface{}{
"name": "奮鬥",
"age": 24,
})
return
}
func namedQuery() {
sqlStr := "select * from User where name=:name"
// 使用map做命名查詢
rows, err := db.NamedQuery(sqlStr, map[string]interface{}{"name": "wunai"})
if err != nil {
fmt.Printf("db.NamedQuery failed, err:%v\n", err)
return
}
defer rows.Close()
for rows.Next() {
var u User
err := rows.StructScan(&u)
if err != nil {
fmt.Printf("scan failed,err:%v\n", err)
continue
}
fmt.Printf("namedQuery User:%#v\n", u)
}
u := User{
Name: "奮鬥",
}
// 使用結構體命名查詢, 根據結構體字段的db tag進行映射
rows, err = db.NamedQuery(sqlStr, u)
if err != nil {
fmt.Printf("db.NamedQuery failed,err:%v\n", err)
return
}
defer rows.Close()
for rows.Next() {
var u User
err := rows.StructScan(&u)
if err != nil {
fmt.Printf("scan failed, err:%v\n", err)
continue
}
fmt.Printf("namedQuery User:%#v\n", u)
}
}
// 事務操作
func transactionDemo1() (err error) {
tx, err := db.Beginx()
if err != nil {
fmt.Printf("begin trans failed, err:%v\n", err)
return err
}
defer func() {
if p := recover(); p != nil {
tx.Rollback()
panic(p)
} else if err != nil {
fmt.Printf("rollback, err = %#v", err)
tx.Rollback()
} else {
err = tx.Commit()
fmt.Println("commit")
}
}()
sqlStr1 := "update User set age = 30 where id = ?"
rs, err := tx.Exec(sqlStr1, 1)
if err != nil {
return err
}
n, err := rs.RowsAffected()
if err != nil {
return err
}
if n != 1 {
return errors.New("exec sqlStr1 failed")
}
sqlStr2 := "Update User set age=50 where i=?"
rs, err = tx.Exec(sqlStr2, 5)
if err != nil {
return err
}
n, err = rs.RowsAffected()
if err != nil {
return err
}
if n != 1 {
return errors.New("exec sqlStr1 failed")
}
return err
}
批量操作
package main
import (
"fmt"
_ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
"strings"
)
// BatchInsertUsers 自行構造批量插入的語句
func BatchInsertUsers(users []*User) error {
// 存放 (?, ?) 的slice
valueStrings := make([]string, 0, len(users))
// 存放values的slice
valueArgs := make([]interface{}, 0, len(users)*2)
// 遍歷users準備相關數據
for _, u := range users {
// 此處佔位符要與插入值的個數對應
valueStrings = append(valueStrings, "(?, ?)")
valueArgs = append(valueArgs, u.Name)
valueArgs = append(valueArgs, u.Age)
}
// 自行拼接要執行的具體語句
stmt := fmt.Sprintf("INSERT INTO user (name, age) VALUES %s",
strings.Join(valueStrings, ","))
_, err := db.Exec(stmt, valueArgs...)
return err
}
// BatchInsertUsers2 使用sqlx.In幫我們拼接語句和參數, 注意傳入的參數是[]interface{}
func BatchInsertUsers2(users []interface{}) error {
query, args, _ := sqlx.In(
"INSERT INTO user (name, age) VALUES (?), (?), (?)",
users..., // 如果arg實現了 driver.Valuer, sqlx.In 會通過調用 Value()來展開它
)
fmt.Println(query) // 查看生成的querystring
fmt.Println(args) // 查看生成的args
_, err := db.Exec(query, args...)
return err
}
// BatchInsertUsers3 使用NamedExec實現批量插入
func BatchInsertUsers3(users []*User) error {
_, err := db.NamedExec("INSERT INTO user (name, age) VALUES (:name, :age)", users)
return err
}
func main() {
err := initDB()
if err != nil {
panic(err)
}
defer db.Close()
u1 := User{Name: "七米", Age: 18}
u2 := User{Name: "q1mi", Age: 28}
u3 := User{Name: "小王子", Age: 38}
// 方法1
users := []*User{&u1, &u2, &u3}
err = BatchInsertUsers(users)
if err != nil {
fmt.Printf("BatchInsertUsers failed, err:%v\n", err)
}
// 方法2
users2 := []interface{}{u1, u2, u3}
err = BatchInsertUsers2(users2)
if err != nil {
fmt.Printf("BatchInsertUsers2 failed, err:%v\n", err)
}
// 方法3
users3 := []*User{&u1, &u2, &u3}
err = BatchInsertUsers3(users3)
if err != nil {
fmt.Printf("BatchInsertUsers3 failed, err:%v\n", err)
}
//users4 := make([]interface{}, 3)
//uu1 := User{Name: "hello1", Age: 11}
//uu2 := User{Name: "hello2", Age: 11}
//uu3 := User{Name: "hello3", Age: 11}
//users4[0] = uu1
//users4[1] = uu2
//users4[2] = uu3
//fmt.Printf("users4 = %#v", users4)
//BatchInsertUsers2(users4)
}