golang-mysql、sqlx

news/2024/12/22 14:10:23/

1.导包

go get -u github.com/go-sql-driver/mysql
import _ "github.com/go-sql-driver/mysql"

_ 表示只执行包中init函数,mysql包会在init函数中注册自己。

2.连接数据库

利用基本库database/sql连接数据库

	dsn := "root:123456@tcp(127.0.0.1:3306)/test_db"db, err := sql.Open("mysql", dsn)db.SetMaxIdleConns(10) //设立连接池的最大连接数if err != nil {panic(err)}defer db.Close()

3.CRUD操作

常用函数:

func (db *DB) Query(query string, args …any) (*Rows, error)
func (db *DB) QueryRow(query string, args …any) *Row //查询单行
func (db *DB) Exec(query string, args …any) (Result, error)

Query和Exec的主要区别是Query(查询)能够知道返回的结果集,而Exec(执行)只能知道最后插入的ID和影响的行数。

查询

	rows, err := db.Query("select * from test_db.user_table")for rows.Next() {var id, age intvar name stringerr := rows.Scan(&id, &name, &age)if err != nil {panic(err)}fmt.Println(id, name, age)}

查询单行:

	var id, age intvar name string_ = db.QueryRow("select * from test_db.user_table").Scan(&id, &name, &age)println(id, name, age)

插入

	result, err := db.Exec("insert into test_db.user_table values (?,?,?)", 4, "gi", 19)if err != nil {panic(err)}id, _ := result.LastInsertId()println("lastInsetId:", id)

更新,删除与插入类似,不多叙述。

事务

func Transaction(db *sql.DB) {//事务开启tx, err := db.Begin()if err != nil {tx.Rollback()log.Println(err)return}_, err = tx.Exec("update online_info set Status=? where User_id=?", "online", 1)if err != nil {tx.Rollback()log.Println(err)return}//提交事务err = tx.Commit()if err != nil {tx.Rollback()log.Println(err)return}
}

sqlx库

sqlx是sql的超集,能够兼容sql库的所有方法,包括db.Exec\Query\Queryrow等等。

sqlx特性

db.Get():查询一行

在查询的时候将结果通过反射赋值给结构体。
注意:需要传入结构体实例的地址,结构体字段要大写!

	db, err := sqlx.Open("mysql", dsn)if err != nil {panic(err)}var a account  err= db.Get(&a,"select * from online_info where User_id=?", 1)

db.Select():查询多行结果

dest需要为slice类型的指针,

	var a []account = make([]account, 0)err = db.Select(&a, "select * from online_info where User_id=?", 1)if err != nil {panic(err)}fmt.Println(a)

namedQuery():将args参数绑定在sql中的:arg字段

rows, err := db.NamedQuery("select * from online_info where User_id=:id", map[string]interface{}{"id": 1
})

namedExec():与namedQuery作用相同,用于Exec()

StructScan():Scan增强版,直接将结果中的值赋给结构体变量。

连接池

源码分析:https://zhuanlan.zhihu.com/p/430993402

总结

只用 sqlx.Open() 函数创建连接池,此时只是初始化了连接池,并没有连接数据库,连接都是惰性的,只有调用 sqlx.DB 的方法时,此时才真正用到了连接,连接池才会去创建连接,连接池很重要,它直接影响着你的程序行为。

连接池的工作原理也非常简单,当调用 sqlx.DB 的方法时,会首先去向连接池请求要一个数据库连接,如果连接池有空闲的连接,则返回给方法中使用,否则连接池将创建一个新的连接给到方法中使用;一旦将数据库连接给到了方法中,连接就属于方法了。方法执行完毕后,要不把连接所属权还给连接池,要不传递给下一个需要数据库连接的方法中,最后都使用完将连接释放回到连接池中

请求数据库连接的方法有几个,执行完毕处理连接的方式也不同:

  1. DB.Ping() 使用完毕后会马上把连接返回给连接池 DB.Exec() 使用完毕后会马上把连接返回给连接池,但是它返回的

  2. Result 对象还保留着连接的引用,当后面的代码需要处理结果集的时候,连接将会被重新启用 DB.Query() 调用完毕后将连接传递给

  3. sql.Rows 类型,当后者迭代完毕或者显示的调用 Close() 方法后,连接将会被释放到连接池 DB.QueryRow()

  4. 调用完毕后将连接传递给 sql.Row 类型,当 Scan() 方法调用完成后,连接将会被释放到连接池 DB.Begin()调用完毕后将连接传递给 sql.Tx 类型对象,当 Commit() 或 Rollback() 方法调用后释放连接

