json - 如何只编辑数据库中的某些字段而不是全部?
问题描述
我有一个应用程序,并且有一个用于编辑用户信息的端点。但是我发现了一个问题,如果在 json 中看到空白信息(假设用户只想编辑名称,而将其他字段留空),数据将在 DB 中编辑,空白的信息将覆盖是数据库的信息,即使用户不想编辑它们。
如何仅使到达 json 的字段在数据库中得到有效编辑?或者,还有更好的方法?
我很期待知道!
我的控制器
func EditUser(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
userID, err := strconv.ParseUint(params["userID"], 10, 64)
if err != nil {
returns.ERROR(w, http.StatusInternalServerError, err)
return
}
userIDInToken, err := auth.ExtractUserID(r)
if err != nil {
returns.ERROR(w, http.StatusInternalServerError, err)
return
}
if userIDInToken != userID {
returns.ERROR(w, http.StatusForbidden, errors.New("you can't update other user"))
return
}
bodyRequest, err := ioutil.ReadAll(r.Body)
if err != nil {
returns.ERROR(w, http.StatusBadRequest, err)
return
}
var user models.User
if err := json.Unmarshal(bodyRequest, &user); err != nil {
returns.ERROR(w, http.StatusUnprocessableEntity, err)
return
}
db, err := db.ConnectToDB()
if err != nil {
returns.ERROR(w, http.StatusInternalServerError, err)
return
}
defer db.Close()
repository := repositories.NewUsersRepository(db)
if err := repository.UpdateUserInfo(userID, user); err != nil {
returns.ERROR(w, http.StatusInternalServerError, err)
return
}
returns.JSON_RESPONSE(w, http.StatusOK, nil)
}
我的存储库(访问数据库)
func (repository Users) UpdateUserInfo(userID uint64, user models.User) error {
stmt, err := repository.db.Prepare(
"UPDATE user SET name = ?, cpf = ?, email = ?, password = ?, city = ?, state = ? WHERE id = ?")
if err != nil {
return err
}
defer stmt.Close()
if _, err := stmt.Exec(
user.Name,
user.CPF,
user.Email,
user.Password,
user.City,
user.State,
userID,
); err != nil {
return err
}
return nil
}
用户型号
type User struct {
ID uint64 `json:"id,omitempty"`
Name string `json:"name,omitempty"`
CPF string `json:"cpf,omitempty"`
Email string `json:"email,omitempty"`
Password string `json:"password,omitempty"`
City string `json:"city,omitempty"`
State string `json:"state,omitempty"`
}
解决方案
我将动态构造 UPDATE 语句以及需要编辑的字段切片,方法是在将字段添加到切片之前检查字段是否不为空。
像这样的东西:
func (repository Users) UpdateUserInfo(userID uint64, user User) error {
fields := make([]string, 0)
values := make([]string, 0)
if user.Name != "" {
values = append(values, user.Name)
fields = append(fields, "name = ?")
}
if user.CPF != "" {
values = append(values, user.CPF)
fields = append(fields, "cpf = ?")
}
if user.Email != "" {
values = append(values, user.Email)
fields = append(fields, "email = ?")
}
if user.Password != "" {
values = append(values, user.Password)
fields = append(fields, "password = ?")
}
if user.City != "" {
values = append(values, user.City)
fields = append(fields, "city = ?")
}
if user.State != "" {
values = append(values, user.State)
fields = append(fields, "state = ?")
}
if len(fields) != 0 {
return errors.New("no fields to update")
}
updateString := fmt.Sprintf("UPDATE user SET %s WHERE id = ?", strings.Join(fields, ","))
stmt, err := repository.db.Prepare(updateString)
if err != nil {
return err
}
defer stmt.Close()
if _, err := stmt.Exec(values...,userID); err != nil {
return err
}
return nil
}
对于更简洁的代码,我建议可能将“if 语句”/验证提取到单独的函数中。
推荐阅读
- tfs - Azure DevOps 中帐户和组织、集合之间的主要区别是什么?
- node.js - 根据用户角色显示菜单列表
- rstudio - 可以在 rstudio 中突出显示特定文本(如用户定义的单词)吗?
- php - Imagick 给出了错误的 gif 宽度和高度?
- android - 应用因违反 SMS 权限而从 google playstore 下架
- apache - 多个后端服务的 Apache 反向代理上的上下文路径
- c# - 从 windows 窗体调用 .NET core REST api 以发送包括 IFormFile 在内的数据
- python-3.x - 计算单个数据框中具有相同几何形状的多边形数量
- python - 在 GitPython 中迭代提交 b/w 2 个指定的提交
- mysql - Talend Open Studio 使用 MySQL 进行父子关系数据迁移