• Go语学习笔记 - gorm使用 - 表增删改查 Web框架Gin(八)


    目录

    新增修改接口

    查询所有未逻辑删除接口

    根据ID删除接口

    时间字段序列化问题处理

    接口验证

    小结


    学习笔记,写到哪是哪。

    接着上一篇文章:Go语学习笔记 - gorm使用 - 数据库配置、表新增 | Web框架Gin(七)_的博客-CSDN博客

    数据库初始化配置已经弄好了,上一篇文章中简单的写了一个demo接口。

    本篇文章接着上一篇,对表进行增删改查,同时对时间字段进行特殊处理。

    项目地址:github地址

    新增修改接口

    一般我们在实际项目中,会把新增接口和更新修改接口合并,也就是传递参数中带ID的话则为修改,不带ID的话为新增。

    按照项目结构的编写方式,在student_service下新增AddOrUpdateStudent方法。

    方法代码如下:

    //新增或者更新学生
    func (t StudentImpl) AddOrUpdateStudent(student *db_entity.Student) rsp.ResponseMsg {
    	log.Logger.Info("新增或者更新学生参数:", log.Any("Student", student))
    	_db := mysql.GetDB()
    	if student.Id != 0 {
    		_db.Model(&student).Updates(student)
    	} else {
    		_db.Create(&student)
    	}
    	return *rsp.SuccessMsg("操作成功")
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    注意:在接口测试中你会发现传递update_time时间字段解析错误,在下面的小结里面会讲到自定义事件结构体来解决json时间字段序列化问题。

    查询所有未逻辑删除接口

    在student_service下新增SelectAll方法,对del_flag为0的用户进行查询。

    方法代码如下:

    //查询所有学生
    func (t StudentImpl) SelectAll() rsp.ResponseMsg {
    	log.Logger.Info("查询所有学生")
    	_db := mysql.GetDB()
    	var _result []db_entity.Student
    	_db.Where("del_flag = ?", 0).Find(&_result)
    	return *rsp.SuccessMsg(_result)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    根据ID删除接口

    在student_service下新增根据ID删除数据接口。

    方法代码如下:

    //根据id删除学生
    func (t StudentImpl) DeleteById(id int32) rsp.ResponseMsg {
    	log.Logger.Info("根据id删除学生")
    	_db := mysql.GetDB()
    	_db.Delete(&db_entity.Student{}, id)
    	return *rsp.SuccessMsg("删除成功")
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    时间字段序列化问题处理

    由于json不能直接序列化time.Time类型,网上有多种解决方法,我这边主要采用自定义时间类型重写序列化方法的方法来解决。

    在constants目录下,创建common.go文件。

    common.go代码如下:

    package constants
    
    import (
    	"database/sql/driver"
    	"fmt"
    	"time"
    )
    
    type HTime struct {
    	time.Time
    }
    
    var (
    	formatTime = "2006-01-02 15:04:05"
    )
    
    func (t HTime) MarshalJSON() ([]byte, error) {
    	formatted := fmt.Sprintf(""%s"", t.Format(formatTime))
    	return []byte(formatted), nil
    }
    
    func (t *HTime) UnmarshalJSON(data []byte) (err error) {
    	now, err := time.ParseInLocation(`"`+formatTime+`"`, string(data), time.Local)
    	*t = HTime{Time: now}
    	return
    }
    
    func (t HTime) Value() (driver.Value, error) {
    	var zeroTime time.Time
    	if t.Time.UnixNano() == zeroTime.UnixNano() {
    		return nil, nil
    	}
    	return t.Time, nil
    }
    
    func (t *HTime) Scan(v interface{}) error {
    	value, ok := v.(time.Time)
    	if ok {
    		*t = HTime{Time: value}
    		return nil
    	}
    	return fmt.Errorf("can not convert %v to timestamp", v)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    注意:

    1、重新定义HTime结构体,对序列化方法进行调整。

    2、Student结构体中UpdateTime字段数据类型调整为HTime,调整后如下。

    type Student struct {
    	Id         int32           `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT;comment:'id'"`
    	Name       string          `json:"name" gorm:"column:name;type:varchar(255);comment:'名字'"`
    	Age        int64           `json:"age" gorm:"column:age;comment:'年龄'"`
    	Content    string          `json:"content" gorm:"column:content;type:varchar(255);comment:'描述'"`
    	UpdateTime constants.HTime `json:"update_time" time_format:"unix" gorm:"column:update_time"`
    	DelFlag    int64           `json:"del_flag" gorm:"column:del_flag;comment:'删除标识'"`
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    接口验证

    controller层增加接口代码,如下:

    //新增或者修改一个学生信息
    func (s StudentController) AddOrUpdateStudent(context *gin.Context) {
    	var addOrUpdateStudent db_entity.Student
    	log.Logger.Info("AddOrUpdateStudent接口")
    	if err := context.ShouldBindJSON(&addOrUpdateStudent); err != nil {
    		log.Logger.Panic("参数异常")
    	}
    
    	if _, err := json.Marshal(addOrUpdateStudent); err != nil {
    		log.Logger.Panic("参数解析异常")
    	}
    	_rsp := services.StudentServ.AddOrUpdateStudent(&addOrUpdateStudent)
    	context.JSON(http.StatusOK, _rsp)
    }
    
    //查询所有学生
    func (s StudentController) SelectAll(context *gin.Context) {
    	log.Logger.Info("SelectAll接口")
    	_rsp := services.StudentServ.SelectAll()
    	context.JSON(http.StatusOK, _rsp)
    }
    
    //根据id删除学生
    func (s StudentController) DeleteById(context *gin.Context) {
    	log.Logger.Info("DeleteById接口")
    	_id := context.Query("id")
    	_a, _ := strconv.ParseInt(_id, 10, 64)
    	_rsp := services.StudentServ.DeleteById(int32(_a))
    	context.JSON(http.StatusOK, _rsp)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    router增加路由路径,如下:

    func StudentRouter(r *gin.Engine) {
    	r.POST("/student/addOne", controllers.StudentCtrl.StudentAddOne)
    	r.POST("/student/addOrUpdateStudent", controllers.StudentCtrl.AddOrUpdateStudent)
    	r.GET("/student/selectAll", controllers.StudentCtrl.SelectAll)
    	r.DELETE("/student/deleteById", controllers.StudentCtrl.DeleteById)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    分别验证一下3个接口。

    新增修改接口

    查询接口

    删除接口

    小结

    最近说实话有点忙了,在忙也要抽时间学习啊。后面继续操作一些复杂的查询操作。

    参考链接:gorm time.Time 使用钩子函数解决反序列化问题_qq_26372385的博客-CSDN博客

    先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦

  • 相关阅读:
    python-----字典练习
    Docker Hub 公有镜像在国内拉取加速配置
    计算机组成原理_Cache的替换算法
    synchronized有几种用法?
    过早的给方法中 引用对象 设为 null 可被 GC提前回收吗?
    Apache DolphinScheduler如何完全设置东八区?
    String、StringBuffer、StringBuilder的区别
    element-ui 图片压缩上传
    编译原理期末复习
    数据结构——链表
  • 原文地址:https://blog.csdn.net/m0_67401746/article/details/126083416