如何在Golang Gin中编写正确的注册查询 解决创建用户报错问题
修复方案
核心错误点
- SQL预处理用法错误:使用
fmt.Sprintf拼接SQL语句,且给占位符?包裹了单引号,直接导致SQL语法错误。预处理的占位符不需要加引号,也不要手动拼接参数到SQL语句中,避免语法错误和SQL注入风险。 - 仅预编译SQL未执行:
db.Prepare()仅完成SQL预编译,没有调用Exec()传入参数执行语句,数据不会写入数据库。 - 错误处理不合理:遇到错误直接调用
log.Fatal()会终止整个服务,且仅打印自定义错误信息,没有输出原始报错,无法定位问题根因。 - 结构体字段权限问题:
User结构体中firstname、lastname、password为小写首字母的私有字段,序列化、ORM绑定时无法正常访问,后续扩展会出现异常。 - 主键插入逻辑问题:用户表ID通常为自增主键,不需要显式插入,传入重复ID会触发唯一索引冲突报错。
修正后代码
model/user.go
package model type User struct { ID int `json:"id"` Firstname string `json:"firstname"` Lastname string `json:"lastname"` Username string `json:"username"` Password string `json:"password"` Isadmin bool `json:"is_admin"` }
注册控制器代码
package controller import ( "LoginRegister/dto" "LoginRegister/repository" "github.com/gin-gonic/gin" "log" "net/http" ) type RegisterController struct { } func (lc *RegisterController) Register(c *gin.Context) { var registerRequest dto.RegisterRequest if err := c.ShouldBindJSON(®isterRequest); err != nil { c.JSON(http.StatusBadRequest, gin.H{ "message": "请求参数错误", }) return } db := repository.Database if db == nil { c.JSON(http.StatusInternalServerError, gin.H{ "message": "数据库连接异常", }) return } // 预编译SQL,占位符无需加引号 stmt, err := db.Prepare("INSERT INTO users(`firstname`,`lastname`,`Username`,`password`,`isadmin`) VALUES (?,?,?,?,?)") if err != nil { log.Printf("SQL预编译失败: %v", err) c.JSON(http.StatusInternalServerError, gin.H{ "message": "服务内部错误", }) return } defer stmt.Close() // 执行插入操作,传入对应参数,生产环境请先对密码做bcrypt加密 res, err := stmt.Exec(registerRequest.Firstname, registerRequest.Lastname, registerRequest.Username, registerRequest.Password, registerRequest.Isadmin) if err != nil { log.Printf("用户插入失败: %v", err) c.JSON(http.StatusInternalServerError, gin.H{ "message": "创建用户失败", }) return } userId, _ := res.LastInsertId() c.JSON(http.StatusOK, gin.H{ "message": "注册成功", "user_id": userId, }) }
注意事项
- 生产环境禁止明文存储用户密码,必须使用bcrypt等不可逆加密算法加密后再存入数据库
dto.RegisterRequest需要保证所有字段首字母大写,并添加对应的json标签,否则参数绑定会失败- 如果表ID不是自增主键,需要手动传入ID的话,在SQL语句中补充ID字段和对应占位符,执行时传入ID参数即可
内容的提问来源于stack exchange,提问作者Cebrayil
相关产品推荐
相关产品推荐

