go database/sql sql-driver/mysql 操作

這里使用的是github.com/Go-SQL-Driver/MySQL,

所以需要下載一個(gè)github.com/Go-SQL-Driver/MySQL

引入 database/sql 和?github.com/Go-SQL-Driver/MySQL

這里實(shí)現(xiàn)了對數(shù)據(jù)庫的 增、刪、改、查、事務(wù)

這里直接上代碼,代碼中有詳細(xì)的解釋。并且這些操作都經(jīng)過我實(shí)際操作

引入需要的包

import(

? ? "database/sql"? ? _"github.com/Go-SQL-Driver/MySQL""log""strconv"

? ? //"reflect"? ? //獲取變量類型用

)

增:

func main (){

? ? //insert name :="name"? ? pwd :="password"? ? nickname :="nickname"? ? db,err := sql.Open("mysql","go_mysql_user:go_mysql_pwd@tcp(localhost:3306)/go_mysql?charset=utf8")

? ? iferr != nil{

? ? ? ? ? ? panic(err.Error())

? ? ? ? ? ? log.Println(err)

? ? ? ? ? ? return? ? }

? ? defer db.Close()? //只有在前面用了 panic[拋出異常] 這時(shí)defer才能起作用,如果鏈接數(shù)據(jù)的時(shí)候出問題,他會往err寫數(shù)據(jù)。defer:延遲,這里立刻申請了一個(gè)關(guān)閉sql 鏈接的草錯(cuò),defer 后的方法,或延遲執(zhí)行。在函數(shù)拋出異常一會被執(zhí)行insert_sql :="insert into users (name,pwd,nickname) value (?,?,?),(?,?,?),(?,?,?),(?,?,?)"? ? stmt,err := db.Prepare(insert_sql)//準(zhǔn)備一個(gè)sql操作,返回一個(gè)*Stmt,用戶后面的執(zhí)行,這個(gè)Stmt可以被多次執(zhí)行,或者并發(fā)執(zhí)行/*? ? *? ? 這個(gè)stmt的主要方法:Exec、Query、QueryRow、Close

? ? */iferr != nil {

? ? ? ? ? ? log.Println(err)

? ? ? ? ? ? return

? ? }

? ? res,err := stmt.Exec(name,pwd,nickname,name,pwd,nickname,name,pwd,nickname,name,pwd,nickname)

? ? iferr != nil {

? ? ? ? ? ? log.Println(err)

? ? ? ? ? ? return

? ? }

? ? lastInsertId,err := res.LastInsertId()//批量插入的時(shí)候LastInserId返回的是第一條id,單條插入則返回這條的id

? ? //lastInsertId,err := res.RowsAffected()? ? ? ? //插入的是后RowsAffected 返回的是插入的條數(shù)iferr != nil {

? ? ? ? ? ? log.Println(err)

? ? ? ? ? ? return

? ? }

? ? //log.Println(reflect.TypeOf(lastInsertId))? ? //打印變量類型last_insert_id_string := strconv.FormatInt(lastInsertId,10)//int64 轉(zhuǎn)string 需要引入 strconv包log.Println("lastInsertId = "+ last_insert_id_string)

}

刪:

func main (){

? ? //deletedel_sql :="delete from users where id=?"? ? del_stmt,del_err := db.Prepare(del_sql)

? ? del_stmt.Exec(6)//不返回任何結(jié)果

}

改:

func main (){

? ? //updateupdate_sql :="update users set name=? where id=?"? ? update_stmt,update_err := db.Prepare(update_sql)

? ? ifupdate_err != nil {

? ? ? ? ? ? log.Println(update_err)

? ? ? ? ? ? return;

? ? }

? ? update_res,update_err := update_stmt.Exec("username",9)

? ? ifupdate_err != nil {

? ? ? ? ? ? log.Printf("%v",update_err)

? ? ? ? ? ? return? ? }

? ? affect_count,_ := update_res.RowsAffected()//返回影響的條數(shù),注意有兩個(gè)返回值log.Printf("%v",affect_count)

}

查一條:

type Userstruct{

? ? id int? ? name string? ? pwd string? ? nickname string}

