目录

1.使用框架介绍

1.1go-zero框架:

1.2.gorm框架:

1.3.glus框架

 2.使用

2.1go-zero结合gorm

2.2使用gplus框架

2.2.1创建

2.2.2查询

2.2.1根据id查询

2.2..2根据ids查询

2.2.3条件查询单个分类

2.2..4 条件查询列表

2.2.5查询总条数

2.2.6分页查询数据

2.2.7查询数据是否存在

2.2.8根据泛型返回数据

2.3更新

2.3.1根据id更新记录

2.3.2 选择字段更新

2.3.3 忽略字段更新

2.3.4 根据条件更新

2.4 删除

2.4.1 根据id删除

2.4.2 根据多个id删除

2.4.3 根据条件删除

3.总结


在日常工作中主要用的是go-zero框架,虽然go-zero框架提供了访问数据库的sqlc和sqlx包,提供了最基本的增删改查方法,但是没有mybatis-plus那种操作单表的方法,所以要不停写sql,例如:查询分页,逻辑删除,修改单个信息,批量删除.....等等,十分繁琐,还有大量重复代码,十分不利于维护,虽然后面用到了go-zero结合gorm框架,但是还是会有各种条件查询都需要开发手动来拼接字符串,如果项目比较大的话,就会看到漫天飞的SQL字段,维护起来非常麻烦。所以就想基于go的框架实现mybatis-plus框架那样的功能。

1.使用框架介绍

1.1go-zero框架:

go-zero 是有圈内大佬万俊峰开发的,七牛云技术副总裁。go-zero 是一个集成了各种工程实践的 web 和 rpc 框架。通过弹性设计保障了大并发服务端的稳定性,经受了充分的实战检验(千万日活)。

官方文档:框架概述 | go-zero Documentation

1.2.gorm框架:

上一篇文章已经详细介绍过了,如果不了解可以看看这个

gorm框架学习-CSDN博客

1.3.glus框架

Gorm-Plus是Gorm的增强工具,它在保持Gorm原有特性的基础上,为开发者提供了开箱即用的增强功能。通过简化开发流程、提高效率,它为开发者带来了无与伦比的开发体验。如果您渴望尝试一款让开发变得轻松而高效的工具,Gorm-Plus将是您不可错过的选择。

其实就是把Mybatis-plus的那套语法借鉴了一下。(好吧,就是抄他的)

Mybatis-plus对于单表操作提供了非常多的CRUD操作

用go1.18出的泛型也可以实现这些方法,本来我还准备自己琢磨写一套的,突然有一天在github上面看见有人已经写了,那我这里就直接拿来用了(好吧,就是懒)。

总结来说就是一句话:

他山之石,可以攻玉

项目地址:GitHub - acmestack/gorm-plus: Gorm-plus是基于Gorm的增强版,类似Mybatis-plus语法。Gorm-plus is based on an enhanced version of Gorm, similar to Mybatis-plus syntax.

 2.使用

2.1go-zero结合gorm

首先创建项目

注意,需要安装go-zero框架的工具 goctl和go的开发环境

在idea中创建go项目,创建godemo文件夹,然后创建godemo.api文件

执行命令

goctl api go -api mingcheng.api -dir .

生成的项目结构如下

导入所需要的依赖

go get github.com/acmestack/gorm-plus
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql

增加配置文件

需要注意的是 config包定义的变量要和配置文件一一对应

然后在svc下的servicecontext.go中创建数据库连接,相当于注册数据库连接对象。

然后在logic层编写业务代码

例如我们现在写一个根据名称查询数据的例子

我们可以看见数据已经被查出来了,但是问题就是:

但是还是会有各种条件查询都需要开发手动来拼接字符串,如果项目比较大的话,就会看到漫天飞的SQL字段,维护起来非常麻烦

 想要实现的是不用手动拼接条件。直接用泛型就好啦

2.2使用gplus框架

gplus是基于gorm框架做的一层封装,上手非常简单

2.2.1创建

普通创建

category := model.Category{Name: req.Name, ParentId: req.ParentId, Level: req.Level, CategoryType: req.CategoryType}
	//普通添加方法
	result := gplus.Insert(&category)
	fmt.Println(category.Id)
	fmt.Println(result.Error)
	fmt.Println(result.RowsAffected)

指定字段创建

