首页 > 数据库 >Go 语言之 SQLX 高级操作 sqlx.In

Go 语言之 SQLX 高级操作 sqlx.In

时间:2023-06-14 18:00:11浏览次数:55  
标签:SQLX sqlx name err fmt db user Go

Go 语言之 SQLX 高级操作 sqlx.In

sqlx.In 介绍

sqlx is a package for Go which provides a set of extensions on top of the excellent built-in database/sql package.

Illustrated guide to SQLX:http://jmoiron.github.io/sqlx/

sqlx:https://github.com/jmoiron/sqlx

"In" Queries

Because database/sql does not inspect your query and it passes your arguments directly to the driver, it makes dealing with queries with IN clauses difficult:

SELECT * FROM users WHERE level IN (?);

When this gets prepared as a statement on the backend, the bindvar ? will only correspond to a single argument, but what is often desired is for that to be a variable number of arguments depending on the length of some slice, eg:

var levels = []int{4, 6, 7}rows, err := db.Query("SELECT * FROM users WHERE level IN (?);", levels)

This pattern is possible by first processing the query with sqlx.In:

var levels = []int{4, 6, 7}query, args, err := sqlx.In("SELECT * FROM users WHERE level IN (?);", levels) // sqlx.In returns queries with the `?` bindvar, we can rebind it for our backendquery = db.Rebind(query)rows, err := db.Query(query, args...)

What sqlx.In does is expand any bindvars in the query passed to it that correspond to a slice in the arguments to the length of that slice, and then append those slice elements to a new arglist. It does this with the ? bindvar only; you can use db.Rebind to get a query suitable for your backend.

普通批量插入数据,不使用 sqlx.In

package main

import (
	"database/sql"
	"fmt"
	"strings"
	"time"

	_ "github.com/go-sql-driver/mysql" // 匿名导入 自动执行 init()
)

var db *sql.DB

func initMySQL() (err error) {
	//DSN (Data Source Name)
	dsn := "root:12345678@tcp(127.0.0.1:3306)/sql_test"
	// 注意:要初始化全局的 db 对象,不要新声明一个 db 变量
	db, err = sql.Open("mysql", dsn) // 只对格式进行校验,并不会真正连接数据库
	if err != nil {
		return err
	}

	// Ping 验证与数据库的连接是否仍处于活动状态,并在必要时建立连接。
	err = db.Ping()
	if err != nil {
		fmt.Printf("connect to db failed, err: %v\n", err)
		return err
	}
	// 数值需要根据业务具体情况来确定
	db.SetConnMaxLifetime(time.Second * 10) // 设置可以重用连接的最长时间
	db.SetConnMaxIdleTime(time.Second * 5)  // 设置连接可能处于空闲状态的最长时间
	db.SetMaxOpenConns(200)                 // 设置与数据库的最大打开连接数
	db.SetMaxIdleConns(10)                  //  设置空闲连接池中的最大连接数
	return nil
}

type User struct {
	Name string `db:"name"`
	Age  int    `db:"age"`
}

// BatchInsertUsers 批量插入数据
func BatchInsertUsers(users []*User) error {
	valueStrings := make([]string, 0, len(users))     // 占位符 slice
	valueArgs := make([]interface{}, 0, len(users)*2) // 插入值 slice

	for _, u := range users {
		valueStrings = append(valueStrings, "(?, ?)")
		valueArgs = append(valueArgs, u.Name, u.Age) // 占位符与插入值 一一对应
	}
	// 拼接完整的SQL语句
	// Sprintf根据格式说明符进行格式化,并返回结果字符串。
	// Join将其第一个参数的元素连接起来以创建单个字符串。分隔字符串sep放置在结果字符串的元素之间。
	stmt := fmt.Sprintf("INSERT INTO user (name, age) VALUES %s", strings.Join(valueStrings, ","))
	// Exec执行查询而不返回任何行。参数用于查询中的任何占位符参数。
	result, err := db.Exec(stmt, valueArgs...)
	if err != nil {
		fmt.Printf("Error inserting user into database: %v \n", err)
		return err
	}
	var rows_affected int64
	rows_affected, err = result.RowsAffected() // 返回受更新、插入或删除影响的行数。并非每个数据库或数据库驱动程序都支持此功能。
	if err != nil {
		fmt.Printf("返回受更新、插入或删除影响的行数 failed, err: %v\n", err)
		return err
	}
	fmt.Println("受更新、插入或删除影响的行数: ", rows_affected)
	return nil
}

