這裡使用的是github.com/Go-SQL-Driver/MySQL,
所以需要下載一個github.com/Go-SQL-Driver/MySQL
引入 database/sql 和 github.com/Go-SQL-Driver/MySQL
這裡實現了對資料庫的 增、刪、改、查、事務
這裡直接上代碼,代碼中有詳細的解釋。並且這些操作都經過我實際操作
引入需要的包
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[拋出異常] 這時defer才能起作用,如果連結資料的時候出問題,他會往err寫資料。defer:延遲,這裡立刻申請了一個關閉sql 連結的草錯,defer 後的方法,或順延強制。在函數拋出異常一會被執行insert_sql :="insert into users (name,pwd,nickname) value (?,?,?),(?,?,?),(?,?,?),(?,?,?)" stmt,err := db.Prepare(insert_sql)//準備一個sql操作,返回一個*Stmt,使用者後面的執行,這個Stmt可以被多次執行,或者並發執行/* * 這個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()//批量插入的時候LastInserId返回的是第一條id,單條插入則返回這條的id
//lastInsertId,err := res.RowsAffected() //插入的是後RowsAffected 返回的是插入的條數iferr != nil {
log.Println(err)
return
}
//log.Println(reflect.TypeOf(lastInsertId)) //列印變數類型last_insert_id_string := strconv.FormatInt(lastInsertId,10)//int64 轉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)//不返回任何結果
}
改:
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()//返回影響的條數,注意有兩個傳回值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)//查詢一條,返回一條結果。並賦值到user這個結構體類型的變數中,就算查詢到的是多條,單返回的還是一條ifselect_err != nil {//如果沒有查詢到任何資料就進入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)
}
}
事務:
func main (){
//事務tx,err := db.Begin()//聲明一個事務的開始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的這條資料是不存在與資料庫表中的
//tx.Commit() //這裡提交了上面的操作,所以上面的執行的sql 會在資料庫中產生一條資料
}
知識點總結和注意事項:
db,err := sql.Open("mysql","資料庫登入名稱:資料庫密碼@tcp(伺服器:連接埠)/資料庫名?charset=utf8") 對應修改;
defer db.Close() defer 是延遲或異常或者該方法結束時執行的操作。這裡表示有異常就關閉db 可與 panic(err.Error())=》拋出異常。配合使用。一種情況不可執行=》你的方法進入了死迴圈,該方法不會結束與異常則不可執行。
LastInsertId() 擷取插入第一條的id 有用
RowsAffected() 擷取影響/插入的條數 有用
reflect.TypeOf(i) reflect包中TypeOf 返回的是變數i的類型
strconv.FormatInt(int64位變數,10) strconv包中FormatInt將int64位的變數轉為string 具體是用另一篇文章中有總結
其他都在代碼中一些傳回值 和使用。
mymysql與GO-MYSQL_DRIVER對比
1 go-mysql-driver是實現了golang標準庫database/sql的產物。底層實現比較有保證
2 go-mysql-driver雖然每個命令的已耗用時間比mymysql長,但是記憶體使用量少得非常明顯,這點兩方算打平。
3 go-mysql-driver實現了database/sql,如果資料庫換成其他的話,不需要更改應用邏輯的代碼。
4 go-mysql-driver實現了database/sql,這個介面的設計也是非常好的,基本和php中的pdo一樣,上手和學習成本低。