golang 之 sql
golang提供了sql包查询数据
建立连接
导入第三方包
import( "database/sql" _"github.com/go-sql-driver/mysql" )
open打开
db, err := sql.Open("mysql", "root:password@tcp(127.0.0.1:3306)/databases")
返回一个db类型后续会用来操作sql语句,err校验
if err != nil{ log.Fatal(err) }
这里需要注意的是open打开并不会校验数据源是否有效,所以需要ping一下,如果不进行ping的话,以往情况会有些童鞋因为数据源不通关闭等导致的错位在纠结半天。
err = db.Ping() if err!= nil { log.Fatal(err) }
开始操作
sql包为我们提供了几种增删改查的方法
- DB.Exec():执行不返回行(row)的查询,比如INSERT,UPDATE,DELETE
- DB.Query():用于检索(retrieval),比如SELECT
- DB.QueryRow():用于返回单行的查询,然后转交给DB.Query()查询
- db.Prepare():返回一个Stmt。Stmt对象可以执行Exec,Query,QueryRow等操作。最后要close()
而db.Prepare会为我们返回一个stmt对象,然后stmt.QueryRow等去操作
db.Prepare
stmt,err := db.Prepare("select name from groups") //查询 // 不添加Where条件 rows, err := stmt.Query() defer stmt.Close() for rows.Next() { var value string if ers := rows.Scan(&value); ers == nil { fmt.Println(value) } } // 添加where条件 stmt,err := db.Prepare("select name from groups where id=?") var name string err = stmt.QueryRow(15).Scan(&name) fmt.Println(name) var names [] string rows,err:= stmt.Query(15) defer rows.Close() for rows.Next(){ var name string if err:= rows.Scan(&name); err!= nil { log.Fatal(err) } names = append(names,name) } //增加数据 stmt, err := db.Prepare(`INSERT student (name,age) values (?,?)`) res, err := stmt.Exec("wangwu", 26) id, err := res.LastInsertId() fmt.Println("自增id=", id) //修改数据 stmt, err := db.Prepare(`UPDATE student SET age=? WHERE id=?`) res, err := stmt.Exec(21, 5) num, err := res.RowsAffected() //影响行数 fmt.Println(num) //删除数据 stmt, err := db.Prepare(`DELETE FROM student WHERE id=?`) res, err := stmt.Exec(5) num, err := res.RowsAffected() fmt.Println(num)
db操作
查询
rows, err := db.Query("SELECT * FROM groups") //构造scanArgs、values两个数组,scanArgs的每个值指向values相应值的地址 columns, _ := rows.Columns() scanArgs := make([]interface{}, len(columns)) values := make([]interface{}, len(columns)) for i := range values { scanArgs[i] = &values[i] } for rows.Next() { //将行数据保存到record字典 err = rows.Scan(scanArgs...) record := make(map[string]string) for i, col := range values { if col != nil { record[columns[i]] = string(col.([]byte)) } } fmt.Println(record) }
删除,增加,修改同db.Prepare语法,只是直接db.去调用即可
事务
sql包通过db.Begin()来开启一个事务, 通过Commit()和Rollback()方法来关闭。
tx := db.Begin() tx.Rollback() // 回滚 tx.Commit() //然后通过tx操作Exec, Query, QueryRow and Prepare 方法,流程和上面一样。示例 tx, err := db.Begin() stmt, err := tx.Prepare(`UPDATE student SET age=? WHERE id=?`) _, err = stmt.Exec(18, 5) if err != nil { tx.Rollback() panic(err) } err = tx.Commit() if err != nil { tx.Rollback() panic(err) }