func main (){

? ? //selectvar user User

? ? select_sql :="select * from users where id > ?"? ? select_err := db.QueryRow(select_sql,11).Scan(&user.id,&user.name,&user.pwd,&user.nickname)//查詢一條,返回一條結(jié)果。并賦值到user這個(gè)結(jié)構(gòu)體類型的變量中,就算查詢到的是多條,單返回的還是一條ifselect_err != nil {//如果沒有查詢到任何數(shù)據(jù)就進(jìn)入if中err:no rows in result set? ? ? ? ? ? log.Println(select_err)

? ? ? ? ? ? return? ? }

? ? log.Println(user)

}

查多條:

func main (){

? ? //查詢多條select_rows,select_err := db.Query(select_sql,16)

? ? ifselect_err != nil {

? ? ? ? ? ? log.Println(select_err)

? ? ? ? ? ? return? ? }

? ? defer select_rows.Close()

? ? for select_rows.Next(){

? ? ? ? varidintvarnamestringvarpwdstringvarnicknamestringiferr := select_rows.Scan(&id,&name,&pwd,&nickname); err != nil {

? ? ? ? ? ? ? ? log.Println(err)

? ? ? ? ? ? ? ? return? ? ? ? }

? ? ? ? log.Printf("id=%v,name=%v,pwd=%v,nickname=%v",id,name,pwd,nickname)

? ? }

}

事務(wù):

func main (){

? ? //事務(wù)tx,err := db.Begin()//聲明一個(gè)事務(wù)的開始iferr != nil {

? ? ? ? ? ? log.Println(err)

? ? ? ? ? ? return? ? }

? ? insert_sql :="insert into users (name,pwd,nickname) value(?,?,?)"? ? insert_stmt,insert_err := tx.Prepare(insert_sql)

? ? ifinsert_err != nil {

? ? ? ? ? ? log.Println(insert_err)

? ? ? ? ? ? return? ? }

? ? insert_res,insert_err := insert_stmt.Exec("tx_name","tx_pwd","tx_nickname")

? ? last_insert_id,_ := insert_res.LastInsertId()

? ? log.Println(last_insert_id)

? ? defer tx.Rollback()? ? ? ? ? ? //回滾之前上面的last_login_id是有的,但在回滾后該操作沒有被提交,被回滾了,所以上面打印的Last_login_id的這條數(shù)據(jù)是不存在與數(shù)據(jù)庫表中的

? ? //tx.Commit()? ? ? ? ? ? ? ? ? ? ? ? //這里提交了上面的操作,所以上面的執(zhí)行的sql 會在數(shù)據(jù)庫中產(chǎn)生一條數(shù)據(jù)

}

知識點(diǎn)總結(jié)和注意事項(xiàng):

db,err := sql.Open("mysql","數(shù)據(jù)庫登錄名:數(shù)據(jù)庫密碼@tcp(服務(wù)器:端口)/數(shù)據(jù)庫名?charset=utf8") 對應(yīng)修改;

defer db.Close()  defer 是延遲或異?;蛘咴摲椒ńY(jié)束時(shí)執(zhí)行的操作。這里表示有異常就關(guān)閉db 可與 panic(err.Error())=》拋出異常。配合使用。一種情況不可執(zhí)行=》你的方法進(jìn)入了死循環(huán),該方法不會結(jié)束與異常則不可執(zhí)行。

LastInsertId()  獲取插入第一條的id  有用

RowsAffected()  獲取影響/插入的條數(shù)  有用

reflect.TypeOf(i)  reflect包中TypeOf 返回的是變量i的類型

strconv.FormatInt(int64位變量,10)  strconv包中FormatInt將int64位的變量轉(zhuǎn)為string 具體是用另一篇文章中有總結(jié)

其他都在代碼中一些返回值 和使用。

mymysql與GO-MYSQL_DRIVER對比

1 go-mysql-driver是實(shí)現(xiàn)了golang標(biāo)準(zhǔn)庫database/sql的產(chǎn)物。底層實(shí)現(xiàn)比較有保證

2 go-mysql-driver雖然每個(gè)命令的運(yùn)行時(shí)間比mymysql長,但是內(nèi)存使用少得非常明顯,這點(diǎn)兩方算打平。

3 go-mysql-driver實(shí)現(xiàn)了database/sql,如果數(shù)據(jù)庫換成其他的話,不需要更改應(yīng)用邏輯的代碼。

4 go-mysql-driver實(shí)現(xiàn)了database/sql,這個(gè)接口的設(shè)計(jì)也是非常好的,基本和php中的pdo一樣,上手和學(xué)習(xí)成本低。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容