GIN试玩:GORM增删改查分页

10 篇文章 0 订阅
10 篇文章 0 订阅

首先,将数据库表转换为结构体,在线转结构体

Model

// Model/user.go
type UserRole struct {
	Id int `gorm:"column:id" db:"id" json:"id" form:"id"`
	Keyword string `gorm:"column:keyword" db:"keyword" json:"keyword" form:"keyword"` //角色关键字
	Name string `gorm:"column:name" db:"name" json:"name" form:"name"` //角色名称
	Level int `gorm:"column:level" db:"level" json:"level" form:"level"` //角色等级
	CreateBy string `gorm:"column:create_by" db:"create_by" json:"createBy" form:"create_by"` //创建人
	CreateTime string `gorm:"column:create_time" db:"create_time" json:"createTime" form:"create_time"` //创建时间
	UpdateBy string `gorm:"column:update_by" db:"update_by" json:"updateBy" form:"update_by"` //更新人
	UpdateTime string `gorm:"column:update_time" db:"update_time" json:"updateTime" form:"update_time"` //更新时间
}

数据库dataTime格式转换为结构体为Time.time,处理起来极为麻烦,还要修改mysql的配置,建议手动修改为string

如果与前端交互的字段为驼峰格式,手动修改json

Service

// Service/user.go
type UserService struct {
}
// 相当于声明一个命名空间
var UserServer UserService
// 查询
func (t *UserService) RoleList(params string, pageNo int, pageSize int) ([]Model.UserRole, int) {
	var total int
	db := GetDb().Model(&Model.UserRole{}).Where(params).Count(&total).Limit(pageSize).Offset((pageNo - 1) * pageSize)
	var list []Model.UserRole
	db = db.Find(&list)
	if db.Error != nil {
		fmt.Println(db.Error)
	}
	return list, total
}
// 新增、编辑
func (t *UserService) RoleEdit(model Model.UserRole, isEdit bool) error {
	db := GetDb()
	if isEdit {
		db = db.Save(model)
	} else {
		// 如果id是自增的,务必带&
		db = db.Create(&model) 
	}
	if db.Error != nil {
		return db.Error
	}
	return nil
}
// 删除
func (t *UserService) RoleDel(ids []int) error {
	db := GetDb().Model(&Model.UserRole{})
	db = db.Delete(Model.UserRole{}, ids)
	if db.Error != nil {
		return db.Error
	}
	return nil
}

Controller

// Controller/user.go
type UserController struct {
}
var UserControl = &UserController{}

func (t *UserController) RoleList(c *gin.Context) {
	// 解析前端参数
	params, pageNo, pageSize := PackageRequestParams(c)
	res, total := Service.UserServer.RoleList(params, pageNo, pageSize)
	ResponseSuccessMap(c, map[string]interface{}{
		"records": res,
		"total":   total,
	})
}

func (t *UserController) RoleEdit(c *gin.Context) {
	data, err := ioutil.ReadAll(c.Request.Body)
	CheckError(err)
	var msg Model.UserRole
	json.Unmarshal(data, &msg)
	user, _ := GetCurUserinfo(c)
	// time.Time 与数据库与前端三者之间转换实在太麻烦,所以定义为string, updateTime为空时指定一个特定时间,前端显示时过滤掉
	if msg.Id == 0 {
		msg.CreateBy = user.Username
		msg.CreateTime = time.Now().Format("2006-01-02 15:04:05")
		msg.UpdateTime = "1010-10-10 00:00:00"
	} else {
		msg.UpdateBy = user.Username
		msg.UpdateTime = time.Now().Format("2006-01-02 15:04:05")
	}
	if err := Service.UserServer.RoleEdit(msg, msg.Id != 0); err == nil {
		ResponseSuccess(c, "success")
	} else {
		ResponseError(c, err.Error())
	}
}

func (t *UserController) RoleDel(c *gin.Context) {
	data, err := ioutil.ReadAll(c.Request.Body)
	CheckError(err)
	var msg struct {
		Ids []int
	}
	json.Unmarshal(data, &msg)
	if err := Service.UserServer.RoleDel(msg.Ids); err == nil {
		ResponseSuccess(c, "success")
	} else {
		ResponseError(c, err.Error())
	}
}

公用方法

// Controller/common.go
type RequestCondition struct {
	Column string
	Value  string
	Type   string
}
// 前端列表请求参数格式
type RequestListData struct {
	PageNo    int
	PageSize  int
	Condition []RequestCondition
}
func ResponseSuccess(c *gin.Context, data string) {
	c.JSON(http.StatusOK, gin.H{
		"code":    "200",
		"message": "success",
		"data":    data,
		"success": true,
	})
}
func ResponseSuccessMap(c *gin.Context, data map[string]interface{}) {
	c.JSON(http.StatusOK, gin.H{
		"code":    "200",
		"message": "success",
		"data":    data,
		"success": true,
	})
}
func ResponseError(c *gin.Context, data string) {
	c.JSON(http.StatusOK, gin.H{
		"code":    "500",
		"message": data,
		"data":    "",
		"success": false,
	})
}
func CheckError(e error) {
	if e != nil {
		fmt.Println(e.Error())
	}
}
// 将前端请求参数转换为 grom where语句
func PackageRequestParams(c *gin.Context) (string, int, int) {
	data, err := ioutil.ReadAll(c.Request.Body)
	CheckError(err)
	var req RequestListData
	json.Unmarshal(data, &req)
	var res []string
	for _, value := range req.Condition {
		var c string
		key := snakeString(value.Column)
		switch value.Type {
		case "eq":
			c = key + " = " + "'" + value.Value + "'"
			break
		case "like":
			c = key + " like " + "'%" + value.Value + "%'"
			break
		case "gt":
			c = key + " > " + value.Value
			break
		case "lt":
			c = key + " < " + value.Value
			break
		}
		res = append(res, c)
	}
	return strings.Join(res, " and "), req.PageNo, req.PageSize
}
// 驼峰转蛇形
func snakeString(s string) string {
	data := make([]byte, 0, len(s)*2)
	j := false
	num := len(s)
	for i := 0; i < num; i++ {
		d := s[i]
		// or通过ASCII码进行大小写的转化
		// 65-90(A-Z),97-122(a-z)
		//判断如果字母为大写的A-Z就在前面拼接一个_
		if i > 0 && d >= 'A' && d <= 'Z' && j {
			data = append(data, '_')
		}
		if d != '_' {
			j = true
		}
		data = append(data, d)
	}
	//ToLower把大写字母统一转小写
	return strings.ToLower(string(data[:]))
}

前端列表请求参数示例
在这里插入图片描述

困惑点

刚入门,不知如何写一个公用方法,只需要传入不同的struct则返回不同的结果,这样就避免了多次重复代码,研究中…

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值