//指定字段创建值
	result = gplus.Insert(&category, gplus.Select(model.CategoryColumn.Name, model.CategoryColumn.CategoryType))
	fmt.Println(category.Id)         // 打印插入数据的主键
	fmt.Println(result.Error)        // 打印 error
	fmt.Println(result.RowsAffected) // 打印插入记录的条数

批量创建

	//批量插入
	categoryList := make([]*model.Category, 0)
	res := &model.Category{
		Name:  "大大的",
		Level: 10,
	}
	res1 := &model.Category{
		Name:  "小小的",
		Level: 10,
	}
	categoryList = append(categoryList, res, res1)
	result := gplus.InsertBatchSize(categoryList, 1000)
	fmt.Println(result.Error)        // 打印 error
	fmt.Println(result.RowsAffected) // 打印插入记录的条数

2.2.2查询

2.2.1根据id查询

//对应数据库表
	var category model.Category
//1.根据id查询
	item, result := gplus.SelectById[model.Category](543)
	category = *item
	fmt.Println(item, result.RowsAffected)
	fmt.Println(category)

2.2..2根据ids查询

//2.根据ids查询
	var ids = []int{542, 543}
	categoryList, resultDb := gplus.SelectByIds[model.Category](ids)
	fmt.Println(resultDb.Error, resultDb.RowsAffected)
	for _, item := range categoryList {
		category = *item
		fmt.Println(category)
	
	}

2.2.3条件查询单个分类

//3.查询单条记录
	query, u := gplus.NewQuery[model.Category]()
	query.Eq(u.Name, "六楼")
	res, resultDb := gplus.SelectOne(query)
	fmt.Println(res, resultDb.Error, resultDb.RowsAffected)

如果遇到下面代码飘红的问题,检查编译器版本(泛型是新特性,旧版本的编译器不支持)

2.2..4 条件查询列表

//4.查询列表
	query, u := gplus.NewQuery[model.Category]()
	query.Gt(u.CategoryType, 1)
	list, resultDb := gplus.SelectList(query)
	fmt.Println(resultDb.RowsAffected)
	for _, item := range list {
		fmt.Println(category)
	}
	fmt.Println(colum.Name)

2.2.5查询总条数

	//5.条件查询记录数量
	query, u:= gplus.NewQuery[model.Category]()
	query.Gt(u.CategoryType, 1)
	count, resultDd := gplus.SelectCount(query)
	fmt.Println(count)
	fmt.Println(resultDd.Error, resultDd.RowsAffected)

2.2.6分页查询数据

//6.分页查询
	query, u = gplus.NewQuery[model.Category]()
	page := gplus.NewPage[model.Category](1, 10)
	query.Gt(u.CategoryType, 1)
	categoryList, resultDb := gplus.SelectPage(page, query)
	fmt.Println(resultDb.Error, resultDb.RowsAffected)
	fmt.Println(categoryList.Total)
	for _, item := range categoryList.Records {
		fmt.Println(item)
	}
	println(category.CategoryType)

2.2.7查询数据是否存在

//7.判断数据是否存在
	query, u:= gplus.NewQuery[model.Category]()
	query.Eq(u.Name, "八楼")
	exists, resultDb := gplus.Exists(query)
	fmt.Println(exists)
	fmt.Println(resultDb.Error)

2.2.8根据泛型返回数据

返回单条记录

	//8.根据泛型返回数据
	query, u := gplus.NewQuery[model.Category]()
	query.Eq(u.Name, "八楼")
	categoryVo, resultDb := gplus.SelectGeneric[model.Category, types.Category](query)
	fmt.Println(categoryVo)
	fmt.Println(resultDb.Error, resultDb.RowsAffected)
	fmt.Println(category.Name)
	return resp, nil

返回多条记录

query, u := gplus.NewQuery[model.Category]()
	query.Gt(u.CategoryType, 1)
	categoryListVo, resultDb := gplus.SelectGeneric[model.Category, []*types.Category](query)
	for _, item := range categoryListVo {
		// 解析字符串时间
		// 解析包含时区信息的时间字符串
		createTime, err := time.Parse(time.RFC3339, item.CreateTime)
		if err != nil {
			fmt.Println(err)
			continue
		}
		timeName := timex.Time2String(createTime)
		item.CreateTime = timeName

	}

分页返回多条数据

