Go语言短链接服务:长/短URL无法存入MySQL数据库求助
短链接服务无法写入MySQL数据库的问题修复
核心问题与修复点
你的代码存在几个关键问题导致数据无法写入数据库,逐一修复如下:
1. 全局DB变量被局部覆盖
main函数里重新声明了局部变量db,导致全局的var db *sql.DB始终为nil,addLink中调用数据库方法时会直接报错。
修复:
直接赋值给全局变量,不要重新声明:
var db *sql.DB // 全局变量 func main(){ var err error // 去掉var,直接给全局db赋值 db, err = sql.Open("mysql", dsn()) if err != nil { fmt.Println(err.Error()) return } // 添加Ping验证数据库连接是否真正建立 if err := db.Ping(); err != nil { fmt.Println("数据库连接失败:", err.Error()) return } fmt.Printf("已连接到MySQL服务器\n%s\n", dsn()) defer db.Close() // 其余代码不变... }
2. 数据库代码永远不会执行
addLink中在返回响应后写了return,后续的数据库操作代码完全不会运行,这是最核心的问题。
修复:
调整代码顺序,先执行数据库写入,再返回响应:
3. 插入参数顺序错误+错误的存储值
你要存储的是长URL和短URL标识,但代码里传的是genString(短标识)和linkString(HTML标签),完全不符合预期。
修复:
传入正确的长URL和短URL值,同时修正SQL语句的规范写法:
4. 错误的连接关闭时机
addLink里的defer db.Close()会在每次请求后关闭数据库连接,导致后续请求无法使用数据库,main函数里已经有全局的连接关闭逻辑,这里不需要重复。
修正后的addLink函数
func addLink(w http.ResponseWriter, r *http.Request) { log.Println("Add Link") key, ok := r.URL.Query()["ik"] if !ok || len(key) == 0 { w.WriteHeader(http.StatusBadRequest) fmt.Fprintf(w, "Failed to add link") return } longUrl := key[0] if !validLink(longUrl) { w.WriteHeader(http.StatusBadRequest) fmt.Fprintf(w, "Could not create shortlink need absolute path link.") return } // 检查长链接是否已存在(修正之前的逻辑错误) if _, exists := linkList[longUrl]; exists { w.WriteHeader(http.StatusConflict) fmt.Fprintf(w, "Already have this link") return } genString := randomString(5) shortUrl := fmt.Sprintf("hpe/%s", genString) linkList[genString] = longUrl // 执行数据库插入 result, err := db.Exec("INSERT INTO Url (LongUrl, ShortUrl) VALUES (?, ?);", longUrl, shortUrl) if err != nil { fmt.Printf("数据库插入错误: %v\n", err) w.WriteHeader(http.StatusInternalServerError) fmt.Fprintf(w, "Failed to save link to database") return } // 可选:获取插入ID if _, err := result.LastInsertId(); err != nil { fmt.Printf("获取插入ID失败: %v\n", err) } // 返回响应 w.Header().Set("Content-Type", "text/html") w.WriteHeader(http.StatusAccepted) linkString := fmt.Sprintf("<a href=\"%s\">%s</a>", shortUrl, shortUrl) fmt.Fprintf(w, "Added shortlink\n") fmt.Fprintf(w, linkString) }
额外建议
- 可以给
genString添加唯一性检查,避免生成重复的短标识 - 如果担心数据库写入延迟影响响应速度,可以将数据库操作放入goroutine,但要注意错误处理
内容的提问来源于stack exchange,提问作者expert.free
相关产品推荐
相关产品推荐

