go mysql基本操作

本人是新学go语言,文章仅供学习所用,如有错误之处,烦请指正。

一、简介

go中支持的MySQL驱动比较多,推荐最多的是https://github.com/go-sql-driver/mysql,支持database/sql标准。

二、使用前的准备

1.引用

需要引用两个包

import "database/sql"
import _ "github.com/go-sql-driver/mysql"

备注:_是只引入包名(即只使用init函数注册mysql数据库驱动)而不直接使用保重定义的函数

2.连接数据库

sql.Open() 打开一个由其数据库驱动程序名称和驱动程序特定的数据源名称指定的数据库,通常由至少一个数据库名称和连接信息组成。方法定义如下:
func Open(driverName, dataSourceName string) (*DB, error)

有两个参数:第一个参数driverName是注册进去的数据库名称,第二个参数是数据库连接和配置信息。格式如下:
user@unix(/path/to/socket)/dbname?charset=utf8
user:password@tcp(localhost:3306)/dbname?charset=utf8(推荐)
user:password@/dbname
user:password@tcp([de:ad:be:ef::ca:fe]:80)/dbname

db,err := sql.Open("mysql", "root:@tcp(localhost:3306)/default?charset=utf8")
if err != nil {
    panic(err)
}

三、mysql基本操作(增删改查)

db.Prepare()方法为以后的查询或执行创建一个准备好的语句(用于增删改),返回一个准备完毕的执行状态stmt
func (db *DB) Prepare(query string) (*Stmt, error)
stmt.Exec()使用给定的参数执行一个准备好的语句,并返回一个总结语句效果的Result结果集
func (s *Stmt) Exec(args ...interface{}) (Result, error)

1.增改查(操作都差不多,故放一块)
db,err := sql.Open("mysql", "root:root@tcp(localhost:3306)/default?charset=utf8")
if err != nil {
    panic(err)
}
//新增一条数据
stmt, err := db.Prepare(`INSERT user (uname, age, mobile) VALUES (?, ?, ?)`)
if err != nil {
    panic(err)
}
defer stmt.Close() //延时关闭一个准备好的资源
res, err := stmt.Exec("fightWang",28,"18888888888")
if err != nil {
    panic(err)
}
//更新数据(修改id=5的数据)
stmt, err = db.Prepare("update user set mobile=? where id=?")
if err != nil {
    panic(err)
}
res, err = stmt.Exec("18899999999",5) 
//删除数据(删除id=5的数据)
stmt, err = db.Prepare("DELETE FROM user where id=?")
if err != nil {
    panic(err)
}
res, err = stmt.Exec(5) 

增删改也可以直接使用db.Exec()方法(注意与stmt.Exec()的区别)
func (db *DB) Exec(query string, args ...interface{}) (Result, error)

2.查(多条)

与增删改一样,可以配合db.Prepare()使用stmt.Query()方法来查询,结果返回Rows结果集
func (s *Stmt) Query(args ...interface{}) (*Rows, error)

stmt, err := db.Prepare(`SELECT * FROM user WHERE mobile=?`)
if err != nil {
    panic(err)
}
rows, err := stmt.Query("18888888888")
if err != nil {
    panic(err)
}

查询操作也可以直接使用db.Query()方法(注意与stmt.Query()的区别)
func (db *DB) Query(query string, args ...interface{}) (*Rows, error)

rows返回结果是多个结果行的集合,可以通过rows.Next()和rows.Scan()方法来获取行内数据
rows.Next()接下来准备下一个结果行以便用Scan方法读取。它在成功时返回true,如果没有下一个结果行或在准备过程中发生错误,则返回false。
func (rs *Rows) Next() bool
rows.Close() 关闭行,防止进一步枚举。如果Next被调用并返回false,并且没有其他结果集,则行自动关闭,并且检查Err的结果就足够了。关闭是幂等的,不会影响Err的结果。故在调用的时候使用defer rows.Close()是一个好习惯
func (rs *Rows) Close() error
rows.Scan()将当前行中的列复制到dest指向的值中。dest中的值数量必须与行中的列数相同
func (rs *Rows) Scan(dest ...interface{}) error

