当前位置: 首页 > news >正文

go gin学习记录4

环境

环境:mac m1,go version 1.17.2, goland, mysql

除了原生sql,和orm操作之外,go还有一类包,只用于生成sql,典型的如sqlbuilder,今天就来研究一下它。

安装sqlbuilder

首先需要安装:

$ go get github.com/huandu/go-sqlbuilder
go: downloading github.com/huandu/go-sqlbuilder v1.19.0
go get: added github.com/huandu/go-sqlbuilder v1.19.0
go get: added github.com/huandu/xstrings v1.3.2

测试准备

为了实验,需要准备一个测试数据表,这里就按照第一节的user来复制一个worker表出来:

mysql> create table worker like user;
Query OK, 0 rows affected (0.02 sec)

接下来就到了创建controller和router group的节点了,第二节和第三节已经做了两遍,这里就直接贴代码了。
main.go:

	worker := r.Group("/worker"){workerCtrl := controller.WorkerController{}worker.POST("/createWorker", workerCtrl.CreateWorker)worker.GET("/getWorkerInfo", workerCtrl.GetWorkerInfo)worker.POST("/updateWorkerInfo", workerCtrl.UpdateWorkerInfo)}

controller/worker.go:

package controllerimport ("github.com/gin-gonic/gin"
)type WorkerController struct {ID    int    `json:"id"`Name  string `json:"name"`Birth string `json:"birth"`
}func (w *WorkerController) CreateWorker(c *gin.Context) {}func (w *WorkerController) GetWorkerInfo(c *gin.Context) {}func (w *WorkerController) UpdateWorkerInfo(c *gin.Context) {}

好的,前面这些重复的流程都搞定了。

sqlbuilder-插入操作

接下来我们开始完善代码,同样先从插入操作开始完善。

func (w *WorkerController) CreateWorker(c *gin.Context) {name := c.PostForm("name")birth := c.PostForm("birth")sb := sqlbuilder.NewInsertBuilder()sb.InsertInto("worker")sb.Cols("name", "birth")sb.Values(name, birth)sqlString, args := sb.Build()log.Println(sqlString, args)db, err := sql.Open("mysql", "root:@tcp(127.0.0.1:3306)/t_gin?charset=utf8&parseTime=true")if err != nil {log.Panic(err.Error())}_, err = db.Exec(sqlString, args)if err != nil {log.Panic(err.Error())}c.JSON(http.StatusOK, gin.H{"code": 0,"data": true,})
}

运行一下看看
在这里插入图片描述
出错了。
好吧,看看是什么问题。
查一下terminal,能够看到打印出来的sql语句,已经一条错误信息:

2023/02/20 16:53:36 INSERT INTO worker (name, birth) VALUES (?, ?) [tata 2008-1-1]
2023/02/20 16:53:36 sql: converting argument $1 type: unsupported type []interface {}, a slice of interface

定位一下错误,发现是exec操作给的参数有点问题,因为Exec操作接收的参数是这样的:

func (db *DB) Exec(query string, args ...interface{}) (Result, error) {return db.ExecContext(context.Background(), query, args...)
}

我们调整一下代码:

	_, err = db.Exec(sqlString, args...)

重新运行项目,这次是成功了
看一下数据库,数据正确插入了

mysql> select * from worker;
+----+------+----------+
| id | name | birth    |
+----+------+----------+
|  2 | tata | 2008-1-1 |
+----+------+----------+
1 row in set (0.00 sec)

sqlbuilder-查询操作

好的,接下来再完善查询操作。

func (w *WorkerController) GetWorkerInfo(c *gin.Context) {id := c.Query("id")sb := sqlbuilder.NewSelectBuilder()sb.From("worker")sb.Select("name,birth")sb.Where(sb.Equal("id", id))sqlString, args := sb.Build()log.Println(sqlString, args)db, err := sql.Open("mysql", "root:@tcp(127.0.0.1:3306)/t_gin?charset=utf8&parseTime=true")if err != nil {log.Panic(err.Error())}result := db.QueryRow(sqlString, args...)var worker Workererr = result.Scan(&worker.ID, &worker.Name, &worker.Birth)if err != nil {log.Panic(err.Error())}c.JSON(http.StatusOK, gin.H{"code": 0,"data": worker,})
}

