go mysql基本操作

本人是新學(xué)go語言,文章僅供學(xué)習(xí)所用冰寻,如有錯(cuò)誤之處仲器,煩請(qǐng)指正煤率。

一、簡(jiǎn)介

go中支持的MySQL驅(qū)動(dòng)比較多乏冀,推薦最多的是https://github.com/go-sql-driver/mysql,支持database/sql標(biāo)準(zhǔn)蝶糯。

二、使用前的準(zhǔn)備

1.引用

需要引用兩個(gè)包

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

備注:_是只引入包名(即只使用init函數(shù)注冊(cè)mysql數(shù)據(jù)庫驅(qū)動(dòng))而不直接使用保重定義的函數(shù)

2.連接數(shù)據(jù)庫

sql.Open() 打開一個(gè)由其數(shù)據(jù)庫驅(qū)動(dòng)程序名稱和驅(qū)動(dòng)程序特定的數(shù)據(jù)源名稱指定的數(shù)據(jù)庫辆沦,通常由至少一個(gè)數(shù)據(jù)庫名稱和連接信息組成昼捍。方法定義如下:
func Open(driverName, dataSourceName string) (*DB, error)

有兩個(gè)參數(shù):第一個(gè)參數(shù)driverName是注冊(cè)進(jìn)去的數(shù)據(jù)庫名稱识虚,第二個(gè)參數(shù)是數(shù)據(jù)庫連接和配置信息。格式如下:
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()方法為以后的查詢或執(zhí)行創(chuàng)建一個(gè)準(zhǔn)備好的語句(用于增刪改),返回一個(gè)準(zhǔn)備完畢的執(zhí)行狀態(tài)stmt
func (db *DB) Prepare(query string) (*Stmt, error)
stmt.Exec()使用給定的參數(shù)執(zhí)行一個(gè)準(zhǔn)備好的語句担锤,并返回一個(gè)總結(jié)語句效果的Result結(jié)果集
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)
}
//新增一條數(shù)據(jù)
stmt, err := db.Prepare(`INSERT user (uname, age, mobile) VALUES (?, ?, ?)`)
if err != nil {
    panic(err)
}
defer stmt.Close() //延時(shí)關(guān)閉一個(gè)準(zhǔn)備好的資源
res, err := stmt.Exec("fightWang",28,"18888888888")
if err != nil {
    panic(err)
}
//更新數(shù)據(jù)(修改id=5的數(shù)據(jù))
stmt, err = db.Prepare("update user set mobile=? where id=?")
if err != nil {
    panic(err)
}
res, err = stmt.Exec("18899999999",5) 
//刪除數(shù)據(jù)(刪除id=5的數(shù)據(jù))
stmt, err = db.Prepare("DELETE FROM user where id=?")
if err != nil {
    panic(err)
}
res, err = stmt.Exec(5) 

增刪改也可以直接使用db.Exec()方法(注意與stmt.Exec()的區(qū)別)
func (db *DB) Exec(query string, args ...interface{}) (Result, error)

2.查(多條)

與增刪改一樣乍钻,可以配合db.Prepare()使用stmt.Query()方法來查詢肛循,結(jié)果返回Rows結(jié)果集
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()的區(qū)別)
func (db *DB) Query(query string, args ...interface{}) (*Rows, error)

rows返回結(jié)果是多個(gè)結(jié)果行的集合,可以通過rows.Next()和rows.Scan()方法來獲取行內(nèi)數(shù)據(jù)
rows.Next()接下來準(zhǔn)備下一個(gè)結(jié)果行以便用Scan方法讀取团赁。它在成功時(shí)返回true育拨,如果沒有下一個(gè)結(jié)果行或在準(zhǔn)備過程中發(fā)生錯(cuò)誤,則返回false欢摄。
func (rs *Rows) Next() bool
rows.Close() 關(guān)閉行熬丧,防止進(jìn)一步枚舉。如果Next被調(diào)用并返回false怀挠,并且沒有其他結(jié)果集析蝴,則行自動(dòng)關(guān)閉,并且檢查Err的結(jié)果就足夠了绿淋。關(guān)閉是冪等的闷畸,不會(huì)影響Err的結(jié)果。故在調(diào)用的時(shí)候使用defer rows.Close()是一個(gè)好習(xí)慣
func (rs *Rows) Close() error
rows.Scan()將當(dāng)前行中的列復(fù)制到dest指向的值中吞滞。dest中的值數(shù)量必須與行中的列數(shù)相同
func (rs *Rows) Scan(dest ...interface{}) error

rows, err := db.Query("SELECT * FROM user") //user表中共四個(gè)字段
if err != nil {
    panic(err)
}
defer rows.Close()
uid, uname, age, mobile := 0,"",0,""
for rows.Next() {
    err = rows.Scan(&uid,&uname,&age,&mobile) //要四個(gè)字段一一對(duì)齊
    if err != nil {
        panic(err)
    }
    fmt.Println(uid, uname, age, mobile)
}
3.查詢(單條查詢)