query, q := gplus.NewQuery[model.Category]()
	page := gplus.NewPage[types.Category](1, 10)
	query.Gt(q.CategoryType, 1)
	page, resultDb := gplus.SelectPageGeneric[model.Category, types.Category](page, query)
	for _, userVo := range page.Records {
		resp.List = append(resp.List, userVo)
	}
	if resultDb.Error != nil {
		fmt.Print(resultDb.Error)
		fmt.Print(resultDb.RowsAffected)
	}
	resp.Total = page.Total

2.3更新

2.3.1根据id更新记录

  u := User{ID: 1, Username: "张三", Password: "123456"}
  resultDb := gplus.UpdateById[User](&u)
  fmt.Println(resultDb.Error)
  fmt.Println(resultDb.RowsAffected)
  // UPDATE `users` SET `username`='张三',`password`='123456',`updated_at`='2023-06-03 16:54:37.677' WHERE `id` = 1

上面的方式,默认是不更新零值得,如果需要更新零值,可以使用UpdateZeroById

2.3.2 选择字段更新

  u := User{ID: 1, Username: "张三", Password: "123456"}
  resultDb := gplus.UpdateZeroById[User](&u)
  fmt.Println(resultDb.Error)
  fmt.Println(resultDb.RowsAffected)
  // UPDATE `users` SET `username`='张三',`password`='123456',`address`='',`age`=0,`phone`='',`score`=0,`dept`='',`created_at`='0000-00-00 00:00:00',`updated_at`='2023--03 16:56:01.117' WHERE `id` = 1

2.3.3 忽略字段更新

  u := User{ID: 1, Username: "张三", Age: 20, Password: "123456", Score: 18, Address: "北京", Dept: "开发"}
  model := gplus.GetModel[User]()
  resultDb := gplus.UpdateById[User](&u, gplus.Select(&model.Username, &model.Password))
  fmt.Println(resultDb.Error)
  fmt.Println(resultDb.RowsAffected)
  //  UPDATE `users` SET `username`='张三',`password`='123456',`updated_at`='2023-06-03 17:02:36.579' WHERE `id` = 1

2.3.4 根据条件更新

  q, u := gplus.NewQuery[User]()
  q.Eq(&u.ID, 1).Set(&u.Score, 60)
  resultDb := gplus.Update(q)
  fmt.Println(resultDb.Error)
  fmt.Println(resultDb.RowsAffected)
  // UPDATE `users` SET `score`=60,`updated_at`='2023-06-03 16:58:11.93' WHERE id = 1

2.4 删除

2.4.1 根据id删除

  resultDb := gplus.DeleteById[User](6)
  fmt.Println(resultDb.Error)
  fmt.Println(resultDb.RowsAffected)
  //  DELETE FROM `users` WHERE `id` = 6

2.4.2 根据多个id删除

  resultDb := gplus.DeleteByIds[User]([]int{7, 8, 9})
  fmt.Println(resultDb.Error)
  fmt.Println(resultDb.RowsAffected)
  //   DELETE FROM `users` WHERE `id` IN (7,8,9)

2.4.3 根据条件删除

  query, u := gplus.NewQuery[User]()
  query.Eq(&u.Username, "afumu")
  resultDb := gplus.Delete[User](query)
  fmt.Println(resultDb.Error)
  fmt.Println(resultDb.RowsAffected)
  // DELETE FROM `users` WHERE username = 'afumu'

3.总结

优点:

  1. 无侵入、增强而非改变:Gorm-Plus以无侵入的方式对 Gorm 进行增强,保持原有特性的同时提供更多功能,让您无需担心兼容性问题。
  2. 强大的 CRUD 操作和通用查询:Gorm-Plus内置了强大的 CRUD 操作功能,并提供了简便的通用查询功能,无需繁琐的配置即可轻松构建复杂条件查询。
  3. 支持指针字段形式查询:通过支持指针字段形式查询,Gorm-Plus让编写各类查询条件变得更加便捷,再也不用担心因为字段写错而出现错误。
  4. 内置泛型查询和灵活的返回类型封装:Gorm-Plus内置了泛型查询功能,让您能够灵活封装返回类型,轻松应对各种查询需求。
  5. 内置分页插件:Gorm-Plus还提供了内置的分页插件,让分页操作变得简单而高效,让您能够轻松处理大量数据,并实现更好的用户体验。

缺点:

1.无sql,出现问题排除错误有些麻烦。

2.无缓存,每次都直接请求到数据库(可以自己写一套)

3. 封装力度大,对新手不太友好

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