运行看看
在这里插入图片描述
又出错了
看下终端的输出:

2023/02/20 17:13:44 SELECT name,birth FROM worker WHERE id = ? [2]
2023/02/20 17:13:44 sql: expected 2 destination arguments in Scan, not 3

错误指向scan操作,说是只需要两个,却给了3个
检查代码后发现,是在生成sql时,select只查了name、birth两个字段,scan的时候却给了id、name、birth3个。
我们调整一下代码,将scan中的id去掉:

	err = result.Scan(&worker.Name, &worker.Birth)

然后我们再运行:
在这里插入图片描述
好的,这次是成功的。
但是,有没有发现返回的数据是有问题的,id是0。
因为返回的是定义的struct,而查询时只查询了指定的字段,并没给id赋值,所以id字段用了一个默认值。
通过查询指定和结果绑定,就可以解决这个问题了。

sqlbuilder-更新操作

继续完善更新操作

func (w *WorkerController) UpdateWorkerInfo(c *gin.Context) {id := c.PostForm("id")name := c.PostForm("name")sb := sqlbuilder.NewUpdateBuilder()sb.Update("worker")sb.Where(sb.Equal("id", id))sb.SetMore(sb.Assign("name", name))sqlString, args := sb.Build()log.Println(sqlString, args)db, err := sql.Open("mysql", "root:@tcp(127.0.0.1:3306)/t_gin?charset=utf8&parseTime=true")if err != nil {log.Panic(err.Error())}_, err = db.Exec(sqlString, args...)if err != nil {log.Panic(err.Error())}c.JSON(http.StatusOK, gin.H{"code": 0,"data": true,})
}

运行一下看看
在这里插入图片描述
运行成功了,我们看看数据表中的数据:

mysql> select * from worker;
+----+-----------+----------+
| id | name      | birth    |
+----+-----------+----------+
|  2 | this name | 2008-1-1 |
+----+-----------+----------+
1 row in set (0.03 sec)

也没有问题,符合预期。

然后呢?

sqlbuilder作为原生sql和orm之间的地带,适合什么样子的场景呢?我暂时还没有想到。

sqlbuilder比原生的多了一些复合操作,但它的功能就是用来生成SQL语句,具体的执行还是需要原生的db操作去执行。

而相比于gorm,它又显得过于简陋。当然好处是更浅显一些。
需求当中怎么选择,看个人的倾向吧。

今天就到这。

http://www.lryc.cn/news/13786.html

相关文章:

  • 家政服务小程序实战开发教程015-填充用户信息
  • python+selenium使用webdriver启动chrome出现闪退现象解决
  • 新建idea项目
  • Django框架之类视图
  • win11/10+Azure kinect DK配置 VS2019/2017/2015的方法(简单,亲测可以)
  • 子查询的相关例题
  • vue2.0与vue3.0及vue与react区别
  • 【SQL】MySQL秘籍
  • vue-router 的基本用法
  • 图像显著性目标检测
  • 力扣-查找重复的电子邮箱
  • 如何选择正规可靠的ISO认证机构?
  • React源码解读之更新的创建
  • 【程序人生】从土木专员到网易测试工程师,薪资翻3倍,他经历了什么?
  • C++——C++11第二篇
  • 14.最长公共前缀
  • 【免费教程】 SWMM在城市水环境治理中的应用及案例分析
  • SortableJS/Sortable拖拽组件,使用详细(Sortablejs安装使用)
  • Heartbeat+Nginx实验
  • JavaEE|网络编程之套接字 TCP
  • Robot Framework自动化测试---元素定位
  • ASP.NET Core中的路由
  • VBA提高篇_26 Textbox多行_ListBox_ComboBox
  • python环境配置
  • 集算器连接外部库
  • 力扣刷题|216.组合总和 III、17.电话号码的字母组合
  • 机器学习笔记之谱聚类(一)k-Means聚类算法介绍
  • 云原生周刊 | 2023 年热门:云 IDE、Web Assembly 和 SBOM | 2023-02-20
  • python 打包EXE
  • CANopen概念总结、心得体会