
2024年在線市場平臺的11大最佳支付解決方案
sql.Open
方法開始連接數(shù)據(jù)庫,第一個參數(shù)為所要連接的數(shù)據(jù)庫類型。第二個參數(shù)為dsn,可以理解為連接數(shù)據(jù)庫的參數(shù)信息。
這里在連接以后,又對連接進行了三個設(shè)置。
conn.SetConnMaxLifetime
為設(shè)置連接的空閑時間,為什么要設(shè)置這個參數(shù)以及該設(shè)置多少是有講究的。
有的MySQL服務(wù)器為了性能考慮,會設(shè)置主動斷開空閑連接的,默認8個小時,但是一般的dba不會設(shè)置那么長,很有可能會設(shè)置10秒或者更短,所以這個參數(shù)要設(shè)置的更短,這個參數(shù)可以登錄MySQL 服務(wù)器執(zhí)行show global variables like '%timeout%';
來查看,有個wait_timeout
值,這里的值要設(shè)置比這個值更短。
conn.SetMaxOpenConns(10)
和conn.SetMaxOpenConns(10)
這兩個方法會初始化一個連接池,保證池子里會有足夠的連接,這個值要設(shè)置多少需要根據(jù)應(yīng)用的并發(fā)情況。
但是SetMaxIdleConns
的值不要小于SetMaxOpenConns
設(shè)置的值,否則會導(dǎo)致頻繁的創(chuàng)建連接。
官方的解釋為
db.SetMaxIdleConns() is recommended to be set same to db.SetMaxOpenConns(). When it is smaller than SetMaxOpenConns(), connections can be opened and closed much more frequently than you expect
這里還有個需要注意的是,在import 時,有個_ "github.com/go-sql-driver/mysql"
這行代碼不能缺,該代碼會執(zhí)行一下init方法,初始化一些變量,如果沒有這行的話,會由于一些變量未被初始化而panic.
一般情況下,我們會將數(shù)據(jù)庫連接對象放到一個全局的變量中,然后將不同的數(shù)據(jù)庫操作封裝到dao中。
在項目目錄下再創(chuàng)建一個global目錄,再創(chuàng)建一個global.go文件, 在該文件中定義一些需要全局使用的變量.
package global
import "database/sql"
var (
Mysql *sql.DB
)
之后在main.go中進行mysql變量的初始化
package main
import (
"github.com/gin-gonic/gin"
"yyxtest/db"
"yyxtest/global"
"yyxtest/handlers"
)
func main() {
r := gin.Default()
global.Mysql = db.InitDB()
userv1_h := handlers.UserV1{}
userv1 := r.Group("/user/v1")
{
userv1.GET("/check", userv1_h.CheckUsers)
}
r.Run(":8080")
}
global.Mysql = db.InitDB()
這行代碼為初始化全局的Mysql 對象, 之后我們創(chuàng)建一個dao文件夾,再創(chuàng)建一個userdao.go文件,這里封裝數(shù)據(jù)庫的查詢. 先寫一個查詢所有記錄的函數(shù)。
事先準備一個表,并插入幾條數(shù)據(jù)
id | name | age |
1 | 楊彥星 | 18 |
2 | 飯團兒 | 1 |
3 | aaa | 100 |
4 | bbb | 22 |
5 | ccc | 19 |
6 | 35 | |
7 | 46 |
在userdao.go中寫入以下代碼,
package dao
import "yyxtest/global"
type user struct {
ID int json:"id"
Name string json:"name"
Age int json:"age"
}
func GetAllUsers() []user {
rows, err :=global.Mysql.Query("select * from user_infos")
if err != nil{
return nil
}
var persons = make([]user, 0)
for rows.Next() {
var a user
err := rows.Scan(&a.ID, &a.Name, &a.Age)
if err != nil {
return nil
}
persons = append(persons, a)
}
return persons
}
GetAllUsers
函數(shù)執(zhí)行select * from user_infos
, 并且將該查詢結(jié)果返回[]user 的結(jié)構(gòu)體, 接下來再編寫路由處理類, userv1_h.CheckUsers
在handler 文件夾中再創(chuàng)建一個userv1.go
package handlers
import (
"github.com/gin-gonic/gin"
"yyxtest/dao"
)
type UserV1 struct {}
func (UserV1) CheckUsers(c *gin.Context) {
users := dao.GetAllUsers()
if users == nil{
c.JSON(200, gin.H{"error": 1, "msg": "查詢失敗"})
}
c.JSON(200, gin.H{"error":0, "msg":"查詢成功", "users": users})
}
運行服務(wù),如果沒有什么意外的話將可以正常的請求到數(shù)據(jù)
如果在進行數(shù)據(jù)庫的查詢時,沒有對用戶的輸入進校驗,而是完全的進行字符串拼接,將會導(dǎo)致SQL注入的問題發(fā)生,如以下的代碼
func GetUser(name string) (user, error) {
sqlstr := fmt.Sprintf("select * from user_infos where name
='%s'", name)
row := global.Mysql.QueryRow(sqlstr)
var u user
err := row.Scan(&u.ID, &u.Name, &u.Age)
if err != nil {
return user{}, err
}
return u, nil
}
sqlstr 直接進行字符串拼接將會導(dǎo)致注入問題。
正確的做法應(yīng)該是使用點位符
插入數(shù)據(jù)也比較簡單,使用Exec函數(shù) ,在userdao.go中寫入以下代碼
func InsertUser(name string, age int) error {
exec, err := global.Mysql.Exec("INSERT into user_infos(name, age) values (?,?)", name, age)
if err != nil {
return err
}
_, err = exec.LastInsertId()
if err != nil {
return err
}
return nil
}
在處理類中寫入以下代碼
func (UserV1) AddUser(c *gin.Context) {
name := c.Query("name")
age := c.Query("age")
age_i, err:=strconv.Atoi(age)
if err!=nil{
c.JSON(200, gin.H{"error": 1, "msg": "age 參數(shù)不正確"})
}else{
err = dao.InsertUser(name, age_i)
if err!= nil{
c.JSON(200, gin.H{"error": 2, "msg": err.Error()})
}else{
c.JSON(200, gin.H{"error": 1, "msg": "插入成功"})
}
}
}
MySQL的初步使用還是比較簡單的,只是在初始化的時候定義好相應(yīng)的對象,但是MySQL是個博大精深的數(shù)據(jù)庫,入門很簡單,但是想要深入還是需要很多的內(nèi)功修煉的,之后再深入一些事務(wù)相關(guān)的查詢。
文章轉(zhuǎn)自微信公眾號@序語程言
2024年在線市場平臺的11大最佳支付解決方案
完整指南:如何在應(yīng)用程序中集成和使用ChatGPT API
選擇AI API的指南:ChatGPT、Gemini或Claude,哪一個最適合你?
用ASP.NET Core 2.1 建立規(guī)范的 REST API — 緩存和并發(fā)
企業(yè)工商數(shù)據(jù)API用哪種?
2024年創(chuàng)建社交媒體帖子的最佳圖像工具API
2024年小型企業(yè)的7個最佳短信應(yīng)用API
用gin寫簡單的crud后端API接口
最新LangChain+GLM4開發(fā)AI應(yīng)用程序系列(一):快速入門篇