mod文件go.mod
module sqlxdemogo 1.14require ( github.com/go-sql-driver/mysql v1.4.0 github.com/jmoiron/sqlx v1.2.0 google.golang.org/appengine v1.6.7 // indirect)
创建数据表
创建表代码
create table `userinfo` ( `id` int(11) not null auto_increment, `name` varchar(10) default null, `phone` char(11) default null, `address` varchar(64) default null, primary key (`id`)) engine=innodb auto_increment=4 default charset=utf8mb4;
创建结构体
结构体代码
type userinfo struct { id int64 `json:"id"` name string `json:"name"` phone string `json:"phone"` address string `json:"address"`}
连接数据库
代码
import ( "fmt" _ "github.com/go-sql-driver/mysql" "github.com/jmoiron/sqlx")type userinfo struct { id int64 `json:"id"` name string `json:"name"` phone string `json:"phone"` address string `json:"address"`}func main() { dsn := "root:rootroot@tcp(127.0.0.1:3306)/go_mysql_demo?charset=utf8mb4&parsetime=true" // 使用 mustconnect 连接的话,验证失败不成功直接panic //db := sqlx.mustconnect("mysql", dsn) //使用 connect 连接,会验证是否连接成功, db, err := sqlx.connect("mysql", dsn) if err != nil { fmt.printf("connect db failed, err:%v\n", err) return} db.setmaxopenconns(20) db.setmaxidleconns(10)}
查询单条我记得使用原来的方式进行查询并且绑定结构体,是这审的。
//查询单条sqlstr := "select id,`name`,phone,address from userinfo where id = ?;"var user userinfoerr = db.queryrow(sqlstr, 1).scan(&user.id, &user.name, &user.phone, &user.address)if err != nil { fmt.println("查询失败", err) return}
看第4行代码,需要将结构体的字段一个一个点上去。
如果使用sqlx呢?
代码
//查询sqlstr := "select id,`name`,phone,address from userinfo where id = ?;"var user userinfoerr = db.get(&user, sqlstr, 1)if err != nil { fmt.println("查询失败:", err) return}fmt.println("user:",user)
执行结果
还是第4行代码,直接一个结构体扔过去,就绑定成功了。
如果表有很多字段,结构体字段也有很多,这个是很有用的。
查询多条还是惯例,看看原来是怎么查的。
//查询多条sqlstr := "select id,`name`,phone,address from userinfo where id >= ?"//参数同 queryrowrows, err := db.query(sqlstr, 1)//处理err// 此处使用rows释放所有链接defer rows.close()//循环整理所有数据var userlist = make([]userinfo, 0, 10)for rows.next() { var user userinfo err = rows.scan(&user.id, &user.name, &user.phone, &user.address) //处理err userlist = append(userlist, user)}fmt.println(userlist)
为了方便,我去掉了err,使用伪代码处理err代替。
原来的方法,查询出来还得需要一个循环,还需要一个切片,乖乖嘞,打扰了。
来看看sqlx
代码
//查询多条sqlstr := "select id,`name`,phone,address from userinfo where id >= ?"var userlist []userinfoerr = db.select(&userlist, sqlstr, 1)if err != nil { fmt.println("查询失败:", err) return}fmt.println("userlist:",userlist)
执行结果
还是直接扔过去,就绑定完成了,真是美滋滋。
添加额,添加,更新,删除,事物的话,似乎跟原来差不多,直接看代码叭。
代码
//添加sqlstr := "insert into userinfo(name,phone,address) values(?,?,?);"result, err := db.exec(sqlstr, "吴彦祖", 555, "不知道哪的")if err != nil { fmt.println("插入失败", err) return}row_affect, err := result.rowsaffected()if err != nil { fmt.println("受影响行数获取失败:", err) return}fmt.println("受影响的行数:", row_affect)lastid, err := result.lastinsertid()if err != nil { fmt.println("新增行id获取失败:", err) return}fmt.println("新增行id:", lastid)fmt.println("插入成功")
执行结果
mysql
更新
代码
//更新数据sqlstr := `update userinfo set name=? where id=?;`result, err := db.exec(sqlstr, "吴彦祖666", 4)if err != nil { fmt.println("更新失败", err) return}//受影响的行数row_affect, err := result.rowsaffected()if err != nil { fmt.println("受影响行数获取失败:", err) return}fmt.println("受影响的行数:", row_affect)fmt.println("更新成功")
执行结果
mysql
删除
代码
sqlstr := "delete from userinfo where id = ?;"result, err := db.exec(sqlstr, 4)if err != nil { fmt.println("删除失败", err) return}//受影响的行数row_affect, err := result.rowsaffected()if err != nil { fmt.println("受影响行数获取失败:", err) return}fmt.println("受影响的行数:", row_affect)fmt.println("删除成功")
执行结果
mysql
事物
代码
//事物tx, err := db.begin()if err != nil { //释放事物 if tx != nil { tx.rollback()} fmt.println("事物开启失败") return}张三减10块sql := `update bill set money=money - 10 where name = ?;`result, err := tx.exec(张三减10块sql, "张三")if err != nil { //有错误表示更是失败,回滚原来状态 tx.rollback() fmt.println(err) return}张三受影响行数, err := result.rowsaffected()if err != nil { tx.rollback() // 回滚 return}李四加10块sql := `update bill set money=money + 10 where name = ?;`result, err = tx.exec(李四加10块sql, "李四")if err != nil { //有错误表示更是失败,回滚原来状态 tx.rollback() fmt.println(err) return}李四受影响行数, err := result.rowsaffected()if err != nil { tx.rollback() // 回滚 return}//都等于1表示成功,可以提交事务,修改数据if 张三受影响行数==1 && 李四受影响行数==1{ //提交事务 fmt.println("提交事务") tx.commit()}else{ //有一个!=1表示没有更新成功,可能用户不存在 fmt.println("失败了,事物回滚了") tx.rollback()}fmt.println("事物执行成功")
执行结果
mysql
nameexec
做增 删 改使用。
nameexec方法是通过结构体或map绑定sql语句,试了试,感觉用处不大,不做举例。
namequery做查询使用。
用法同上,没用,不做举例。
总结其实sqlx模块,最大的改进是在查询方面,相信你也看到了,确实会比原生查询方便很多很多。
但是在其他方便,就显得捉襟见肘了,但是又说,一般还是查询场景多,查多改少。
以上就是go语言增强版操作mysql(sqlx)的详细内容。