大家都知道框架自带的开发工具可以生成 do 对象代码,该 do 对象主要用于查询、修改、写入等操作时对操作字段的自动 nil 过滤。

今天教给大家一个新的玩法,通过指针结合 do 对象快速实现灵活、便捷的修改操作 API 实现。

数据结构

以下是我们使用的用户表数据结构:

  1. CREATE TABLE `user`(
  2. `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户ID',
  3. `passport` varchar(32) NOT NULL COMMENT '账号',
  4. `password` varchar(32) NOT NULL COMMENT '密码',
  5. `nickname` varchar(32) NOT NULL COMMENT '昵称',
  6. `status` varchar(32) NOT NULL COMMENT '状态',
  7. `brief` varchar(512) NOT NULL COMMENT '备注信息',
  8. `create_at` datetime DEFAULT NULL COMMENT '创建时间',
  9. `update_at` datetime DEFAULT NULL COMMENT '修改时间',
  10. PRIMARY KEY (`id`),
  11. UNIQUE KEY `uniq_passport` (`passport`)
  12. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

其中的用户状态,我们使用了单独的类型定义,用以实现枚举值:

  1. type Status string
  2. const (
  3. StatusEnabled = "enabled"
  4. StatusDisabled = "disabled"
  5. )

通过 gf gen dao 命令,我们自动生成的 do 对象如下:

  1. type User struct {
  2. g.Meta `table:"uer" orm:"do:true"`
  3. Id interface{}
  4. Passport interface{}
  5. Password interface{}
  6. Nickname interface{}
  7. Status interface{}
  8. Brief interface{}
  9. CreatedAt interface{}
  10. UpdatedAt interface{}
  11. }

请求API定义

我们来实现一个用户信息修改的 API 接口,这是一个运维管理接口,可以通过用户账号名称来修改用户信息。该 API 的定义如下:

  1. type UpdateReq struct {
  2. g.Meta `path:"/user/{Id}" method:"post" summary:"修改用户信息"`
  3. Passport string `v:"required" dc:"用户账号"`
  4. Password *string `dc:"修改用户密码"`
  5. Nickname *string `dc:"修改用户昵称"`
  6. Status *Status `dc:"修改用户状态"`
  7. Brief *string `dc:"修改用户描述"`
  8. }

其中,用户的可修改信息为密码、昵称、状态和描述,可能同时修改一项或者多项。这里使用了 指针类型 的属性参数, 用于实现:当传递该参数时执行修改,不传递时不修改。

业务逻辑实现

为了简化实例,我们这里直接在控制器中将指针参数传递给 do 对象。我们知道当调用端没有传递该参数时,该参数为 nil,那么传递给 do 对象的字段时,仍然是 nil,这个时候执行数据库更新操作时, do 对象中的 nil 字段将会被自动过滤掉。

  1. func (c *Controller) Update(ctx context.Context, req *v1.UpdateReq) (res *v1.UpdateRes, err error) {
  2. _, err = dao.User.Ctx(ctx).Data(do.User{
  3. Password: req.Password,
  4. Nickname: req.Nickname,
  5. Status: req.Status,
  6. Brief: req.Brief,
  7. }).Where(do.User{
  8. Passport: req.Passport,
  9. }).Update()
  10. return
  11. }