一.gorm連接mysql數據庫
gorm支持多種數據庫,這里主要介紹mysql,連接mysql主要有兩個步驟:
- 配置DSN (Data Source Name)
- 使用gorm.Open連接數據庫
1. 配置DSN (Data Source Name)
gorm庫使用dsn作為連接數據庫的參數,dsn翻譯過來就叫數據源名稱,用來描述數據庫連接信息。一般都包含數據庫連接地址,賬號,密碼之類的信息。
DSN格式:
[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...¶mN=valueN]
mysql連接dsn例子:
//mysql dsn格式
//涉及參數:
//username 數據庫賬號
//password 數據庫密碼
//host 數據庫連接地址,可以是Ip或者域名
//port 數據庫端口
//Dbname 數據庫名
username:password@tcp(host:port)/Dbname?charset=utf8&parseTime=True&loc=Local
//填上參數后的例子
//username = root
//password = 123456
//host = localhost
//port = 3306
//Dbname = tizi365
//后面K/V鍵值對參數含義為:
// charset=utf8 客戶端字符集為utf8
// parseTime=true 支持把數據庫datetime和date類型轉換為golang的time.Time類型
// loc=Local 使用系統本地時區
root:123456@tcp(localhost:3306)/tizi365?charset=utf8&parseTime=True&loc=Local
//gorm 設置mysql連接超時參數
//開發的時候經常需要設置數據庫連接超時參數,gorm是通過dsn的timeout參數配置
//例如,設置10秒后連接超時,timeout=10s
//下面是完成的例子
root:123456@tcp(localhost:3306)/tizi365?charset=utf8&parseTime=True&loc=Local&timeout=10s
//設置讀寫超時時間
// readTimeout - 讀超時時間,0代表不限制
// writeTimeout - 寫超時時間,0代表不限制
root:123456@tcp(localhost:3306)/tizi365?charset=utf8&parseTime=True&loc=Local&timeout=10s&readTimeout=30s&writeTimeout=60s
2. 使用gorm.Open連接數據庫
有了上面配置的dsn參數,就可以使用gorm連接數據庫,下面是連接數據庫的例子
package main import ( "gorm.io/driver/mysql" "gorm.io/gorm" ) func main() {
//配置MySQL連接參數
username := "root" //賬號
password := "123456" //密碼
host := "127.0.0.1" //數據庫地址,可以是Ip或者域名
port := 3306 //數據庫端口
Dbname := "tizi365" //數據庫名
timeout := "10s" //連接超時,10秒
//拼接下dsn參數, dsn格式可以參考上面的語法,這里使用Sprintf動態拼接dsn參數,因為一般數據庫連接參數,我們都是保存在配置文件里面,需要從配置文件加載參數,然后拼接dsn。
dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True&loc=Local&timeout=%s", username, password, host, port, Dbname, timeout)
//連接MYSQL, 獲得DB類型實例,用於后面的數據庫讀寫操作。
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic("連接數據庫失敗, error=" + err.Error())
}
//延時關閉數據庫連接
defer db.Close()
}
3. gorm調試模式
為了方便調試,了解gorm操作到底執行了怎么樣的sql語句,開發的時候需要打開調試日志,這樣gorm會打印出執行的每一條sql語句。
使用Debug函數執行查詢即可
例子:
result := db.Debug().Where("username = ?", "tizi365").First(&u)
二.gorm連接池
在高並發實踐中,為了提高數據庫連接的使用率,避免重復建立數據庫連接帶來的性能消耗,會經常使用數據庫連接池技術來維護數據庫連接。
gorm自帶了數據庫連接池使用非常簡單只要設置下數據庫連接池參數即可。
數據庫連接池使用例子:
定義tools包,負責數據庫初始化工作
//定義一個工具包,用來管理gorm數據庫連接池的初始化工作。
package tools
//定義全局的db對象,我們執行數據庫操作主要通過他實現。
var _db *gorm.DB
//包初始化函數,golang特性,每個包初始化的時候會自動執行init函數,這里用來初始化gorm。
func init() {
...忽略dsn配置,請參考上面例子...
// 聲明err變量,下面不能使用:=賦值運算符,否則_db變量會當成局部變量,導致外部無法訪問_db變量
var err error
//連接MYSQL, 獲得DB類型實例,用於后面的數據庫讀寫操作。
_db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic("連接數據庫失敗, error=" + err.Error())
}
sqlDB, _ := db.DB()
//設置數據庫連接池參數
sqlDB.SetMaxOpenConns(100) //設置數據庫連接池最大連接數
sqlDB.SetMaxIdleConns(20) //連接池最大允許的空閑連接數,如果沒有sql任務需要執行的連接數大於20,超過的連接會被連接池關閉。
}
//獲取gorm db對象,其他包需要執行數據庫查詢的時候,只要通過tools.getDB()獲取db對象即可。
//不用擔心協程並發使用同樣的db對象會共用同一個連接,db對象在調用他的方法的時候會從數據庫連接池中獲取新的連接
func GetDB() *gorm.DB {
return _db
}
使用例子:
package main
//導入tools包
import tools func main() {
//獲取DB
db := tools.GetDB()
//執行數據庫查詢操作
u := User{}
//自動生成sql: SELECT * FROM `users` WHERE (username = 'tizi365') LIMIT 1
db.Where("username = ?", "tizi365").First(&u)
}
注意:使用連接池技術后,千萬不要使用完db后調用db.Close關閉數據庫連接,這樣會導致整個數據庫連接池關閉,導致連接池沒有可用的連接。
更多使用
package main import ( "fmt" //_ "github.com/go-sql-driver/mysql" //"github.com/jinzhu/gorm" "gorm.io/driver/mysql" "gorm.io/gorm" ) type Students struct { gorm.Model Username string `gorm:"type:varchar(20);not null " ` Password string `gorm:"type:varchar(500);not null" ` Age int `gorm:"type:int;DEFAULT:18" ` } func main() { // 參考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 獲取詳情 dsn := "luffyapi:Luffy123?@tcp(127.0.0.1:3306)/luffyapi?charset=utf8mb4&parseTime=True&loc=Local" db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) if err != nil { fmt.Println("連接數據庫出錯:", err) } db.AutoMigrate(&Students{}) user := Students{Username: "Jinzhu", Age: 18, Password: "123456"} result := db.First(&user) fmt.Println(result) db.Take(&user) //result := db.Create(&user) // 通過數據的指針來創建 //fmt.Println(result) }
https://www.tizi365.com/archives/15.html