首页 > 数据库 >操作MySQL之sqlx库

操作MySQL之sqlx库

时间:2024-03-14 17:46:20浏览次数:23  
标签:sqlx err fmt DB music MySQL Println 操作 id

目录

一、介绍和使用

  • 上一篇我们用了go-sql-driver/mysql库来操作mysql,还有一个更优秀的库sqlx,它也是对标准库database/sql具体的实现,并进行进一步封装和新增了一些方法

1. 安装和快速使用

go get github.com/jmoiron/sqlx
package main

import (
	"fmt"
	_ "github.com/go-sql-driver/mysql" //执行一些初始化操作
	"github.com/jmoiron/sqlx"
)


func main() {

	//1 链接方式一
	DB,err:=sqlx.Open("mysql","root:123@tcp(127.0.0.1:3306)/lqz?charset=utf8")
	if err != nil {
		fmt.Println("链接出错:",err)
	}
	defer DB.Close()
	err=DB.Ping()
	if err!=nil {
		fmt.Println("通信出错",err)
	}
	// 2 链接方式二
	//DB:=sqlx.MustOpen("mysql","root:123@tcp(127.0.0.1:3306)/lqz?charset=utf8")
	//defer DB.Close()
	//err:=DB.Ping()
	//if err!=nil {
	//	fmt.Println("通信出错",err)
	//}

}

二、基本增删查改

  • 之前go-sql-driver/mysql库的用法完全兼容

1. 增加数据

// 1 增加数据
	sqlStr := "insert into music(name, year,sign_id) values (?,?,?)"
	ret, err := DB.Exec(sqlStr, "听爸爸的话", 2023,1)
	if err != nil {
		fmt.Println("插入出错",err)
		return
	}
	theID, err := ret.LastInsertId() // 新插入数据的id
	if err != nil {
		fmt.Println("获取插入的id错误:",err)
		return
	}
	fmt.Println("插入成功,id为:", theID)

2. 修改数据

	// 2 修改数据
	sqlStr := "update music set name= ? where id = ?"
	ret, err := DB.Exec(sqlStr, "长大后我就成了你", 4)
	if err != nil {
		fmt.Println("更新失败",err)
		return
	}
	n, err := ret.RowsAffected()
	if err != nil {
		fmt.Println("获取影响的行数失败:",err)
		return
	}
	fmt.Println("更新成功,影响行数为:",n)

3. 删除数据

	// 3 删除数据
	sqlStr := "delete from music where id = ?"
	ret, err := DB.Exec(sqlStr, 1)
	if err != nil {
		fmt.Println("删除出错:",err)
		return
	}
	n, err := ret.RowsAffected() // 操作影响的行数
	if err != nil {
		fmt.Println("获取操作影响的行数出错:",err)
		return
	}
	fmt.Println("删除成功,影响的行数为:",n)

4. 查询数据

// 4 查询数据单条
	var music struct {
		Id     int
		Name   string
		Year   string
		SignId int
	}
	//QueryRow后一定要调用Scan方法,否则持有的数据库链接不会被释放
	err = DB.QueryRow("select * from music where id=?", 2).Scan(&music.Id, &music.Name, &music.Year, &music.SignId)
	if err != nil {
		fmt.Println("查询出错:", err)
	}
	fmt.Println(music)
	// 5 查询多条
	sqlStr := "select * from music where id > ?"
	rows, err := DB.Query(sqlStr, 1)
	if err != nil {
		fmt.Println("查询出错:", err)
		return
	}
	// 关闭rows释放持有的数据库链接
	defer rows.Close()
	// 循环读取结果集中的数据
	for rows.Next() {
		var m struct {
			Id     int
			Name   string
			Year   string
			SignId int
		}
		err := rows.Scan(&m.Id, &m.Name, &m.Year, &m.SignId)
		if err != nil {
			fmt.Println("遍历出错", err)
			return
		}
		fmt.Println(m)
	}

三、其他查询

1. Get和Select查询

	type Music struct {
		Id     int
		Name   string
		Year   string
		SignId int `db:"sign_id"`
	}
	var music Music
	err=DB.Get(&music,"select * from music where id=?", 2)
	if err != nil {
		fmt.Println("查询出错",err)
	}
	fmt.Println(music)
	// Select 查询
	type Music struct {
		Id     int
		Name   string
		Year   string
		SignId int `db:"sign_id"`
	}
	var music []Music
	err=DB.Select(&music,"select * from music where id > ?", 2)
	if err != nil {
		fmt.Println("查询出错",err)
	}
	fmt.Println(music)

四、其他方法

1. sqlx的NamedExec

  • 传参可使用key-value的形式,不用原来一个问号?对应一个参数
    用来绑定SQL语句与结构体或map中的同名字段
sqlStr := "insert into music(name, year,sign_id) values (:name,:year,:sign_id)"
_, err = DB.NamedExec(sqlStr,
		map[string]interface{}{
			"name": "好汉歌",
			"year": 2024,
			"sign_id":1,
		})

2. sqlx的NamedQuery

  • 支持查询
