go语言对gorm不固定条件查询封装

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了go语言对gorm不固定条件查询封装相关的知识,希望对你有一定的参考价值。

参考技术A 在写sql语句时,where的条件主要是 key=1 and key2=2 或者 key=1 or key2=2 这种形式[还有 and与or 混合]。
认真分析会发现条件有 4部分 组成-- 字段名、操作符、查询值、与前一个条件的关系[and,or] ,这样就很容易实现了。下面就是一个说明,为了简化,其中会默认省略一些特征。

启动项目

访问测试地址:
http://127.0.0.1:8100/api/v1/user/test

带分页的地址: http://127.0.0.1:8100/api/v1/user/list

go-micro微服务Mysql配置

一 gorm介绍

Go语言中的database/sql包提供了保证SQL或类SQL数据库的泛用接口,并不提供具体的数据库驱动。使用database/sql包时必须注入(至少)一个数据库驱动。

我们常用的数据库基本上都有完整的第三方实现。例如:MySQL驱动

二 gorm安装

1.1 下载依赖

go get -u github.com/go-sql-driver/mysql

1.2 使用MySQL驱动

func Open(driverName, dataSourceName string) (*DB, error)

三 CURD操作

  • 下面介绍一下gorm的简单用法

1. 查询

为了方便查询,我们事先定义好一个结构体来存储user表的数据。

type user struct 
	id   int
	age  int
	name string

1.1 单行查询

单行查询db.QueryRow()执行一次查询,并期望返回最多一行结果(即Row)。QueryRow总是返回非nil的值,直到返回值的Scan方法被调用时,才会返回被延迟的错误。

func (db *DB) QueryRow(query string, args ...interface) *Row

具体示例代码:

// 查询单条数据示例
func queryRowDemo() 
	sqlStr := "select id, name, age from user where id=?"
	var u user
	// 确保QueryRow之后调用Scan方法,否则持有的数据库链接不会被释放
	err := db.QueryRow(sqlStr, 1).Scan(&u.id, &u.name, &u.age)
	if err != nil 
		fmt.Printf("scan failed, err:%v\\n", err)
		return
	
	fmt.Printf("id:%d name:%s age:%d\\n", u.id, u.name, u.age)

1.2 多行查询

多行查询db.Query()执行一次查询,返回多行结果(即Rows),一般用于执行select命令。参数args表示query中的占位参数。

func (db *DB) Query(query string, args ...interface) (*Rows, error)

具体示例代码:

// 查询多条数据示例
func queryMultiRowDemo() 
	sqlStr := "select id, name, age from user where id > ?"
	rows, err := db.Query(sqlStr, 0)
	if err != nil 
		fmt.Printf("query failed, err:%v\\n", err)
		return
	
	// 关闭rows释放持有的数据库链接
	defer rows.Close()

	// 循环读取结果集中的数据
	for rows.Next() 
		var u user
		err := rows.Scan(&u.id, &u.name, &u.age)
		if err != nil 
			fmt.Printf("scan failed, err:%v\\n", err)
			return
		
		fmt.Printf("id:%d name:%s age:%d\\n", u.id, u.name, u.age)
	

2. 插入数据

插入、更新和删除操作都使用Exec方法。

func (db *DB) Exec(query string, args ...interface) (Result, error)

Exec执行一次命令(包括查询、删除、更新、插入等),返回的Result是对已执行的SQL命令的总结。参数args表示query中的占位参数。

具体插入数据示例代码如下:

// 插入数据
func insertRowDemo() 
	sqlStr := "insert into user(name, age) values (?,?)"
	ret, err := db.Exec(sqlStr, "王五", 38)
	if err != nil 
		fmt.Printf("insert failed, err:%v\\n", err)
		return
	
	theID, err := ret.LastInsertId() // 新插入数据的id
	if err != nil 
		fmt.Printf("get lastinsert ID failed, err:%v\\n", err)
		return
	
	fmt.Printf("insert success, the id is %d.\\n", theID)

3. 更新数据

具体更新数据示例代码如下:

// 更新数据
func updateRowDemo() 
	sqlStr := "update user set age=? where id = ?"
	ret, err := db.Exec(sqlStr, 39, 3)
	if err != nil 
		fmt.Printf("update failed, err:%v\\n", err)
		return
	
	n, err := ret.RowsAffected() // 操作影响的行数
	if err != nil 
		fmt.Printf("get RowsAffected failed, err:%v\\n", err)
		return
	
	fmt.Printf("update success, affected rows:%d\\n", n)

4. 删除数据

具体删除数据的示例代码如下:

// 删除数据
func deleteRowDemo() 
	sqlStr := "delete from user where id = ?"
	ret, err := db.Exec(sqlStr, 3)
	if err != nil 
		fmt.Printf("delete failed, err:%v\\n", err)
		return
	
	n, err := ret.RowsAffected() // 操作影响的行数
	if err != nil 
		fmt.Printf("get RowsAffected failed, err:%v\\n", err)
		return
	
	fmt.Printf("delete success, affected rows:%d\\n", n)

四 初始化连接

  • 在mysql目录下新建mysql.go文件

  • 写入以下代码:

package mysql

import (
   "github.com/jinzhu/gorm"
)

// MysqlInit 初始化数据库
func MysqlInit(user string,pwd string,database string)(*gorm.DB,error)
   //连接数据库
   db, err := gorm.Open("mysql", user+":"+pwd+"@/"+database+"?charset=utf8&parseTime=True&loc=Local")
   if err != nil 
      return db,err
   
   //禁止复表
   db.SingularTable(true)
   //初始化表,只使用第一次
   //err = repository.NewUserRepository(db).InitTable()
   //if err != nil 
   // logger.Error(err)
   //
   return db,nil

五 使用

在main.go文件中编写代码 初始化数据库:

db, err := mysql.MysqlInit(micro.ConsulInfo.Mysql.User, micro.ConsulInfo.Mysql.Pwd, micro.ConsulInfo.Mysql.Database)
if err != nil 
   logger.Error(err)
   return

defer db.Close()

六 最后

  • 至此,go-micro微服务Mysql配置开发工作就正式完成。

  • 接下来就开始正式的Redis配置编写了,希望大家关注博主和关注专栏,第一时间获取最新内容,每篇博客都干货满满。

欢迎大家加入 夏沫の梦的学习交流群 进行学习交流经验,点击

以上是关于go语言对gorm不固定条件查询封装的主要内容,如果未能解决你的问题,请参考以下文章

Gorm 预加载及实现联表条件查询仿WhereHas

Gorm 高级查询

Go语言学习之旅--gorm

Go语言学习之旅--gorm

Go语言学习之旅--gorm

Gorm框架学习---CRUD接口之查询