package main
import (
"database/sql/driver"
"fmt"
"strings"
"time"
_ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
)
type user struct {
Id int
Name string // 首字母大写,不然后面的Get拿不到值会报错,这个字段需要跟数据库字段对应
Age int
Gender []uint8 // go语言目前没有跟bit类型对应的数据类型
Birthday time.Time
Salary float32
Department string
}
type student struct {
Name string
Age int
}
func (u student) Value() (driver.Value, error) {
return []interface{}{u.Name, u.Age}, nil
}
func main() {
// 连接数据库
var db *sqlx.DB
dsn := "root:123456@(127.0.0.1:3306)/golang?charset=utf8mb4&parseTime=true"
db, err := sqlx.Connect("mysql", dsn)
if err != nil {
fmt.Printf("connect DB failed, err:%v
", err)
return
}
db.SetMaxOpenConns(20)
db.SetMaxIdleConns(10)
// 批量插入
// 方式一:手动拼接
users := make([]student, 2)
users = []student{
{"zhangsan2", 26},
{"lisi1", 20},
}
// 存放 (?, ?) 的slice
valueStrings := make([]string, 0, len(users))
// 存放values的slice
valueArgs := make([]interface{}, 0, len(users)*2)
// 遍历users准备相关数据
for _, u := range users {
// 此处占位符要与插入值的个数对应
fmt.Println(u)
valueStrings = append(valueStrings, "(?, ?)") // 有多少个需要插入的用户就有多少个(?, ?)
valueArgs = append(valueArgs, u.Name) // 将用户名和年龄依次插入到切片
valueArgs = append(valueArgs, u.Age)
}
// 最终得到:valueStrings=[(?, ?) (?, ?)] valueArgs=[zhangsan1 26 lisi 20]
//自行拼接要执行的具体语句
stmt := fmt.Sprintf("INSERT INTO stu (name, age) VALUES %s", strings.Join(valueStrings, ",")) //INSERT INTO stu (name, age) VALUES (?, ?),(?, ?)
fmt.Println(stmt)
_, err1 := db.Exec(stmt, valueArgs...) // 用valueArgs里的值去填充stmt里面的问号
fmt.Println(err1)
// 方式二 sqlx.In(尚未实现,待研究)
// 方式三 NamedExec实现批量插入
_, err1 := db.NamedExec("INSERT INTO stu (name, age) VALUES (:name, :age)", users)
fmt.Println(err1)
}
老师博客地址:www.liwenzhou.com