MySQL是常用的關(guān)系型數(shù)據(jù)庫,本文介紹了go語言如何操作MySQL數(shù)據(jù)庫。
創(chuàng)新互聯(lián)建站是一家專注于網(wǎng)站設(shè)計(jì)制作、做網(wǎng)站與策劃設(shè)計(jì),上栗網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)建站做網(wǎng)站,專注于網(wǎng)站建設(shè)十多年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:上栗等地區(qū)。上栗做網(wǎng)站價(jià)格咨詢:18980820575
Go語言中的database/sql 包提供了保證SQL或類SQL數(shù)據(jù)庫的廣泛接口,并不提供具體的數(shù)據(jù)庫驅(qū)動(dòng)。使用database/sql包時(shí)必須注入一個(gè)數(shù)據(jù)庫驅(qū)動(dòng)。
go get -u github.com/go-sql-driver/mysql
func Open(driverName,dataSourceName string)(*DB,error)
Open打開一個(gè)driverName 指定的數(shù)據(jù)庫,dataSourceName指定數(shù)據(jù)源,一般包至少包括數(shù)據(jù)庫文件名和可能的連接信息。
package main
import (
"database/sql"
)
func main() {
dsn := "user:password@tcp(127.0.0.1:3306)/dbname"
db, err := sql.Open("mysql", dsn)
if err != nil {
panic(err)
}
defer db.Close()
}
Open函數(shù)可能只是驗(yàn)證其參數(shù),而不創(chuàng)建與數(shù)據(jù)庫的連接。如果要檢查數(shù)據(jù)源的名稱的合法性,應(yīng)該調(diào)用返回值的ping方法。
返回的DB可以安全的被多個(gè)goroutine同時(shí)調(diào)用,并會(huì)維護(hù)自身的閑置連接池。這樣一來,Open函數(shù)只需要調(diào)用一次。很少需要關(guān)閉DB.
var db *sql.DB
func initDB() (err error) {
dsn := "user:password@tcp(127.0.0.1:3306)/test"
db, err = sql.Open("mysql", dsn)
if err != nil {
return err
}
err = db.Ping()
if err != nil {
return err
}
return nil
}
func main() {
err := initDB()
if err != nil {
fmt.Printf("init db failed,err:%v\n", err)
return
}
}
其中的sql.DB 是一個(gè)數(shù)據(jù)庫操作句柄,代表一個(gè)具有零到讀個(gè)底層連接的連接池。它可以安全的被多個(gè)goroutine 同時(shí)使用。database/sql 包會(huì)自動(dòng)創(chuàng)建和釋放連接;它也會(huì)維護(hù)一個(gè)閑置的連接池。
func (db *DB) SetMaxOpenConns(n int)
SetMaxOpenConns 設(shè)置與數(shù)據(jù)庫建立連接的最大數(shù)目。如果n大于0且小于最大閑置連接數(shù),會(huì)將最大閑置連接數(shù)減小到匹配最大開啟連接數(shù)的限制。如果n<=0,不會(huì)限制最大開啟連接數(shù),默認(rèn)是0.
func (db *DB)SetMaxIdleConns(n int)
SetMaxIdleConns設(shè)置連接池中的最大閑置連接數(shù)。如果n大于最大開啟連接數(shù),則新的最大閑置連接數(shù)會(huì)減小到匹配最大開啟連接數(shù)的限制。如果n<=0,不會(huì)保留限制連接。
我們先在MySQL中創(chuàng)建一個(gè)名為sql_test的數(shù)據(jù)庫。
CREATE DATABASE sql_test;
進(jìn)入數(shù)據(jù)庫:
use sql_test;
執(zhí)行下面命令創(chuàng)建一張用于測試的數(shù)據(jù)表:
CREATE TABLE `user` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(20) DEFAULT '',
`age` INT(11) DEFAULT '0',
PRIMARY KEY(`id`)
)ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
單行查詢db.QueryRow()執(zhí)行一次查詢,并期望返回最多一行結(jié)果(即Row)。 QueryRow總是返回非nil的值,直到返回值的Scan方法被調(diào)用時(shí),才會(huì)返回被延遲的錯(cuò)誤(如:未找到結(jié)果)。
func (db *DB)QueryRow(query string, args ...interface{})*Row
具體示例代碼:
func queryRowDeme() {
sqlstr := "select id ,name,age from user where id =?"
var u user
err := db.QueryRow(sqlstr, 1).Scan(&u.id, &u.name, &u.name)
if err != nil {
fmt.Printf("scan failed,err:%v\n", err)
return
}
fmt.Printf("id:%d name:%s age:%d\n", u.id, u.name, u.age)
}
多行查詢db.Query()執(zhí)行一次查詢,返回多行結(jié)果(即Rows),一般用于執(zhí)行select命令,參數(shù)args表示query中的占位參數(shù)。
func (db *DB) Query(query string, args ...interface{}) (*Rows, error)
具體示例代碼:
func queryMultiRowDemo() {
sqlstr := "select id,name,age from user where id >?"
rows, err := db.Query(sqlstr, 0)
if err != nil {
fmt.Printf("query failed,err:%v\n", err)
return
}
defer rows.Close()
for rows.Next() {
var u user
err := rows.Scan(&u.id, &u.name, &u.age)
if err != nil {
fmt.Printf("scan failed,err:%v\n", err)
return
}
fmt.Printf("id:%d name:%s age:%d\n", u.id, u.name, u.age)
}
}
插入、更新和刪除操作都使用方法:
func (db *DB) Exec(query string, args ...interface{})(Result,err)
Exec執(zhí)行一次命令(包括查詢,刪除,更新,插入等),返回的Result是對已執(zhí)行的SQL命令的總結(jié)。參數(shù)args表示query中的占位參數(shù)。
具體插入數(shù)據(jù)示例代碼如下:
func insertRowDemo(){
sqlstr := "insert into user(name, age) values (?,?)"
ret,err :db.Exec(sqlstr,"張一",18)
if err != nil{
fmt.Printf("insert failed,err:%v\n",err)
return
}
theID,err := ret.LastInsertId()
if err != nil{
fmt.Printf("get lastinsert ID failed,err:%v\n",err)
return
}
fmt.Printf("insert success,the id is %d.\n",theID)
}
具體更新數(shù)據(jù)示例代碼如下:
func updateRowDemo(){
sqlstr := "update user set age=? where id =?"
ret ,err := db.Exec(sqlstr,39,3)
if err != nil{
fmt.Printf("update failed,err:%v\n",err)
return
}
n, err := ret.RowsAffected()
if err != nil{
fmt.Printf("get Rowaffected failed,err:%v\n",err)
return
}
fmt.Printf("update success,affected rows:%d\n",n)
}
具體刪除數(shù)據(jù)的示例代碼如下:
func deleteRowDemo(){
sqlstr = "delete from user where id =?"
ret,err := db.Exec(sqlstr,3)
if err != nil{
fmt.Printf("delete failed,err:%v\n",err)
return
}
n ,err := ret.RowsAffected()
if err != nil{
fmt.Printf("get RowsAffected failed,err:%v\n",err)
return
}
fmt.Printf("delete success,affected rows:%d\n",n)
}