博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Golang学习日志 ━━ Mysql相关
阅读量:4116 次
发布时间:2019-05-25

本文共 5539 字,大约阅读时间需要 18 分钟。

重点是看推荐的几篇文章,这里列举了一个我觉得算入门不错的文章。

Go标准库中没有数据库驱动。参见获取第三方驱动。

这里选择了Go-MySQL-Driver这个实现。地址是:。
安装:go get github.com/go-sql-driver/mysql
官方database/sql包文档:

使用的数据库定义如下

在这里插入图片描述

一、打开数据库

函数原型

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返回一个数据库生成的回应命令的整数。//返回插入的IDinsID, _ := ret.LastInsertId()fmt.Println(insID)

• ret.LastInsertId()插入的ID

• ret.RowsAffected()受影响的行数

五、修改数据

//更新数据,修改id>1的行的nameret2, _ := 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 mainimport (    "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) }}//初始化userInfofunc (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()) }}

转载地址:http://etkpi.baihongyu.com/

你可能感兴趣的文章
js 冒泡事件与解决冒泡事件
查看>>
【Vue.js 入门到实战教程】05-Vue.js 中属性和类名绑定的使用示例
查看>>
8个简单的JavaScript数字方法
查看>>
【Vue.js 入门到实战教程】06-在 Vue.js 中通过计算属性动态设置属性值
查看>>
在JavaScript中使用filter()的4个实用案例
查看>>
【Vue.js 入门到实战教程】07-Vue 组件注册 | 基本使用和组件嵌套
查看>>
9 个功能强大的 JavaScript 技巧
查看>>
你应该知道的TypeScript高级概念
查看>>
【Vue.js 入门到实战教程】08-Vue 组件通信 | 父子组件之间的数据传递和事件监听...
查看>>
如何实现页面中有间隔的方格布局?
查看>>
【视频教程】帝国CMS制作网站系列教程16—帝国CMS总结
查看>>
从6个方面净化你的Js代码
查看>>
如何实现文本内容折叠并显示“...查看全部”?
查看>>
在浏览器地址栏输入url到按下回车发生了什么?
查看>>
Vue关键词搜索高亮
查看>>
【Vue.js 入门到实战教程】09-Vue 组件插槽 | 父子组件间的内容分发和插槽作用域...
查看>>
JS树结构操作:查找、遍历、筛选、树结构和列表结构相互转换
查看>>
【Vue.js 入门到实战教程】10-Vue Loader (上)| 基于 Vue CLI 初始化原型项目
查看>>
快速实现一个简单可复用可扩展的Vue树组件
查看>>
文章页面目录自动生成方案
查看>>