m0_61781411 2024-05-03 15:55 采纳率: 66.7%
浏览 4

Golang交互mysql遇到报错500

问题遇到的现象和发生背景

使用golang开发交互mysql数据库,然后调用方法报错500
看了好多教程都没找到准确修改的方法,qq看看

遇到的现象和发生背景,请写出第一个错误信息

runtime error: invalid memory address or nil pointer dereference

方法

package myfunc8

import (
    "database/sql"
    "github.com/gin-gonic/gin"
    "log"
    "strconv"
    "time"
)

type Course struct {
    Cid   int
    Cname string
    Tid   int
}

func TestDB(dsn string) (db *sql.DB) {
    db, err := sql.Open("mysql", dsn)
    if err != nil {
        return nil
    }
    db.SetConnMaxLifetime(time.Minute * 3)
    db.SetMaxOpenConns(20)
    db.SetMaxIdleConns(10)
    return db
}
func QueryRowsHandler(g *gin.Context) {
    cid, err := strconv.Atoi(g.Query("cid"))
    if err != nil {
        log.Println(err)
    }
    dsn := "root:root@/db"
    db := TestDB(dsn)
    courses := QueryRows(db, cid)
    g.JSON(200, courses)
}
func QueryRows(db *sql.DB, cid int) []Course {
    db.Begin()
    RowsObj, err := db.Query("select cid,tid,cname from course where cid>?", cid)
    if err != nil {
        log.Println(err)
    }
    var courses []Course
    for RowsObj.Next() {
        var course Course
        RowsObj.Scan(&course.Cid, &course.Cname, &course.Tid)
        courses = append(courses, course)
    }
    return courses
}


主函数


```go
package main

import (
    "github.com/gin-gonic/gin"
    "go_gin_exercise/part08/myfunc8"
)

func main() {
    g := gin.Default()
    g.GET("/queryrows", myfunc8.QueryRowsHandler)
    g.Run()
}


```

  • 写回答

4条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-05-03 15:55
    关注

    引自免费微信小程序:皆我百晓生

    根据你提供的信息,错误提示为 runtime error: invalid memory address or nil pointer dereference,这通常意味着你在尝试访问一个空指针的成员。在你的代码中,这个错误很可能出现在 QueryRowsHandler 函数中的这一行:

    courses := QueryRows(db, cid)
    

    这里的问题是,如果你在调用 TestDB 函数时发生了错误并返回了 nil,那么 db 就会是一个空指针。在这种情况下,如果你尝试使用这个空指针执行 SQL 查询(即在 QueryRows 函数中),就会触发上述错误。

    为了修复这个问题,你需要检查 TestDB 函数是否成功创建了一个有效的数据库连接。可以在 TestDB 函数中添加错误处理,确保返回的是非空值,并且在 QueryRowsHandler 中也进行适当的错误检查。以下是修改后的代码:

    // TestDB 函数增加错误检查
    func TestDB(dsn string) (*sql.DB, error) {
        db, err := sql.Open("mysql", dsn)
        if err != nil {
            return nil, err
        }
        db.SetConnMaxLifetime(time.Minute * 3)
        db.SetMaxOpenConns(20)
        db.SetMaxIdleConns(10)
        return db, nil
    }
    
    // 在 QueryRowsHandler 中检查 db 是否为空
    func QueryRowsHandler(g *gin.Context) {
        cid, err := strconv.Atoi(g.Query("cid"))
        if err != nil {
            log.Println(err)
            g.JSON(400, gin.H{"error": "Invalid CID"})
            return
        }
    
        dsn := "root:root@/db"
        db, err := TestDB(dsn)
        if err != nil {
            log.Println(err)
            g.JSON(500, gin.H{"error": "Failed to connect to database"})
            return
        }
    
        courses := QueryRows(db, cid)
        if len(courses) == 0 {
            g.JSON(204, gin.H{"message": "No courses found"})
            return
        }
        g.JSON(200, courses)
    }
    
    // QueryRows 函数保持不变
    func QueryRows(db *sql.DB, cid int) []Course {
        // ...
    }
    

    现在,如果 TestDB 返回 nil 或者发生其他错误,QueryRowsHandler 将会返回一个 JSON 响应,而不是继续执行并导致程序崩溃。这样应该可以解决你的问题。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 5月3日

悬赏问题

  • ¥15 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
  • ¥15 如何用Python爬取各高校教师公开的教育和工作经历
  • ¥15 TLE9879QXA40 电机驱动
  • ¥20 对于工程问题的非线性数学模型进行线性化
  • ¥15 Mirare PLUS 进行密钥认证?(详解)
  • ¥15 物体双站RCS和其组成阵列后的双站RCS关系验证
  • ¥20 想用ollama做一个自己的AI数据库
  • ¥15 关于qualoth编辑及缝合服装领子的问题解决方案探寻
  • ¥15 请问怎么才能复现这样的图呀