php小編子墨在這裡為大家解答一個常見的問題:如果在不同模組中存取資料庫,該如何操作呢?在開發過程中,我們經常需要在不同的功能模組中存取資料庫,這涉及如何管理資料庫連接和執行資料庫操作的問題。為了解決這個問題,我們可以採用多種方式,例如使用全域變數、單例模式、依賴注入等。具體選擇哪種方式取決於專案的需求和開發團隊的習慣。接下來,我將對這些方式進行詳細介紹,希望能幫助大家。
我嘗試使用 jwt 進行 atuhorize,但遇到問題,當我檢查來自聲明的有價值電子郵件的電子郵件時,我收到錯誤 500。這個問題是因為資料庫尚未準備好。
這是程式碼
套餐路線
#package route import ( "go_fiber/controller" "go_fiber/middleware" "github.com/gofiber/fiber/v2" ) func routeinit(app *fiber.app, usercontroller controller.usercontroller) { app.get("/users", middleware.authmiddleware, usercontroller.findall) app.post("/login", usercontroller.login) }
打包應用程式
package app import ( "database/sql" "fmt" "go_fiber/helper" "os" "time" _ "github.com/go-sql-driver/mysql" "github.com/joho/godotenv" ) func newdb() *sql.db { var ( username = envvariable("db_username") password = envvariable("db_password") host = envvariable("db_host") port = envvariable("db_port") db_name = envvariable("db_name") ) dns := fmt.sprintf("%s:%s@tcp(%s:%s)/%s?parsetime=true", username, password, host, port, db_name) db, err := sql.open("mysql", dns) if err != nil { panic(err) } db.setmaxidleconns(10) db.setmaxopenconns(100) db.setconnmaxidletime(5 * time.minute) db.setconnmaxlifetime(60 * time.minute) return db }
包主
package main import ( "go_fiber/app" "go_fiber/controller" "go_fiber/exception" "go_fiber/repository" "go_fiber/route" "go_fiber/service" "github.com/go-playground/validator/v10" "github.com/gofiber/fiber/v2" ) func main(){ var db = app.newdb() app := fiber.new() app.use(func(c *fiber.ctx) error { defer func() { if err := recover(); err != nil { exception.errorhandler(c, err) } }() return c.next() }) validator := validator.new() userrepository := repository.newuserrepository() userservice := service.newuserservice(userrepository, db, validator) usercontroller := controller.newusercontroller(userservice) route.routeinit(app, usercontroller) app.listen(":3000") }
封裝中間件
#package middleware import ( "database/sql" "errors" "fmt" "go_fiber/exception" "log" "os" "time" "github.com/gofiber/fiber/v2" "github.com/golang-jwt/jwt/v4" ) func authmiddleware(c *fiber.ctx) error{ tokenstring := c.cookies("authorization") log.printf("(middleware) token : %v", tokenstring) if tokenstring == "" { panic(exception.newuserunauthorized(errors.new("user unauthorized").error())) } token, err := jwt.parse(tokenstring, func(token *jwt.token) (interface{}, error) { if _, ok := token.method.(*jwt.signingmethodhmac); !ok { return nil, fmt.errorf("unexpected signing method :%v", token.header["sub"]) } return []byte(os.getenv("secret")), nil }) log.printf("(middleware) token : %v", token) log.printf("(middleware) error : %v", err) if claims, ok := token.claims.(jwt.mapclaims); ok && token.valid { if float64(time.now().unix()) > claims["exp"].(float64) { panic(exception.newuserunauthorized(errors.new("user unauthorized").error())) } log.printf("(middleware) claims : %v", claims) log.printf("(middleware) ok : %v", ok) var db *sql.db tx, err := db.begin() log.printf("(middleware) tx : %v", tx) log.printf("(middleware) error : %v", err) query :=` select email from users where email = ? limit 1 ` log.printf("(middleware) query : %v", query) user, err := tx.querycontext(c.context(), query, claims["sub"]) log.printf("(middleware) user : %v", user) log.printf("(middleware) error : %v", err) if err != nil { panic(exception.newuserunauthorized(errors.new("user unauthorized").error())) } c.locals("user", user) c.next() }else { panic(exception.newuserunauthorized(errors.new("user unauthorized").error())) } return nil }
這部分是問題代碼
var db *sql.db tx, err := db.begin() log.printf("(middleware) tx : %v", tx) // no detect in terminal
這是日誌的輸出
2023/02/12 10:00:04 (middleware) token : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NzYxNzEzOTIsInN1YiI6IkphZmFyQGdtYWlsLmNvbSJ9.6nn_IaNACHfe7flFMOXfj1ygZS-U_yrnU_Gvjn8xCp8 2023/02/12 10:00:04 (middleware) token : &{eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NzYxNzEzOTIsInN1YiI6IkphZmFyQGdtYWlsLmNvbSJ9.6nn_IaNACHfe7flFMOXfj1ygZS-U_yrnU_Gvjn8xCp8 0xc0000a6780 map[alg:HS256 typ:JWT] map[exp:1.676171392e+09 sub:[email protected]] 6nn_IaNACHfe7flFMOXfj1ygZS-U_yrnU_Gvjn8xCp8 true} 2023/02/12 10:00:04 (middleware) error : <nil> 2023/02/12 10:00:04 (middleware) claims : map[exp:1.676171392e+09 sub:[email protected]] 2023/02/12 10:00:04 (middleware) ok : true
那麼,如果不同的套件如何解決存取資料庫的問題?
您應該透過路由註冊將資料庫處理程序向下傳遞到中間件。
更改您的 authmiddleware,以便它由採用 db *sql.db 作為參數的函數傳回:
func newauthmiddleware(db *sql.db) fiber.handler { return func(c *fiber.ctx) error { // the rest of your function is here and has access to db } }
然後您需要在 routeinit 函數中呼叫 newauthmiddleware
#func routeinit(app *fiber.app, usercontroller controller.usercontroller, db *sql.db) { app.get("/users", middleware.newauthmiddleware(db), usercontroller.findall) app.post("/login", usercontroller.login) }
然後在主函數中將資料庫傳遞給 routeinit()
func main() { // ... as before route.RouteInit(app, userController, db) }
以上是如果功能在不同模組中如何存取資料庫?的詳細內容。更多資訊請關注PHP中文網其他相關文章!