// 使用map作为查询名	
type Music struct {
		Id     int
		Name   string
		Year   string
		SignId int `db:"sign_id"`
	}
	sqlStr := "SELECT * FROM music WHERE name=:name"
	// 使用map做命名查询
	rows, _ := DB.NamedQuery(sqlStr, map[string]interface{}{"name": "好汉歌"})
	defer rows.Close()
	for rows.Next(){
		var m Music
		rows.StructScan(&m)
		fmt.Println(m)
	}
	// 使用结构体作为查询名
type Music struct {
		Id     int
		Name   string
		Year   string
		SignId int `db:"sign_id"`
	}
	sqlStr := "SELECT * FROM music WHERE name=:name"
	// 使用结构体做命名查询
	var music=Music{Name:"好汉歌"}
	rows, _ := DB.NamedQuery(sqlStr,music)
	defer rows.Close()
	for rows.Next(){
		var m Music
		rows.StructScan(&m)
		fmt.Println(m)
	}

五、事务操作

  • sqlx提供了db.Beginx()tx.Exec()方法进行事务操作
	tx, err := DB.Beginx() // 开启事务
	if err != nil {
		fmt.Printf("开启事务错误:%v\n", err)
		return
	}

	_,err=tx.Exec("insert into music(name, year,sign_id) values (?,?,?)", "听奶奶的话",2023,1)
	if err != nil {
		tx.Rollback() // 出错就回滚
		fmt.Println("出错回滚")
		return
	}
	_,err=tx.Exec("insert into music(name, year,sign_id) values (?,?,?)", "听爷爷的话")
	if err != nil {
		tx.Rollback() // 出错就回滚
		fmt.Println("出错回滚")
		return
	}
	tx.Commit()

六、连接池

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

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

db.SetMaxOpenConns(100) // 设置连接池最大连接数
db.SetMaxIdleConns(20)  // 设置连接池最大空闲连接数

标签:sqlx,err,fmt,DB,music,MySQL,Println,操作,id
From: https://www.cnblogs.com/Mcoming/p/18073549

相关文章

  • 操作Redis之redigo
    目录一、go操作redis的选择二、redigo快速使用1.快速链接三、redis操作四、连接池一、go操作redis的选择golang操作redis主要有两个库,go-redis和redigo。go-redis:star数更多,支持连接哨兵及集群模式的Redisredigo:star数少一些,操作更简单二、redigo快速使用安装:gog......
  • MySQL 5.5和8.0.2 安装在一台电脑上
    情况说明:MySQL5.5已经安装,安装MySQL8方法一:InstallDirectory更改为C:\ProgramFiles\MySQLE\MySQLServer8.0;DataDirectory更改为C:\ProgramData\MySQLE\MySQLServer8(默认路径加E,也可以自定义)2.安装时更改端口号为3307、XProtocolPort为330703.添加环境变量path......
  • MYSQL 存储过程示例
    MySQL5.0版本开始支持存储过程。存储过程(StoredProcedure)是一种在数据库中存储复杂程序,以便外部程序调用的一种数据库对象。存储过程是为了完成特定功能的SQL语句集,经编译创建并保存在数据库中,用户可通过指定存储过程的名字并给定参数(需要时)来调用执行。存储过程思想上很......
  • MYSQL学习笔记26: 多表查询|子查询
    多表查询|子查询行子查询查询与张无忌工资相同,且直属领导相同的员工#写法1select*fromempwheresalary=(selectsalaryfromempwherename='张无忌')andmanagerId=(selectmanagerIdfromempwherename='张无忌');#可以合并起来,写入一个集合selec......
  • MySQL之运算符篇
    1.算术运算符算术运算符主要用于数学运算,其可以连接运算符前后的两个数值或表达式,对数值或表达式进行加(+)、减(-)、乘(*)、除(/)和取模(%)运算。1.1 加法与减法运算符由运算结果可以得出如下结论:一个整数类型的值对整数进行加法和减法操作,结果还是一个整数;一个整数类型的值......
  • 数组常见操作【最大/最小/数据反转操作】
    importjava.util.Scanner;publicclassday_4_5{publicstaticvoidmain(String[]args){/*数组的常见操作*///遍历int[]arr={3,5,2,1,4};intmax=arr[0];intmax1=0;intmax2=0;for(in......
  • Mysql 100个表嵌套查询 存储过程
    背景1. 业务销售订单会随机落在1~100表中,查询一个订单时需要1到100表依次去查询,增加手工重复操作和浪费时间。2.查询未解冻数据时,需要过滤部分解冻的数据,此时需要用到嵌套查询。 一、根据订单号,循环1~100个表,查询出订单数据CREATEDEFINER=`{数据库连接账号}`@`%`......
  • 【掌握版本控制:Git 入门与实践指南】远程操作|标签管理
                             ......
  • 并发支持库:原子操作类型
    原子操作这些组件为细粒度的原子操作提供,允许无锁并发编程。类型别名atomic_bool(C++11)std::atomic(typedef)atomic_char(C++11)std::atomic(typedef)atomic_schar(C++11)std::atomic(typedef)atomic_uchar(C++11)std::atomic(typedef)atomic_short(......
  • 操作DOM对象
    创建一个标签,实现插入<script>varjs=document.getElementById('js');//已经存在的节点varlist=document.getElementById('list');//通过js创建一个节点varnewp=document.createElement('p')//创建一个p标签newp.id='newp'newp.inner......