rows, err := db.Query("SELECT * FROM user") //user表中共四个字段
if err != nil {
    panic(err)
}
defer rows.Close()
uid, uname, age, mobile := 0,"",0,""
for rows.Next() {
    err = rows.Scan(&uid,&uname,&age,&mobile) //要四个字段一一对齐
    if err != nil {
        panic(err)
    }
    fmt.Println(uid, uname, age, mobile)
}
3.查询(单条查询)

可以通过db.QueryRow()或者配合db.Prepare()和stmt.QueryRow()查询单条结果。
db.QueryRow()执行一个查询,该查询最多只返回一行。QueryRow总是返回一个非零值。错误被推迟到行的扫描方法被调用(row.Scan())。
func (db *DB) QueryRow(query string, args ...interface{}) *Row
stmt.QueryRow()使用给定的参数执行一个准备好的查询语句。如果在执行语句期间发生错误,则在返回的*行上调用Scan以返回该错误,该行总是非零
func (s *Stmt) QueryRow(args ...interface{}) *Row

id := 123
var username string
err := db.QueryRow("SELECT username FROM users WHERE id=?", id).Scan(&username)
switch {
case err == sql.ErrNoRows: //当QueryRow没有返回行时,Scan返回ErrNoRows。在这种情况下,QueryRow会返回一个占位符* Row值,该值将推迟发生此错误直到扫描。
        log.Printf("No user with that ID.")
case err != nil:
        log.Fatal(err)
default:
        fmt.Printf("Username is %s\n", username)
}

四、mysql其他常用操作

1.获取执行插入行操作的主键id值

LastInsertId() (int64, error)

//新增一条数据
stmt, err := db.Prepare(`INSERT user (uname, age, mobile) VALUES (?, ?, ?)`)
if err != nil {
    panic(err)
}
res, err := stmt.Exec("fightWang",28,"18888888888")
if err != nil {
    panic(err)
}
uid, err := res.LastInsertId()
if err != nil {
    panic(err)
}
fmt.Println(uid) //返回新插入行的主键
2.返回受到影响的行数(Insert | Update | Delete)
num, err := res.RowsAffected()
if err != nil {
    panic(err)
}
fmt.Println(num) //返回新插入行的主键
3.获取表的字段(列)名(仅用于多条查询)

rows.Columns() 将返回列名称组成的slice。如果行关闭,或者行来自QueryRow并且存在延迟错误,则列将返回错误。
func (rs *Rows) Columns() ([]string, error)

stmt, err := db.Prepare("SELECT * FROM user")
if err != nil {
    panic(err)
}
defer stmt.Close()
rows, err := stmt.Query()
if err != nil {
    panic(err)
}
defer rows.Close()
columns, err := rows.Columns()
if err != nil {
    panic(err)
}
fmt.Println(columns) //[id uname age mobile]
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,529评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,015评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,409评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,385评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,387评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,466评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,880评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,528评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,727评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,528评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,602评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,302评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,873评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,890评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,132评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,777评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,310评论 2 342

推荐阅读更多精彩内容

  • No.1 文档概要 在Golang中使用SQL或类似SQL的数据库的惯用方法是通过 database/sql 包操...
    尼古拉斯河马阅读 27,263评论 5 14
  • 这三张照片,第一张是我和妞去厦门旅游,我们在宾馆喝茶时拍的,第二张是我工作的时候留影,第三张是我第一次...
    敬芳1972阅读 672评论 0 2
  • 1. 你有没有遇到过十分厌恶自己的情况?大概这个时候的你,会觉得自己很让人讨厌,自己做什么事情都是错的。厌恶到连看...
    拂逆之间阅读 482评论 2 4
  • You accidentally broke into my world, since then my world...
    空灵如幽阅读 103评论 0 2
  • 得到也是一种失去,失去也是一种收获。-------少侠 来北京后,坚持写的文章,已经中断几个月没写了。现在...
    hello袁先森阅读 298评论 0 0