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

Go使用sqlx操作MySQL完整指南

# Go使用sqlx操作MySQL完整指南## 1. 安装依赖```bash
go get github.com/go-sql-driver/mysql
go get github.com/jmoiron/sqlx

2. 数据库基础操作

package mainimport ("fmt"_ "github.com/go-sql-driver/mysql""github.com/jmoiron/sqlx"
)// 定义全局db对象
var db *sqlx.DB// 用户结构体
type User struct {ID       int    `db:"id"`Username string `db:"username"`Password string `db:"password"`Age      int    `db:"age"`
}// 初始化数据库连接
func initDB() (err error) {// 连接数据库dsn := "root:123456@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True"db, err = sqlx.Connect("mysql", dsn)if err != nil {return err}// 设置连接池参数db.SetMaxOpenConns(100)db.SetMaxIdleConns(10)return nil
}// 创建数据库
func createDatabase() error {_, err := db.Exec("CREATE DATABASE IF NOT EXISTS test DEFAULT CHARACTER SET utf8mb4")return err
}// 删除数据库
func dropDatabase() error {_, err := db.Exec("DROP DATABASE IF EXISTS test")return err
}// 创建表
func createTable() error {sql := `CREATE TABLE IF NOT EXISTS users(id INT PRIMARY KEY AUTO_INCREMENT,username VARCHAR(50) NOT NULL UNIQUE,password VARCHAR(50) NOT NULL,age INT)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;`_, err := db.Exec(sql)return err
}// 删除表
func dropTable() error {_, err := db.Exec("DROP TABLE IF EXISTS users")return err
}// 插入单条数据
func insertUser(user User) error {sql := "INSERT INTO users(username, password, age) VALUES (?, ?, ?)"_, err := db.Exec(sql, user.Username, user.Password, user.Age)return err
}// 批量插入数据
func batchInsertUsers(users []User) error {sql := "INSERT INTO users(username, password, age) VALUES (:username, :password, :age)"_, err := db.NamedExec(sql, users)return err
}// 查询单个用户
func getUserByID(id int) (User, error) {var user Usersql := "SELECT * FROM users WHERE id=?"err := db.Get(&user, sql, id)return user, err
}// 查询多个用户
func getUsers(age int) ([]User, error) {var users []Usersql := "SELECT * FROM users WHERE age > ?"err := db.Select(&users, sql, age)return users, err
}// 更新用户
func updateUser(user User) error {sql := "UPDATE users SET password=?, age=? WHERE username=?"_, err := db.Exec(sql, user.Password, user.Age, user.Username)return err
}// 删除用户
func deleteUser(id int) error {sql := "DELETE FROM users WHERE id=?"_, err := db.Exec(sql, id)return err
}func main() {// 初始化数据库连接if err := initDB(); err != nil {fmt.Printf("init db failed, err:%v\n", err)return}defer db.Close()// 创建数据库if err := createDatabase(); err != nil {fmt.Printf("create database failed, err:%v\n", err)return}// 创建表if err := createTable(); err != nil {fmt.Printf("create table failed, err:%v\n", err)return}// 插入单个用户user1 := User{Username: "张三",Password: "123456",Age:      20,}if err := insertUser(user1); err != nil {fmt.Printf("insert user failed, err:%v\n", err)return}// 批量插入用户users := []User{{Username: "李四", Password: "123456", Age: 21},{Username: "王五", Password: "123456", Age: 22},{Username: "赵六", Password: "123456", Age: 23},}if err := batchInsertUsers(users); err != nil {fmt.Printf("batch insert users failed, err:%v\n", err)return}// 查询单个用户user, err := getUserByID(1)if err != nil {fmt.Printf("get user failed, err:%v\n", err)return}fmt.Printf("user:%#v\n", user)// 查询多个用户userList, err := getUsers(20)if err != nil {fmt.Printf("get users failed, err:%v\n", err)return}fmt.Printf("users:%#v\n", userList)// 更新用户user1.Password = "654321"if err := updateUser(user1); err != nil {fmt.Printf("update user failed, err:%v\n", err)return}// 删除用户if err := deleteUser(1); err != nil {fmt.Printf("delete user failed, err:%v\n", err)return}// 删除表if err := dropTable(); err != nil {fmt.Printf("drop table failed, err:%v\n", err)return}// 删除数据库if err := dropDatabase(); err != nil {fmt.Printf("drop database failed, err:%v\n", err)return}
}

3. 事务操作示例