每个连接都是惰性的,如果验证 sqlx.Open() 调用之后,sqlx.DB 类型对象可用呢?通过 DB.Ping() 方法来初始化

连接池配置

DB.SetMaxIdleConns(n int) 设置连接池中的保持连接的最大连接数。默认也是0,表示连接池不会保持数据库连接的状态:即当连接释放回到连接池的时候,连接将会被关闭。这会导致连接再连接池中频繁的关闭和创建,我们可以设置一个合理的值。

DB.SetMaxOpenConns(n int) 设置打开数据库的最大连接数。包含正在使用的连接和连接池的连接。如果你的方法调用 需要用到一个连接,并且连接池已经没有了连接或者连接数达到了最大连接数。此时的方法调用将会被 block,直到有可用的连接才会返回。设置这个值可以避免并发太高导致连接 mysql 出现 too many connections 的错误。该函数的默认设置是0,表示无限制

DB.SetConnMaxLifetime(d time.Duration) 设置连接可以被使用的最长有效时间,如果过期,连接将被拒绝

参考文章:https://www.cnblogs.com/kaichenkai/p/11140555.html


http://www.ppmy.cn/news/77746.html

相关文章

深度学习进阶篇-预训练模型[1]:预训练分词Subword、ELMo、Transformer模型原理;结构;技巧以及应用详解

【深度学习入门到进阶】必看系列,含激活函数、优化策略、损失函数、模型调优、归一化算法、卷积模型、序列模型、预训练模型、对抗神经网络等 专栏详细介绍:【深度学习入门到进阶】必看系列,含激活函数、优化策略、损失函数、模型调优、归一化…

114. 二叉树展开为链表

114. 二叉树展开为链表 描述 给你二叉树的根结点 root ,请你将它展开为一个单链表: 展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。展开后的单链表应该与二叉树 先序遍…

【vue3】需要了解哪些【未完结】

这里写目录标题 一.vue3入门1. vue3带来了什么2. vue3工程的创建1. 使用vue-cli创建2. 使用vite创建与webpack的区别 二、常用Composition API1. setup(函数和语法糖)2. ref 和reactive3. vue3的响应式原理1. Vue2 的响应式原理2.vue3的的响应式原理 4.computed5.watch6. watch…

C++由于错误使用下标运算符引发的未定义错误

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、下标运算符是什么?二、复现步骤1.写一个简单的类层次2.原因解析2.解决方法 总结 前言 本节讲一个由于下标使用错误引发的未定义错误&#xff0…

Android java层hook------xposed框架的使用

xposed曾经是android平台上最好的java层hook和调试工具,由于已经不再更新,当前支持的android系统版本比较老旧,目前只能支持到android6.0,故已经逐渐落伍,目前android上最广泛使用的hook工具是frida,这是另…

抖音账号矩阵系统源码/技术开发搭建私有化部署开源

抖音SEO矩阵系统是基于抖音平台的搜索引擎优化技术的一种系统,其主要作用是通过一系列的技术手段,提高抖音视频的曝光和排名,使其获得更多的流量和粉丝。在本文中,我们将介绍抖音SEO矩阵系统的开发技术,包括系统设计、…

小米手机系列的演进:从小米1到小米13

1. 小米1(2011年):小米1是小米公司的首款旗舰手机,以超低的售价提供出色的硬件配置和流畅的用户体验。它打破了传统手机市场的价格壁垒,受到广大用户的欢迎。 2. 小米2(2012年):小米…

算法训练-二分查找

这里写目录标题 34. 在排序数组中查找元素的第一个和最后一个位置162. 寻找峰值153. 寻找旋转排序数组中的最小值33. 搜索旋转排序数组 34. 在排序数组中查找元素的第一个和最后一个位置 题目链接 vector<int> searchRange(vector<int>& nums, int target) {i…