可以通過db.QueryRow()或者配合db.Prepare()和stmt.QueryRow()查詢單條結(jié)果佑菩。
db.QueryRow()執(zhí)行一個(gè)查詢,該查詢最多只返回一行裁赠。QueryRow總是返回一個(gè)非零值殿漠。錯(cuò)誤被推遲到行的掃描方法被調(diào)用(row.Scan())。
func (db *DB) QueryRow(query string, args ...interface{}) *Row
stmt.QueryRow()使用給定的參數(shù)執(zhí)行一個(gè)準(zhǔn)備好的查詢語句佩捞。如果在執(zhí)行語句期間發(fā)生錯(cuò)誤绞幌,則在返回的*行上調(diào)用Scan以返回該錯(cuò)誤,該行總是非零
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: //當(dāng)QueryRow沒有返回行時(shí)一忱,Scan返回ErrNoRows莲蜘。在這種情況下,QueryRow會(huì)返回一個(gè)占位符* Row值帘营,該值將推遲發(fā)生此錯(cuò)誤直到掃描票渠。
        log.Printf("No user with that ID.")
case err != nil:
        log.Fatal(err)
default:
        fmt.Printf("Username is %s\n", username)
}

四、mysql其他常用操作

1.獲取執(zhí)行插入行操作的主鍵id值

LastInsertId() (int64, error)

//新增一條數(shù)據(jù)
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.返回受到影響的行數(shù)(Insert | Update | Delete)
num, err := res.RowsAffected()
if err != nil {
    panic(err)
}
fmt.Println(num) //返回新插入行的主鍵
3.獲取表的字段(列)名(僅用于多條查詢)

rows.Columns() 將返回列名稱組成的slice芬迄。如果行關(guān)閉庄新,或者行來自QueryRow并且存在延遲錯(cuò)誤,則列將返回錯(cuò)誤。
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]
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末择诈,一起剝皮案震驚了整個(gè)濱河市械蹋,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌羞芍,老刑警劉巖哗戈,帶你破解...
    沈念sama閱讀 211,817評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件荷科,死亡現(xiàn)場(chǎng)離奇詭異唯咬,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)畏浆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門胆胰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人刻获,你說我怎么就攤上這事蜀涨。” “怎么了蝎毡?”我有些...
    開封第一講書人閱讀 157,354評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵厚柳,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我沐兵,道長(zhǎng)别垮,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,498評(píng)論 1 284
  • 正文 為了忘掉前任扎谎,我火速辦了婚禮碳想,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘毁靶。我一直安慰自己胧奔,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評(píng)論 6 386
  • 文/花漫 我一把揭開白布老充。 她就那樣靜靜地躺著,像睡著了一般螟左。 火紅的嫁衣襯著肌膚如雪啡浊。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,829評(píng)論 1 290
  • 那天胶背,我揣著相機(jī)與錄音巷嚣,去河邊找鬼。 笑死钳吟,一個(gè)胖子當(dāng)著我的面吹牛廷粒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 38,979評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼坝茎,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼涤姊!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起嗤放,我...
    開封第一講書人閱讀 37,722評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤思喊,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后次酌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體恨课,經(jīng)...
    沈念sama閱讀 44,189評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評(píng)論 2 327
  • 正文 我和宋清朗相戀三年岳服,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了剂公。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,654評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡吊宋,死狀恐怖纲辽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情贫母,我是刑警寧澤文兑,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站腺劣,受9級(jí)特大地震影響绿贞,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜橘原,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評(píng)論 3 313
  • 文/蒙蒙 一籍铁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧趾断,春花似錦拒名、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至脐帝,卻和暖如春同云,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背堵腹。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評(píng)論 1 266
  • 我被黑心中介騙來泰國打工炸站, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人疚顷。 一個(gè)月前我還...
    沈念sama閱讀 46,382評(píng)論 2 360
  • 正文 我出身青樓旱易,卻偏偏與公主長(zhǎng)得像禁偎,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子阀坏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容

  • No.1 文檔概要 在Golang中使用SQL或類似SQL的數(shù)據(jù)庫的慣用方法是通過 database/sql 包操...
    尼古拉斯河馬閱讀 27,302評(píng)論 5 14
  • 這三張照片如暖,第一張是我和妞去廈門旅游,我們?cè)谫e館喝茶時(shí)拍的全释,第二張是我工作的時(shí)候留影装处,第三張是我第一次...
    敬芳1972閱讀 677評(píng)論 0 2
  • 1. 你有沒有遇到過十分厭惡自己的情況李命?大概這個(gè)時(shí)候的你登淘,會(huì)覺得自己很讓人討厭,自己做什么事情都是錯(cuò)的封字。厭惡到連看...
    拂逆之間閱讀 484評(píng)論 2 4
  • You accidentally broke into my world, since then my world...
    空靈如幽閱讀 104評(píng)論 0 2
  • 得到也是一種失去,失去也是一種收獲笆制。-------少俠 來北京后绅这,堅(jiān)持寫的文章,已經(jīng)中斷幾個(gè)月沒寫了≡诹荆現(xiàn)在...
    hello袁先森閱讀 304評(píng)論 0 0