内容简介:• rows.Next() 迭代查询数据.• rows.Scan() 读取每一行的值• rows.Close() 关闭查询
Go标准库中没有数据库驱动。参见 http://golang.org/s/sqldrivers 获取第三方驱动。
这里选择了Go-MySQL-Driver这个实现。地址是: https://github.com/go-sql-driver/mysql/ 。
安装:go get github.com/go-sql-driver/mysql
官方database/sql包文档: https://studygolang.com/pkgdoc
有关于 MySQL 基本操作可以去看我的另一篇简书: https://www.jianshu.com/p/2e01f4c6b626
使用的数据库定义如下
一、打开数据库
函数原型
func Open(driverName, dataSourceName string) (*DB, error)
Open打开一个dirverName指定的数据库,dataSourceName指定数据源,一般包至少括数据库文件名和(可能的)连接信息。
//第⼀步:打开数据库,格式是 ⽤户名:密码@/数据库名称?编码⽅式 db, err := sql.Open("mysql", "root:123@/mydb?charset=utf8") if err != nil { fmt.Println(err) } //关闭数据库 defer db.Close()
二、查询数据
函数原型
func (db *DB) Query(query string, args ...interface{}) (*Rows, error)
Query执行一次查询,返回多行结果(即Rows),一般用于执行select命令。参数args表示query中的占位参数。
var id int var name string var price float64 //查询数据,指定字段名,返回sql.Rows结果集 rows, err := db.Query("select id,name,price from product") if err != nil { fmt.Println(err) } for rows.Next() { rows.Scan(&id, &name, &price) fmt.Println(id, name, price) } defer rows.Close()
• rows.Next() 迭代查询数据.
• rows.Scan() 读取每一行的值
• rows.Close() 关闭查询
三、查询一行数据
函数原型
func (db *DB) QueryRow(query string, args ...interface{}) *Row
QueryRow执行一次查询,并期望返回最多一行结果(即Row)。QueryRow总是返回非nil的值,直到返回值的Scan方法被调用时,才会返回被延迟的错误。
//查询⼀⾏数据可以使用and(与)限定多个条件,或者使用or(或) rows3 := db.QueryRow("SELECT id,name FROM product WHERE id = ? or price like ?", 1,1.11) // rows3 := db.QueryRow("select id,name from product where id = 1") rows3.Scan(&id, &name) fmt.Println(id, name)
四、插入一行数据
函数原型
func (s *Stmt) Exec(args ...interface{}) (Result, error)
Exec使用提供的参数执行准备好的命令状态,返回Result类型的该状态执行结果的总结。
//插⼊⼀⾏数据 ret, _ := db.Exec("insert into product(id,name,price) values(15,'dog',30)") //LastInsertId返回一个数据库生成的回应命令的整数。 //返回插入的ID insID, _ := ret.LastInsertId() fmt.Println(insID)
• ret.LastInsertId()插入的ID
• ret.RowsAffected()受影响的行数
五、修改数据
//更新数据,修改id>1的行的name ret2, _ := db.Exec("update product set name= '000' where id > ?", 1) //获取影响⾏数 aff_nums, _ := ret2.RowsAffected() fmt.Println(aff_nums)
六、删除数据
//删除数据,删除id=3的行 ret3, _ := db.Exec("delete from product where id = ?",3) delNums, _ := ret3.RowsAffected() fmt.Println(delNums)
七、预处理
函数原型
func (db *DB) Prepare(query string) (*Stmt, error)
Prepare创建一个准备好的状态用于之后的查询和命令。返回值可以同时执行多个查询和命令。
//预处理 stmt, _ := db.Prepare("select id,name from product where id=? or name=?") //查找id为3或者name为000的人 row4, _ := stmt.Query(3, "000") //注意这⾥需要Next()下,不然下⾯取不到值 for row4.Next() { row4.Scan(&id, &name) fmt.Println(id, name) } //预处理插入数据 stmt2, _ := db.Prepare("insert into product(name,id,price) values(?,?,null)") //name为lisi,id为22 rows5, _ := stmt2.Exec("lisi", 22) fmt.Println(rows5.RowsAffected())
八、事务处理
函数原型
func (db *DB) Begin() (*Tx, error)
Begin开始一个事务。隔离水平由数据库驱动决定。
//开启事务 tx, _ := db.Begin() //id为1的price+1,id为2的price-1 ret4, _ := tx.Exec("update product set price = price + 1 where id = ?", 1) ret5, _ := tx.Exec("update product set price = price - 1 where id = ?", 2) //如果id不存在,受影响行数则为0 //接收影响行数,为0则失败 updNums1, _ := ret4.RowsAffected() updNums2, _ := ret5.RowsAffected() if updNums1 > 0 && updNums2 > 0 { //只有两条更新同时成功,那么才提交 tx.Commit() //提交事务 fmt.Println("Success") } else { //否则回滚 tx.Rollback() //回退事务 fmt.Println("Fail") }
• tx.Commit() 提交事务
• tx.Rollback() 回退事务
demo
package main import ( "database/sql" "fmt" _ "github.com/go-sql-driver/mysql" ) type dbWorker struct { dsn string db *sql.DB userInfo usertb } type usertb struct { id int //NullString代表一个可为NULL的字符串。 name sql.NullString //NullInt64代表一个可为NULL的Float64值。 price sql.NullFloat64 } func main() { var err error //初始化结构体,保存数据库参数 dbw := dbWorker{ dsn: "root:123@/mydb?charset=utf8", } //打开数据库,并保存给结构体内db dbw.db, err = sql.Open("mysql", dbw.dsn) //如果打开失败,panic退出 if err != nil { panic(err) } //关闭数据库 defer dbw.db.Close() //插入数据 dbw.insertData() //获取数据 dbw.querData() } //创建方法,插入数据 func (dbw *dbWorker) insertData() { //预处理,插入数据 stmt, _ := dbw.db.Prepare(`INSERT INTO product(name,id,price) VALUES(?,null,?)`) //函数执行完毕,关闭 defer stmt.Close() //插入数据 ret, err := stmt.Exec("hz", 29) if err != nil { fmt.Println(err) return } //获取id,执行成功,打印 if LastInsertId, err := ret.LastInsertId(); err == nil { fmt.Println("LastInsertId:", LastInsertId) } //获取行号,执行成功,打印 if RowsAffected, err := ret.RowsAffected(); err == nil { fmt.Println("RowsAffected:", RowsAffected) } } //初始化userInfo func (dbw *dbWorker) querDataPre() { dbw.userInfo = usertb{} } func (dbw *dbWorker) querData() { //预处理,查询数据 stmt, _ := dbw.db.Prepare(`SELECT * From product where price >= ? AND price < ?`) defer stmt.Close() dbw.querDataPre() //取price20到30之间的数据 rows, err := stmt.Query(20, 30) defer rows.Close() if err != nil { fmt.Println(err) return } for rows.Next(){ //取出数据库数据 rows.Scan(&dbw.userInfo.id,&dbw.userInfo.name,&dbw.userInfo.price) if err != nil { fmt.Println(err.Error()) continue } //如果取出的数据为null,则赋一个0值 if !dbw.userInfo.name.Valid{ dbw.userInfo.name.String = "" } if !dbw.userInfo.price.Valid{ dbw.userInfo.price.Float64 = 0.00 } fmt.Println("get data,id:",dbw.userInfo.id,"name:",dbw.userInfo.name.String,"price",float64(dbw.userInfo.price.Float64)) } err = rows.Err() if err != nil{ fmt.Printf(err.Error()) } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 16-《ARKit by Tutorials》读书笔记3:交互操作
- Golang学习笔记之Golang与Mysql交互二、gorm
- iOS 12 人机交互指南:交互(User Interaction)
- 生活NLP云服务“玩秘”站稳人机交互2.0语音交互场景
- asyncio之子进程交互
- 以太坊交互工具
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。