Heim >Backend-Entwicklung >Golang >Wie greife ich auf die Datenbank zu, wenn sich die Funktionen in verschiedenen Modulen befinden?

Wie greife ich auf die Datenbank zu, wenn sich die Funktionen in verschiedenen Modulen befinden?

PHPz
PHPznach vorne
2024-02-10 21:06:10866Durchsuche

Wie greife ich auf die Datenbank zu, wenn sich die Funktionen in verschiedenen Modulen befinden?

PHP-Editor Zimo ist hier, um eine häufig gestellte Frage zu beantworten: Wie sollten Sie vorgehen, wenn Sie in verschiedenen Modulen auf die Datenbank zugreifen? Während des Entwicklungsprozesses müssen wir häufig in verschiedenen Funktionsmodulen auf die Datenbank zugreifen. Dazu gehört die Verwaltung von Datenbankverbindungen und die Durchführung von Datenbankoperationen. Um dieses Problem zu lösen, können wir verschiedene Methoden verwenden, z. B. die Verwendung globaler Variablen, den Singleton-Modus, die Abhängigkeitsinjektion usw. Welche konkrete Methode gewählt wird, hängt von den Anforderungen des Projekts und den Gewohnheiten des Entwicklungsteams ab. Als nächstes werde ich diese Methoden im Detail vorstellen und hoffe, allen zu helfen.

Frageninhalt

Ich versuche, mit jwt zu atuhorisieren, aber ich habe ein Problem. Wenn ich die E-Mails der E-Mail mit dem beanspruchten Wert überprüfe, erhalte ich die Fehlermeldung 500. Das Problem liegt daran, dass die Datenbank noch nicht bereit ist.

Das ist der Code

Pauschalroute

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)
}

Verpackungsanwendungen

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
}

Packmaster

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")
}

Verpackungs-Middleware

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
}

Dieser Teil ist der Problemcode

var db *sql.db
tx, err := db.begin()   
log.printf("(middleware) tx : %v", tx) // no detect in terminal

Dies ist die Ausgabe des Protokolls

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&#160;protected]]
2023/02/12 10:00:04 (middleware) ok : true

Wie lässt sich also das Problem des Datenbankzugriffs lösen, wenn unterschiedliche Pakete verwendet werden?

Workaround

Sie sollten den Datenbankhandler über die Routenregistrierung an die Middleware übergeben.

Ändern Sie Ihre Authmiddleware so, dass sie von einer Funktion zurückgegeben wird, die db *sql.db als Argument verwendet:

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
    }
}

Dann müssen Sie newauthmiddleware in der Routeinit-Funktion aufrufen

func routeinit(app *fiber.app, usercontroller controller.usercontroller, db *sql.db) {
    app.get("/users", middleware.newauthmiddleware(db), usercontroller.findall)
    app.post("/login", usercontroller.login)
}

Dann übergeben Sie die Datenbank an routeinit() in der Hauptfunktion

func main() {
    // ... as before

    route.RouteInit(app, userController, db)
}

Das obige ist der detaillierte Inhalt vonWie greife ich auf die Datenbank zu, wenn sich die Funktionen in verschiedenen Modulen befinden?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen