
2024年在線市場(chǎng)平臺(tái)的11大最佳支付解決方案
sql.Open
方法開(kāi)始連接數(shù)據(jù)庫(kù),第一個(gè)參數(shù)為所要連接的數(shù)據(jù)庫(kù)類型。第二個(gè)參數(shù)為dsn,可以理解為連接數(shù)據(jù)庫(kù)的參數(shù)信息。
這里在連接以后,又對(duì)連接進(jìn)行了三個(gè)設(shè)置。
conn.SetConnMaxLifetime
為設(shè)置連接的空閑時(shí)間,為什么要設(shè)置這個(gè)參數(shù)以及該設(shè)置多少是有講究的。
有的MySQL服務(wù)器為了性能考慮,會(huì)設(shè)置主動(dòng)斷開(kāi)空閑連接的,默認(rèn)8個(gè)小時(shí),但是一般的dba不會(huì)設(shè)置那么長(zhǎng),很有可能會(huì)設(shè)置10秒或者更短,所以這個(gè)參數(shù)要設(shè)置的更短,這個(gè)參數(shù)可以登錄MySQL 服務(wù)器執(zhí)行show global variables like '%timeout%';
來(lái)查看,有個(gè)wait_timeout
值,這里的值要設(shè)置比這個(gè)值更短。
conn.SetMaxOpenConns(10)
和conn.SetMaxOpenConns(10)
這兩個(gè)方法會(huì)初始化一個(gè)連接池,保證池子里會(huì)有足夠的連接,這個(gè)值要設(shè)置多少需要根據(jù)應(yīng)用的并發(fā)情況。
但是SetMaxIdleConns
的值不要小于SetMaxOpenConns
設(shè)置的值,否則會(huì)導(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
這里還有個(gè)需要注意的是,在import 時(shí),有個(gè)_ "github.com/go-sql-driver/mysql"
這行代碼不能缺,該代碼會(huì)執(zhí)行一下init方法,初始化一些變量,如果沒(méi)有這行的話,會(huì)由于一些變量未被初始化而panic.
一般情況下,我們會(huì)將數(shù)據(jù)庫(kù)連接對(duì)象放到一個(gè)全局的變量中,然后將不同的數(shù)據(jù)庫(kù)操作封裝到dao中。
在項(xiàng)目目錄下再創(chuàng)建一個(gè)global目錄,再創(chuàng)建一個(gè)global.go文件, 在該文件中定義一些需要全局使用的變量.
package global
import "database/sql"
var (
Mysql *sql.DB
)
之后在main.go中進(jìn)行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 對(duì)象, 之后我們創(chuàng)建一個(gè)dao文件夾,再創(chuàng)建一個(gè)userdao.go文件,這里封裝數(shù)據(jù)庫(kù)的查詢. 先寫(xiě)一個(gè)查詢所有記錄的函數(shù)。
事先準(zhǔn)備一個(gè)表,并插入幾條數(shù)據(jù)
id | name | age |
1 | 楊彥星 | 18 |
2 | 飯團(tuán)兒 | 1 |
3 | aaa | 100 |
4 | bbb | 22 |
5 | ccc | 19 |
6 | 35 | |
7 | 46 |
在userdao.go中寫(xiě)入以下代碼,
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)體, 接下來(lái)再編寫(xiě)路由處理類, userv1_h.CheckUsers
在handler 文件夾中再創(chuàng)建一個(gè)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})
}
運(yùn)行服務(wù),如果沒(méi)有什么意外的話將可以正常的請(qǐng)求到數(shù)據(jù)
如果在進(jìn)行數(shù)據(jù)庫(kù)的查詢時(shí),沒(méi)有對(duì)用戶的輸入進(jìn)校驗(yàn),而是完全的進(jìn)行字符串拼接,將會(huì)導(dǎo)致SQL注入的問(wèn)題發(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 直接進(jìn)行字符串拼接將會(huì)導(dǎo)致注入問(wèn)題。
正確的做法應(yīng)該是使用點(diǎn)位符
插入數(shù)據(jù)也比較簡(jiǎn)單,使用Exec函數(shù) ,在userdao.go中寫(xiě)入以下代碼
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
}
在處理類中寫(xiě)入以下代碼
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的初步使用還是比較簡(jiǎn)單的,只是在初始化的時(shí)候定義好相應(yīng)的對(duì)象,但是MySQL是個(gè)博大精深的數(shù)據(jù)庫(kù),入門(mén)很簡(jiǎn)單,但是想要深入還是需要很多的內(nèi)功修煉的,之后再深入一些事務(wù)相關(guān)的查詢。
文章轉(zhuǎn)自微信公眾號(hào)@序語(yǔ)程言
2024年在線市場(chǎng)平臺(tái)的11大最佳支付解決方案
完整指南:如何在應(yīng)用程序中集成和使用ChatGPT API
選擇AI API的指南:ChatGPT、Gemini或Claude,哪一個(gè)最適合你?
用ASP.NET Core 2.1 建立規(guī)范的 REST API — 緩存和并發(fā)
企業(yè)工商數(shù)據(jù)API用哪種?
2024年創(chuàng)建社交媒體帖子的最佳圖像工具API
2024年小型企業(yè)的7個(gè)最佳短信應(yīng)用API
用gin寫(xiě)簡(jiǎn)單的crud后端API接口
最新LangChain+GLM4開(kāi)發(fā)AI應(yīng)用程序系列(一):快速入門(mén)篇
對(duì)比大模型API的內(nèi)容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉(zhuǎn)化潛力
一鍵對(duì)比試用API 限時(shí)免費(fèi)