// 使用事务进行转账
func transfer(fromUsername, toUsername string, amount int) error {tx, err := db.Beginx() // 开启事务if err != nil {return err}// 在事务中执行多个SQL操作sql1 := "UPDATE users SET balance = balance - ? WHERE username = ?"sql2 := "UPDATE users SET balance = balance + ? WHERE username = ?"// 执行第一个SQLresult1, err := tx.Exec(sql1, amount, fromUsername)if err != nil {tx.Rollback() // 回滚事务return err}// 检查影响行数rows1, err := result1.RowsAffected()if err != nil {tx.Rollback()return err}if rows1 != 1 {tx.Rollback()return fmt.Errorf("转出账户不存在")}// 执行第二个SQLresult2, err := tx.Exec(sql2, amount, toUsername)if err != nil {tx.Rollback()return err}// 检查影响行数rows2, err := result2.RowsAffected()if err != nil {tx.Rollback()return err}if rows2 != 1 {tx.Rollback()return fmt.Errorf("转入账户不存在")}// 提交事务return tx.Commit()
}

4. 常用查询技巧

4.1 IN查询

func getUsersByIDs(ids []int) ([]User, error) {query, args, err := sqlx.In("SELECT * FROM users WHERE id IN (?)", ids)if err != nil {return nil, err}query = db.Rebind(query)var users []Usererr = db.Select(&users, query, args...)return users, err
}

4.2 分页查询

func getUsersByPage(page, pageSize int) ([]User, error) {offset := (page - 1) * pageSizesql := "SELECT * FROM users LIMIT ? OFFSET ?"var users []Usererr := db.Select(&users, sql, pageSize, offset)return users, err
}

4.3 模糊查询

func searchUsers(keyword string) ([]User, error) {sql := "SELECT * FROM users WHERE username LIKE ?"var users []Usererr := db.Select(&users, sql, "%"+keyword+"%")return users, err
}

5. 注意事项

  1. 始终记得关闭数据库连接
  2. 使用事务时要确保正确处理回滚和提交
  3. 使用预处理语句防止SQL注入
  4. 合理设置连接池参数
  5. 处理所有可能的错误
  6. 使用合适的字段类型和索引优化查询性能

6. 最佳实践

  1. 使用结构体标签映射数据库字段
  2. 统一错误处理
  3. 使用连接池
  4. 合理组织代码结构
  5. 编写单元测试
  6. 记录必要的日志
  7. 定期备份数据库

相关文章:

Go使用sqlx操作MySQL完整指南

# Go使用sqlx操作MySQL完整指南## 1. 安装依赖bash go get github.com/go-sql-driver/mysql go get github.com/jmoiron/sqlx2. 数据库基础操作 package mainimport ("fmt"_ "github.com/go-sql-driver/mysql""github.com/jmoiron/sqlx" )// 定…...

Python 爬取网页文字并保存为 txt 文件教程

引言 在网络数据获取的过程中,我们常常需要从网页中提取有用的文字信息。Python 提供了强大的库来帮助我们实现这一目标。本教程将以https://theory.gmw.cn/2023 - 08/31/content_36801268.htm为例,介绍如何使用requests库和BeautifulSoup库爬取网页文字…...

时间序列预测论文阅读和相关代码库

时间序列预测论文阅读和相关代码库列表 MLP-based的时间序列预测资料DLinearUnetTSFPDMLPLightTS 代码库以及论文库:Time-Series-LibraryUnetTSFLightTS MLP-based的时间序列预测资料 我会定期把我的所有时间序列预测论文有关的资料链接全部同步到这个文章中&#…...

Mamba安装环境和使用,anaconda环境打包

什么是mamba Mamba是一个极速版本的conda,它是conda的C重新实现,使用多线程并行处理来加速包和依赖项的下载。 Mamba旨在提高安装、更新和卸载Python包的速度,同时保持与conda相同的兼容性和命令行接口。 Mamba的核心部分使用C实现&#xff…...

SSH连接成功,但VSCode连接不成功

环境 在实验室PC上连接服务器234 解决方案:在VSCode中重新添加远程主机 删除旧的VSCode Server 在远程主机上,VSCode会安装一个‘vscode-server’服务来支持远程开发,有时旧的‘vscode-server’文件可能会导致问题,删除旧的&am…...

springboot结合AES和国密SM4进行接口加密

