当前位置: 首页 > 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,它又显得过于简陋。当然好处是更浅显一些。
需求当中怎么选择,看个人的倾向吧。

今天就到这。

相关文章:

go gin学习记录4

环境 环境:mac m1,go version 1.17.2, goland, mysql 除了原生sql,和orm操作之外,go还有一类包,只用于生成sql,典型的如sqlbuilder,今天就来研究一下它。 安装sqlbuil…...

家政服务小程序实战开发教程015-填充用户信息

我们上一篇讲解了立即预约功能,存在的问题是,每次都需要用户填写联系信息。在我们前述篇章中已经介绍了用户注册的功能,在立即预约的时候我们需要把已经填写的用户信息提取出来,显示到表单对应的字段中。本篇我们就讲解一下如何提…...

python+selenium使用webdriver启动chrome出现闪退现象解决

这两天发现之前开发的爬虫程序出问题了:谷歌浏览器出现打开立即闪退的现象,代码未修改过,检查也没有任何问题! 查看chrome浏览器发现版本更新了 ↑(点击chrome浏览器右上角三个点,最下面帮助→Google Chr…...

新建idea项目

目录IDEA系列之创建各种项目 https://blog.csdn.net/LOVEQD123/article/details/105886077 idea 创建项目的三种方式 https://blog.csdn.net/weixin_50034122/article/details/118754521 创建空项目 https://blog.csdn.net/qq_44537956/article/details/123075134 创建 spri…...

Django框架之类视图

类视图 思考:一个视图,是否可以处理两种逻辑?比如get和post请求逻辑。 如何在一个视图中处理get和post请求 注册视图处理get和post请求 以函数的方式定义的视图称为函数视图,函数视图便于理解。但是遇到一个视图对应的路径提供…...

win11/10+Azure kinect DK配置 VS2019/2017/2015的方法(简单,亲测可以)

首先下载文件:文件的下载和安装方法参考我的博客(131条消息) WIN11/win10Azure Kinect DK详细驱动配置教程(亲测)_Vertira的博客-CSDN博客安装好VS2019,创建好控制台c工程。这些都很简单,不细说。配置:首先配置环境变量…...

子查询的相关例题

子查询的相关例题: 查询和Zlotkey相同部门的员工姓名和工资 SELECT e1.last_name,e1.first_name,e1.salary FROM employees e1 WHERE e1.department_id (SELECT e2.department_idFROM employees e2WHERE e2.last_nameZlotkey );查询工资比公司平均工资高的员工号…...

vue2.0与vue3.0及vue与react区别

vue2.0与3.0及vue与react区别vue2.0 与 vue3.0 区别1. 双向绑定原理2.Vue3支持碎片(Fragments)3.Composition API4.生命周期5.v-if和v-for的优先级6.typescript支持vue与 react区别共同点1.虚拟domdiff算法2.提供了响应式和组件化的视图组件。3.注意力集中保持在核心库&#xf…...

【SQL】MySQL秘籍

chihiro-notes 千寻简笔记 v0.1 内测版 📔 笔记介绍 大家好,千寻简笔记是一套全部开源的企业开发问题记录,毫无保留给个人及企业免费使用,我是作者星辰,笔记内容整理并发布,内容有误请指出,笔…...

vue-router 的基本用法

vue-router 的基本用法 1.什么是 vue-router vue-router 是 vue.js 官方给出的路由解决方案。它只能结合 vue 项目进行使用,能够轻松的管理 SPA 项目中组件的切换。 vue-router 的官方文档地址:https://router.vuejs.org/zh/ 2.vue-router 安装和配置的…...

图像显著性目标检测

一、概述 1、定义 图像显著性检测(Saliency Detection,SD), 指通过智能算法模拟人的视觉系统特点,预测人类的视觉凝视点和眼动,提取图像中的显著区域(即人类感兴趣的区域),可以广泛用于目标识别、图像编辑以及图像检索等领域&am…...

力扣-查找重复的电子邮箱

大家好,我是空空star,本篇带大家了解一道简单的力扣sql练习题。 文章目录前言一、题目:182. 查找重复的电子邮箱二、解题1.正确示范①提交SQL运行结果2.正确示范②提交SQL运行结果3.正确示范③提交SQL运行结果4.正确示范④提交SQL运行结果总结…...

如何选择正规可靠的ISO认证机构?

ISO认证其实早已融入我们生活中,因为日常生活很多产品都有认证标识,企业办理ISO体系就需要找第三方认证公司,市面上这种公司也有不少,但找到合适可靠、认真负责的还是不易,尤其是体系认证有年审,如何留住客…...

React源码解读之更新的创建

React 的鲜活生命起源于 ReactDOM.render ,这个过程会为它的一生储备好很多必需品,我们顺着这个线索,一探婴儿般 React 应用诞生之初的悦然。 更新创建的操作我们总结为以下两种场景 ReactDOM.rendersetStateforceUpdate ReactDom.render …...

【程序人生】从土木专员到网易测试工程师,薪资翻3倍,他经历了什么?

转行对于很多人来说,是一件艰难而又纠结的事情,或许缺乏勇气,或许缺乏魄力,或许内心深处不愿打破平衡。可对于我来说,转行是一件不可不为的事情,因为那意味着新的方向、新的希望。我是学工程管理的&#xf…...

C++——C++11第二篇

目录 可变参数模板 lambda表达式 lambda表达式语法 捕获列表说明 可变参数模板 可变参数:可以有0到n个参数,如之前学过的 Printf C11的新特性可变参数模板能够让您创建可以接受可变参数的函数模板和类模板 模板参数包 // Args是一个模板参数包&…...

14.最长公共前缀

编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 ""。示例 1:输入:strs ["flower","flow","flight"]输出:"fl"示例 2:输入&…...

【免费教程】 SWMM在城市水环境治理中的应用及案例分析

SWMMSWMM(storm water management model,暴雨洪水管理模型)是一个动态的降水-径流模拟模型,主要用于模拟城市某一单一降水事件或长期的水量和水质模拟。EPA(Environmental Protection Agency,环境保护署&am…...

SortableJS/Sortable拖拽组件,使用详细(Sortablejs安装使用)

简述 作为一名前端开发人员,在工作中难免会遇到拖拽功能,分享一个github上一个不错的拖拽js库,能满足我们在项目开发中的需要,支持Vue和React,下面是SortableJS的使用详细; 这个是sortableJS中文官方文档&…...

Heartbeat+Nginx实验

HeartbeatNginx实验 Heartbeat是什么? Heartbeat是 Linux-HA 工程的一个组件,自1999 年开始到现在,发布了众多版本,是目前开源 Linux-HA项 目成功的一个例子,在行业内得到了广泛的应用 构建规划: 两台后…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换

目录 关键点 技术实现1 技术实现2 摘要&#xff1a; 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式&#xff08;自动驾驶、人工驾驶、远程驾驶、主动安全&#xff09;&#xff0c;并通过实时消息推送更新车…...

React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构

React 实战项目&#xff1a;微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇&#xff01;在前 29 篇文章中&#xff0c;我们从 React 的基础概念逐步深入到高级技巧&#xff0c;涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...

Python常用模块:time、os、shutil与flask初探

一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...

【1】跨越技术栈鸿沟:字节跳动开源TRAE AI编程IDE的实战体验

2024年初&#xff0c;人工智能编程工具领域发生了一次静默的变革。当字节跳动宣布退出其TRAE项目&#xff08;一款融合大型语言模型能力的云端AI编程IDE&#xff09;时&#xff0c;技术社区曾短暂叹息。然而这一退场并非终点——通过开源社区的接力&#xff0c;TRAE在WayToAGI等…...

qt+vs Generated File下的moc_和ui_文件丢失导致 error LNK2001

qt 5.9.7 vs2013 qt add-in 2.3.2 起因是添加一个新的控件类&#xff0c;直接把源文件拖进VS的项目里&#xff0c;然后VS卡住十秒&#xff0c;然后编译就报一堆 error LNK2001 一看项目的Generated Files下的moc_和ui_文件丢失了一部分&#xff0c;导致编译的时候找不到了。因…...

在ubuntu等linux系统上申请https证书

使用 Certbot 自动申请 安装 Certbot Certbot 是 Let’s Encrypt 官方推荐的自动化工具&#xff0c;支持多种操作系统和服务器环境。 在 Ubuntu/Debian 上&#xff1a; sudo apt update sudo apt install certbot申请证书 纯手动方式&#xff08;不自动配置&#xff09;&…...