func main() {
	if err := initMySQL(); err != nil {
		fmt.Printf("connect to db failed, err: %v\n", err)
	}
	// 检查完错误之后执行,确保 db 不为 nil
	// Close() 用来释放数据库连接相关的资源
	// Close 将关闭数据库并阻止启动新查询。关闭,然后等待服务器上已开始处理的所有查询完成。
	defer db.Close()

	fmt.Println("connect to database success")
	// db.xx() 去使用数据库操作...

	// 批量插入数据
	users := []*User{
		{Name: "刘备", Age: 25},
		{Name: "关羽", Age: 30},
		{Name: "张飞", Age: 28},
	}
	err := BatchInsertUsers(users)
	if err != nil {
		fmt.Printf("Failed to batch insert users: %v", err)
	}
}

运行

Code/go/mysql_demo via 

标签:SQLX,sqlx,name,err,fmt,db,user,Go
From: https://www.cnblogs.com/QiaoPengjun/p/17481004.html

相关文章

  • django中设置字段动态默认时间的四种方式
    1.create_time_one=models.DateTimeField('创建时间',default=datetime.now())2.update_time_one=models.DateTimeField('更新时间',default=datetime.now)3.create_time_tow=models.DateTimeField('创建时间',auto_now_add=True)4.update_ti......
  • 用Leangoo领歌敏捷工具做迭代管理sprint
    ​什么是Sprint Backlog? Sprint Backlog是Scrum的主要工件之一。在Scrum中,团队按照迭代的方式工作,每个迭代称为一个Sprint。在Sprint开始之前,PO会准备好产品Backlog,准备好的产品Backlog应该是经过梳理、估算和优先级排列的。在Sprint开始时,第一件事情是Sprint计划会议,在Spri......
  • 使用Leangoo领歌敏捷项目管理工具自动生成燃尽图
    ​在上一篇,我为大家介绍了如何使用Leangoo领歌敏捷工具管理SprintBacklog_哆啦B梦_的博客-CSDN博客,今天我们一起来看看Leangoo领歌敏捷工具是如何自动生成Scrum燃尽图的什么是Scrum燃尽图?燃尽图是在项目完成之前,对需要完成的工作的一种可视化表示。能形象地展示当前迭代中的剩......
  • CSGO服务器租用首选杭州BGP高防103.219.30.x
    Hello,everyone今天我不打算讲游戏攻略了,我了解到很多想要自己搭建服务器的小伙伴在服务器这里遇到颈瓶了,所以我来给大家分享一下搭建CSGO社区服所需的服务器配置,希望可以帮助到你们首先选择合适的服务器配置,第一个需要考虑的就是游戏玩家地区分布情况,我很多玩CSGO的朋友都来自五湖......
  • go实现高并发高可用分布式系统:设计类似kafka的高并发海量数据存储机制2
    上一节我们完成了数据的存储和索引,本节我们看如何写入数据和进行查询。我们将创建一个Segment对象,它一方面接收发送来的请求,也就是Record数据结构,然后将数据写入到store和index,基本架构如下:在前面章节中,我们使用代码定义了Record的数据结构,现在我们需要使用protobuf来重新定义它,一......
  • GO实现高可用高并发分布式系统:gRPC实现客户端与服务端的一对一通讯
    分布式系统的特点是不同的功能模块会以独立服务器程序的方式运行在不同主机上。当服务A想请求位于另一台机器的服务B完成特定请求时,就必须将要处理的数据提交给B。这个过程就涉及到一系列问题,首先A需要把数据进行序列化然后通过网络连接发送给B,B接收到数据后需要进行反序列化得到数......
  • go实现高并发高可用分布式系统:设计类似kafka的高并发海量数据存储机制1
    上一节我们实现了日志微服务,它以http服务器的模式运行,客户端通过json方式将日志数据post过来,然后通过httpget的方式读取日志。当时我们的实现是将所有日志信息添加到数组末尾,这意味着所有日志信息都会保存在内存中。但分布式系统的日志数量将非常巨大,例如推特一天的日志数量就达到......
  • windows使用navicate 导出导入MongoDB数据
    1.下载安装navicate以及mongodb-database-tools-windowsmongodb-database-tools-windows下载地址 https://www.mongodb.com/try/download/database-tools 2.navicate设置MongoDBdump、mongorestore可执行文件路径(mongodb-database-tools里的bin目录)3.选择要备份或恢复......
  • 基于 hugo 和 papermod 主题搭建自己的博客
    部署博客到vercelFreeNom申请域名首先,梯子最好选择美国的,并且freenom选择地址时最好与ip所在州可以对应得上;进入FreeNom,输入zwyb.tk,然后点击检查可用性,这里要记得输入后缀,能避免点击现在获取显示不可用的问题。如下图所示:Cloudfare管理域名cloudfare添加站点zwyyy456.ml,然......
  • golang对于[]byte数组转string进行比较的优化
    当需要比较两个[]byte数组是否相等时有好几种方案,下面可以看出前三种方案都是优化过的,效率高的方案。packagemainimport( "bytes" "crypto/rand" mr"math/rand" "testing")funcStringEqual(nint,ffunc(a,b[]byte)bool){ buf:=make([]byte,1024) rand.......