var db *sqlx.DB funcinitDB() (err error){ dsn := "user:password@tcp(xxx.aws.us-west-1.rds.amazonaws.com:3306)/mt_subtitle_table?charset=utf8mb4&parseTime=True" //也可以使用MustConnect,连接不成功就panic db, err = sqlx.Connect("mysql", dsn) if err != nil { fmt.Printf("connect DB failed, err:%v", err) return } db.SetMaxOpenConns(20) // 设置最大连接数 db.SetMaxIdleConns(10) // 设置最大闲置连接数 }
查询
查询单行数据
1 2 3 4 5 6 7 8 9 10 11
// 查询单条数据 funcqueryRowDemo() { sqlStr := "select id, actress, title from mt_subtitle_table where id = ?" var m Moive err := db.Get(&m, sqlStr, "AAA-001") if err != nil { fmt.Printf("get failed, err :%v", err) return } fmt.Printf("m: %v", m) }
查询多行数据
1 2 3 4 5 6 7 8 9 10
funcqueryMultRowDemo() { sqlStr := "select id, actress, title from mt_subtitle_table where actress= ?" var movies []Movie err := db.Select(&moives, sqlStr, "川岛芳子") if err != nil { fmt.Printf("query failed, err :%v", err) return } fmt.Printf("movies: %#v", movies) }
functransationDemo() (err error) { tx. err := db.Begin() // 开启事务 if err != nil { fmt.Prinf("事务开始失败,错误:%v", err) return err } // return之前执行 deferfunc() { if p := recover(); p != nil { tx.Rollback() panic(p) // 回滚之后重新panic }elseif err != nil { fmt.Println("rollback") tx.Rollback() // 有错误,因此需要回滚 }else { err = tx.Commit() // 没有错误,提交事务 fmt.Println("commit") } }() sqlStr1 := "UPDATE mt_subtitle_table SET title='艺妓回忆录' where id = ?" rs, err := tx.Exec(sqlStr1, "ABC-001") if err != nil { return err } if n != 1 { return errors.New("sqlStr1执行失败") } sqlStr2 := "UPDATE mt_subtitle_table SET title='上海回忆录' where id = ?" rs, err := tx.Exec(sqlStr2, "AAA-001") if err != nil { return err } n, err = rs.RowsAffected() if err != nil { return err } if n != 1 { return errors.New("sqlStr2执行失败") } }
sqlx.In
sqlx.In
是sqlx提供的一个非常方便的函数。
批量插入
这里创建一个表,表结构如下:
1 2 3 4 5 6
CREATE TABLE `mt_subtitle_table` ( `id` text NOT NULL, `actress` text NOT NULL, `title` text NOT NULL, PRIMARY KEY (`id`) )ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
定义一个结构体,字段通过tag和上述表中的字段一致。
1 2 3 4 5
type Moive struct{ ID string`db:"id"` Actress string`db:"actress"` Title string`db:"title"` }
关于sqlx.In这里在补充一个用法,在sqlx查询语句中实现了In查询和FIND_IN_SET函数。即实现SELECT * FROM mt_subtitle_table WHERE actress in ("川岛芳子","广田雅美")和SELECT * FROM mt_subtitle_table in (3, 2, 1) ORDER BY FIND_IN_SET(id, "川岛芳子","广田雅美").
in查询
1 2 3 4 5 6 7 8 9 10 11 12
// QueryByIDs 根据指定ID查询 funcQueryByIDs(ids []string) (movies []Movie, err error) { // 动态填充id query, args, err := sqlx.In("SELECT id, actress, title FROM mt_subtitle_table WHERE actress IN (?)", ids) if err != nil { return } // sqlx.In返回带`?`bindvar`的查询语句,我们使用Rebind()重新绑定他 query = db.Rebind(query) err = db.Select(&movies, query, args...) return }
in查询和FIND_IN_SET函数
查询id在给定id集合的数据并维持给定id集合的顺序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// QuertAndOrderByIDs 按照指定id查询并维护顺序 funcQuertAndOrderByIDs(ids []string)(moives []Movie, err error) { // 动态填充id strIDs := make([]string, 0, len(ids)) for _, id := range ids { strIDs = append(strIDs, fmt.Sprintf("%d", id)) } query, args, err := sqlx.In("SELECT id, actress FROM user WHERE id IN (?) ORDER BY FIND_IN_SET(id, ?) ORDER BY FIND_IN_SET(id, ?)", ids, strings.Join(strIDs, ",")) if err != nil { return } // sqlx.In 返回带 `?` bindvar的查询语句,我们使用Rebind()重新绑定它 query = db.Rebind(query) err = db.Select(&movie, query, args...) return }