api接口加密 1.为什么需要api接口加密呢? 1.防止爬虫 2.防止数据被串改 3.确保数据安全 2.如何实现接口加密呢? 3.我们可以使用哪些加密算法来加密呢? AES 密码学中的高级加密标准(Advanced Encryption Standard,…...

iOS在项目中设置 Dev、Staging 和 Prod 三个不同的环境

在 Objective-C 项目中设置 Dev、Staging 和 Prod 三个不同的环境,并为每个环境使用不同的 Bundle ID,可以通过以下步骤实现: 步骤 1: 创建不同的 Build Configuration 打开项目: 启动 Xcode 并打开你的项目。 选择项目文件&…...

openeuler24.09 系统无需配置 docker 源即可安装 docker 和 docker-composer

准备工作 1、准备一台刚刚创建的 openeuler24.09 lxc 虚拟机 2、使用 dnf 更新到最新,安装常用 工具 dnf update -y dnf install vim net-tools wget3、设置 ssh 由于ssh 与通常网上教程大同小异,在此我们就略过。 从下图我们可以看到 openeuler24.09 已经远程连接上。 …...

Flask入门:打造简易投票系统

目录 准备工作 创建项目结构 编写HTML模板 编写Flask应用 代码解读 进一步优化 结语 Flask,这个轻量级的Python Web框架,因其简洁和易用性,成为很多开发者入门Web开发的首选。今天,我们就用Flask来做一个简单的投票系统,让你快速上手Web开发,同时理解Flask的核心概…...

日常思考笔记

技术管理, 团队管理,人才培养,梯队建设 项目管理,项目全生命周期,项目进度 考核规范, AQS 是CountDownLatch,ReentrantLock,Semaphore,ReentrantReadWriteLock的基础 vo…...

【JAVA】后台管理系统密码复杂度和修改密码处理

一、后台管理系统密码要求 后台管理系统密码要求 口令有效期:90天 口令长度8位及8位以上 口令复杂度要求,至少包含以下四类字符中的三类字符: 英文大写字母(A 到 Z)、英文小写字母(a 到 z)、10个基本数字(0 到 9)、特殊字符(例如 !、$、#、%、、^、&a…...

微服务SpringCloud链路追踪之Micrometer+Zipkin

视频教程: https://www.bilibili.com/video/BV12LBFYjEvR 效果演示 当我们发送一个请求给 Gateway 的时候,由 Micrometer trace 进行链路追踪和数据收集,由 Zipkin 进行数据展示。可以清楚的看到微服务的调用过程,以及每个微服务…...

Quartz(2-Trigger)

相关文章链接 定时任务工具类(Cron Util)SpringBoot TaskQuartz(1-Job)Quartz(2-Trigger) Trigger 方法 优先级(priority) 如果你的 trigger 很多(或者 Quartz 线程…...

【微信小程序开发 - 3】:项目组成介绍

文章目录 项目组成介绍项目的基本组成结构小程序页面的组成部分JSON配置文件的作用app.json文件project.config.json文件sitemap.json文件页面的 .json 配置文件新建小程序页面修改项目首页 XWML模板XWML 和 HTML 的区别 WXSS样式WXSS 和 CSS 的区别 .js文件 项目组成介绍 项目…...

Leetcode 三角形最小路径和

算法思想与代码详解 这段代码采用的是**动态规划(Dynamic Programming)**的思想,用来解决“120. 三角形最小路径和”问题。动态规划通过将问题分解成更小的子问题,并通过保存子问题的解来避免重复计算,从而提高效率。…...

DataOps驱动数据集成创新:Apache DolphinScheduler SeaTunnel on Amazon Web Services

引言 在数字化转型的浪潮中,数据已成为企业最宝贵的资产之一。DataOps作为一种文化、流程和实践的集合,旨在提高数据管道的质量和效率,从而加速数据从源头到消费的过程。白鲸开源科技,作为DataOps领域的领先开源原生公司&#xf…...

Android Studio的笔记--BusyBox相关

BusyBox 相关 BusyBoxandroid上安装busybox和使用示例一、下载二、移动三、安装和设置环境变量四、使用 busybox源码下载和查看 BusyBox BUSYBOX BUSYBOX链接https://busybox.net/ 点击链接后如图 点击左边菜单栏的Get BusyBix中的Download Source 跳转到busybox 的下载源码…...

MySQL 存储过程与函数:增强数据库功能

一、MySQL 存储过程与函数概述 (一)存储过程的定义与特点 存储过程是一组预编译的 SQL 语句集合,它们被存储在数据库中,可根据需要被重复调用。例如,在一个电商系统中,经常需要查询某个时间段内的订单数据…...

网络安全(3)_安全套接字层SSL

4. 安全套接字层 4.1 安全套接字层(SSL)和传输层安全(TLS) (1)SSL/TLS提供的安全服务 ①SSL服务器鉴别,允许用户证实服务器的身份。支持SSL的客户端通过验证来自服务器的证书,来鉴别…...

Git 快速入门

Git 是什么? Git 是一个分布式版本控制系统四大区域: 工作区:项目文件的当前状态,即本地目录。暂存区:保存将要提交的文件快照,是一个中间层,使用git add将文件添加到暂存区。本地仓库&#xf…...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词

Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...

OPENCV形态学基础之二腐蚀

一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

视觉slam十四讲实践部分记录——ch2、ch3

ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行

项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...