go get github.com/go-sql-driver/mysql
一、打开数据库
func Open(driverName, dataSourceName string) (*DB, error)
1//第⼀步:打开数据库,格式是 ⽤户名:密码@/数据库名称?编码⽅式
2 db, err := sql.Open("mysql", "root:123@/mydb?charset=utf8")
3 if err != nil {
4 fmt.Println(err)
5 }
6 //关闭数据库
7 defer db.Close()
二、查询数据
func (db *DB) Query(query string, args ...interface{}) (*Rows, error)
1var id int
2 var name string
3 var price float64
4 //查询数据,指定字段名,返回sql.Rows结果集
5 rows, err := db.Query("select id,name,price from product")
6 if err != nil {
7 fmt.Println(err)
8 }
9 for rows.Next() {
10 rows.Scan(&id, &name, &price)
11 fmt.Println(id, name, price)
12 }
13 defer rows.Close()
• rows.Next() 迭代查询数据. • rows.Scan() 读取每一行的值 • rows.Close() 关闭查询
三、查询一行数据
func (db *DB) QueryRow(query string, args ...interface{}) *Row
1//查询⼀⾏数据可以使用and(与)限定多个条件,或者使用or(或)
2 rows3 := db.QueryRow("SELECT id,name FROM product WHERE id = ? or price like ?", 1,1.11)
3 // rows3 := db.QueryRow("select id,name from product where id = 1")
4 rows3.Scan(&id, &name)
5 fmt.Println(id, name)
6
四、插入一行数据
func (s *Stmt) Exec(args ...interface{}) (Result, error)
1//插⼊⼀⾏数据
2 ret, _ := db.Exec("insert into product(id,name,price) values(15,'dog',30)")
3 //LastInsertId返回一个数据库生成的回应命令的整数。
4 //返回插入的ID
5 insID, _ := ret.LastInsertId()
6 fmt.Println(insID)
7
• ret.LastInsertId()插入的ID • ret.RowsAffected()受影响的行数
五、修改数据
1//更新数据,修改id>1的行的name
2 ret2, _ := db.Exec("update product set name= '000' where id > ?", 1)
3 //获取影响⾏数
4 aff_nums, _ := ret2.RowsAffected()
5 fmt.Println(aff_nums)
六、删除数据
1 //删除数据,删除id=3的行
2 ret3, _ := db.Exec("delete from product where id = ?",3)
3 delNums, _ := ret3.RowsAffected()
4 fmt.Println(delNums)
5
七、预处理
func (db *DB) Prepare(query string) (*Stmt, error)
1 //预处理
2 stmt, _ := db.Prepare("select id,name from product where id=? or name=?")
3 //查找id为3或者name为000的人
4 row4, _ := stmt.Query(3, "000")
5 //注意这⾥需要Next()下,不然下⾯取不到值
6 for row4.Next() {
7 row4.Scan(&id, &name)
8 fmt.Println(id, name)
9 }
10 //预处理插入数据
11 stmt2, _ := db.Prepare("insert into product(name,id,price) values(?,?,null)")
12 //name为lisi,id为22
13 rows5, _ := stmt2.Exec("lisi", 22)
14 fmt.Println(rows5.RowsAffected())
15
八、事务处理
func (db *DB) Begin() (*Tx, error)
1//开启事务
2 tx, _ := db.Begin()
3 //id为1的price+1,id为2的price-1
4 ret4, _ := tx.Exec("update product set price = price + 1 where id = ?", 1)
5 ret5, _ := tx.Exec("update product set price = price - 1 where id = ?", 2)
6
7 //如果id不存在,受影响行数则为0
8 //接收影响行数,为0则失败
9 updNums1, _ := ret4.RowsAffected()
10 updNums2, _ := ret5.RowsAffected()
11 if updNums1 > 0 && updNums2 > 0 { //只有两条更新同时成功,那么才提交
12 tx.Commit() //提交事务
13 fmt.Println("Success")
14 } else { //否则回滚
15 tx.Rollback() //回退事务
16 fmt.Println("Fail")
17 }
• tx.Commit() 提交事务 • tx.Rollback() 回退事务
demo
1package main
2import (
3 "database/sql"
4 "fmt"
5
6 _ "github.com/go-sql-driver/mysql"
7)
8type dbWorker struct {
9 dsn string
10 db *sql.DB
11 userInfo usertb
12}
13type usertb struct {
14 id int
15 //NullString代表一个可为NULL的字符串。
16 name sql.NullString
17 //NullInt64代表一个可为NULL的Float64值。
18 price sql.NullFloat64
19}
20func main() {
21 var err error
22 //初始化结构体,保存数据库参数
23 dbw := dbWorker{
24 dsn: "root:123@/mydb?charset=utf8",
25 }
26 //打开数据库,并保存给结构体内db
27 dbw.db, err = sql.Open("mysql", dbw.dsn)
28 //如果打开失败,panic退出
29 if err != nil {
30 panic(err)
31 }
32 //关闭数据库
33 defer dbw.db.Close()
34 //插入数据
35 dbw.insertData()
36 //获取数据
37 dbw.querData()
38}
39
40//创建方法,插入数据
41func (dbw *dbWorker) insertData() {
42 //预处理,插入数据
43 stmt, _ := dbw.db.Prepare(`INSERT INTO product(name,id,price) VALUES(?,null,?)`)
44 //函数执行完毕,关闭
45 defer stmt.Close()
46 //插入数据
47 ret, err := stmt.Exec("hz", 29)
48 if err != nil {
49 fmt.Println(err)
50 return
51 }
52 //获取id,执行成功,打印
53 if LastInsertId, err := ret.LastInsertId(); err == nil {
54 fmt.Println("LastInsertId:", LastInsertId)
55 }
56 //获取行号,执行成功,打印
57 if RowsAffected, err := ret.RowsAffected(); err == nil {
58 fmt.Println("RowsAffected:", RowsAffected)
59 }
60}
61
62//初始化userInfo
63func (dbw *dbWorker) querDataPre() {
64 dbw.userInfo = usertb{}
65}
66func (dbw *dbWorker) querData() {
67
68 //预处理,查询数据
69 stmt, _ := dbw.db.Prepare(`SELECT * From product where price >= ? AND price < ?`)
70
71 defer stmt.Close()
72
73 dbw.querDataPre()
74 //取price20到30之间的数据
75 rows, err := stmt.Query(20, 30)
76 defer rows.Close()
77 if err != nil {
78 fmt.Println(err)
79 return
80 }
81 for rows.Next(){
82 //取出数据库数据
83 rows.Scan(&dbw.userInfo.id,&dbw.userInfo.name,&dbw.userInfo.price)
84 if err != nil {
85 fmt.Println(err.Error())
86 continue
87 }
88 //如果取出的数据为null,则赋一个0值
89 if !dbw.userInfo.name.Valid{
90 dbw.userInfo.name.String = ""
91 }
92 if !dbw.userInfo.price.Valid{
93 dbw.userInfo.price.Float64 = 0.00
94 }
95 fmt.Println("get data,id:",dbw.userInfo.id,"name:",dbw.userInfo.name.String,"price",float64(dbw.userInfo.price.Float64))
96 }
97 err = rows.Err()
98 if err != nil{
99 fmt.Printf(err.Error())
100 }
101}