【Golang】Go sqlx操作mysql教程

码农印象 等级 404 0 0

sqlx是Go数据库操作包,它在database/sql包的基础上增加了更加高效的数据库操作函数,也就是说使用sqlx操作数据库比使用database/sql更加方便。

1.sqlx关键概念介绍

sqlx定义了下面几个关键类型:

sqlx.DB - 代表一个数据库
sqlx.Tx - 代表一个事务
sqlx.Rows - 代表sql查询结果的多行记录
sqlx.Row - 代表sql查询结果的一条记录
使用sqlx的关键步骤:
根据mysql地址和帐号密码,创建sqlx.DB对象
通过sqlx.DB对象的sql查询函数,操作数据库

2.安装包

//安装sqlx包
go get github.com/jmoiron/sqlx

//安装mysql驱动
go get github.com/go-sql-driver/mysql

3.导入包

import (
    //导入mysql驱动
    _ "github.com/go-sql-driver/mysql"
    //导入sqlx包
    "github.com/jmoiron/sqlx"
)

3.连接数据库

//定义数据库对象
var pool *sqlx.DB

//定义mysql数据源,配置数据库地址,帐号以及密码, dsn格式下面会解释
dsn := "root:123456@tcp(localhost:3306)/tizi365?charset=utf8&parseTime=True&loc=Local"

//根据数据源dsn和mysql驱动, 创建数据库对象
pool, err := sqlx.Open("mysql", dsn)
if err != nil {
    panic(err)
}

MYSQL dsn格式:

{username}:{password}@tcp({host}:{port})/{Dbname}?charset=utf8&parseTime=True&loc=Local

  • 参数说明:
参数    说明
{username}    数据库帐号
{password}    数据库密码
{host}    数据库地址
{port}    数据库端口
{Dbname}    数据库名字

说明: charset=utf8 用于设置字符集,parseTime=True表示将数据库时间类型转换成Go时间类型

4.数据库连接池设置

sqlx.DB内置了数据库连接池,在你调用sql查询函数的时候,自动从连接池申请连接,可以通过下面方式设置连接池参数:

//设置连接池最大连接数
pool.SetMaxOpenConns(100)

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

5.sql语句绑定参数

绑定参数指的是:在sql语句中通过占位符(?), 定义一些参数,然后在执行sql语句的时候再把参数传递进去。

说明: sql语句绑定参数,除了方便我们拼接sql语句参数之外,还有一个重要的功能就是参数的安全检查和过滤,避免sql注入攻击。

例子:

//这里通过占位符(?),定义了两个参数
sql := "select * from tablename where cat=? and uid=?"

//执行sql,并且传入两个参数, 函数的第二个参数101对应sql语句的第一个问号,第三个参数5对应第二个问号
db.Queryx(sql, 101, 5)
提示:sqlx.DB提供的查询函数,都支持参数绑定,教程后续会有相应的例子

6.插入数据

sqlx为我们定义两个函数用于执行插入,更新以及执行DDL语句(创建表,修改表等等):

Exec
MustExec

这两个函数的作用是一样的,区别就是处理错误的机制不一样,MustExec遇到错误的时候直接抛出一个panic错误,程序就退出了;Exec是将错误和执行结果一起返回,由我们自己处理错误。

我们先定义一个mysql表结构并创建表:

//定义表结构
schema := `CREATE TABLE place (
    id int primary key auto_increment,
    country varchar(50),
    city varchar(50) NULL default '',
    telcode int);`

// 调用Exec函数执行sql语句,创建表
_, err := pool.Exec(schema)
//错误处理
if err != nil {
    panic(err)
}

插入数据的例子:

//定义sql语句, 通过占位符 问号( ? ) 定义了三个参数
countryCitySql := `INSERT INTO place (country, city, telcode) VALUES (?, ?, ?)`

//通过Exec插入数据, 这里传入了三个参数,对应sql语句定义的三个问号所在的位置
result1,err := db.Exec(countryCitySql, "中国", "香港", 852)
//错误处理
if err != nil {
    fmt.Println("插入失败!")
}
//插入成功后,获取insert id
id, _ := result.LastInsertId() 
//通过MustExec插入数据, 如果sql语句出错,则直接抛出panic错误
result2 := db.MustExec(countryCitySql, "South Africa", "Johannesburg", 27)

//插入成功后,获取插入id
id2, _ := result2.LastInsertId() 

提示: mysql表如果存在自增id,则可以通过Exec返回的结果对象的LastInsertId,查询新插入数据的ID

7.更新数据

//定义sql语句,通过问号定义了三个参数
sql := "update place set telcode=?, city=? where id=?"

//通过Exec更新数据, 这里传入了三个参数,对应sql语句定义的三个问号所在的位置
result1,err := db.Exec(sql, 100, "香港", 1)
//错误处理
if err != nil {
    fmt.Println("更新失败!")
}

//查询更新影响行数
rowsAffected, _ := result1.RowsAffected()

8.查询数据

8.1.通过Get和Select函数查询数据 Get函数主要用于查询一条记录,Select用于查询多条记录。

例子:

//定义保存查询结果的struct变量
p := Place{}

// 查询一条记录, 并且往sql语句传入参数 1,替换sql语句中的问号,最后将查询结果保存到struct对象中
err = pool.Get(&p, "SELECT * FROM place LIMIT ?", 1)


var total int

//统计表的总记录数,并将查询结果保存到一个变量中
err = pool.Get(&total, "SELECT count(*) FROM place")


//定义一个保存多条记录的struct数组变量
pp := []Place{}

// 通过Select查询多条记录,并且将结果保存至pp变量中
// 这里相当于将一条记录的字段值都映射到struct字段中
err = pool.Select(&pp, "SELECT * FROM place WHERE telcode > ?", 50)

var names []string
// 通过Select查询多条记录,并且将结果保存至names变量中
// 这里仅查询一个字段
err = pool.Select(&names, "SELECT name FROM place LIMIT 10") 

8.2.通过Queryx和QueryRowx查询数据 相对于Get和Select函数,Queryx和QueryRowx函数要繁琐一些。 Queryx可以用于查询多条记录,QueryRowx函数用于查询一条记录。

Queryx例子1

// 查询所有的数据,这里返回的是sqlx.Rows对象
rows, err := pool.Queryx("SELECT country, city, telcode FROM place")
//错误检测
if err !=nil {
    panic(err)
}

// 循环遍历每一行记录,rows.Next()函数用于判断是否还有下一行数据
for rows.Next() {
    //这里定义三个变量用于接收每一行数据
    var country string
    var city    string
    var telcode int

    //调用Scan函数,将当记录的数据保存到变量中,这里参数的顺序跟上面sql语句中select后面的字段顺序一致。
    err = rows.Scan(&country, &city, &telcode)
}

Queryx例子2, 将每一行记录保存到struct/map/数组变量中 Rows对象支持将每一行的数据保存到struct、map或者数组中。

//定义保存数据的结构体, 默认struct字段名(小写)跟表的字段名一致。
type Place struct {
    Country       string
    //因为city字段允许null,所以这里可以使用sql.NullString类型
    City          sql.NullString 
    //如果struct字段名跟表的字段名不一样,可以通过db标签设置数据库字段名
    TelephoneCode int `db:"telcode"`
}

//查询数据
rows, err := pool.Queryx("SELECT * FROM place")

//遍历数据
for rows.Next() {
    //下面演示如何将数据保存到struct、map和数组中
    //定义struct对象
    var p Place

    //定义map类型
    m := make(map[string]interface{})

    //定义slice类型
    s := make([]interface{}, 0)

    //使用StructScan函数将当前记录的数据保存到struct对象中
    err = rows.StructScan(&p)
    //保存到map
    err = rows.MapScan(&m)
    //保存到数组
    err = rows.SliceScan(&s)
}

QueryRowx例子

````c

QueryRowx操作跟Queryx类似,区别就是返回一行数据

//查询数据 row, err := pool.QueryRowx("SELECT country, city, telcode FROM place where id = ?", 1)

//定义保存数据的结构体, 默认struct字段名(小写)跟表的字段名一致。 type Place struct { Country string City sql.NullString Telcode int }

var p Place

//使用StructScan函数将当前记录的数据保存到struct对象中 err = row.StructScan(&p) 提示: sqlx.Row跟sqlx.Rows对象获取数据的方式一样,支持将数据保存到map,slice,struct中,可以参考上面Queryx的例子。

9.删除数据 //定义sql语句,通过问号定义了一个参数 sql := "delete from place where id=?"

//通过Exec删除数据, 这里传入了一个参数,对应sql语句定义的问号所在的位置 result1,err := pool.Exec(sql, 1)

//获取删除影响行数 rowsAffected, _ := result1.RowsAffected()

//错误处理 if err != nil { fmt.Println("更新失败!") } 10.事务处理 sqlx使用mysql事务的格式:

//开始一个事务,返回一个事务对象tx tx, err := pool.Beginx()

//使用事务对象tx, 执行事务 err = tx.Queryx(...) err = tx.Exec(...) err = tx.Exec(...)

if err != nil { //回滚事务 tx.Rollback() }

//提交事务 err = tx.Commit() 提示:注意上面的事务格式,使用的是事务对象tx执行sql,而不是数据库对象,数据库对象执行sql每次都会申请一个新的数据库连接,会导致事务无效。

mysql事务例子:

//开始一个事务,返回一个事务对象tx tx, err := pool.Beginx()

//执行事务 err1 = tx.Exec("delete from place where id=?", 1) err2 = tx.Exec("delete from place where id=?", 2)

if err1 != nil || err2 != nil { //回滚事务 tx.Rollback() }

//提交事务 tx.Commit()

收藏
评论区

相关推荐

学完了C++语法之后该学什么??(数据库篇)
数据库与中间件 主要是MySQL、MongDB、Redis、Nginx等; 在大学的课程里,一般都会开设一门数据库的课程,不过这门数据库是没有针对某一种数据库语言的(例如 MySQL、SQlite)。不过我这里只讲 MySQL,因为最频繁。数据库不在多。 把MySQL学好,还是特别重要的,千万不能停留在会用的层面上,而是应该
postgresql和mysql哪个好
postgresql和mysql都是免费且功能强大的开源数据库,很多用户面对这两个库都会有一个问题,那就是哪一个才是最好的开源数据库,MySQL还是PostgreSQL呢?该选择哪一个开源数据库呢? postgresql和mysql哪个好 一.PostgreSQL相对于MySQL的优势 1、在SQL的标准实现上要比MySQL完善,而且功能实现比较严谨;
[DB]PostgreSQL 与 MySQL 相比,优势何在?
PostgreSQL 与 MySQL 相比,优势何在? 数据库 知乎 Pg 没有 MySQL 的各种坑 MySQL 的各种 text 字段有不同的限制, 要手动区分 small text, middle text, large text... Pg 没有这个限制, text 能支持各种大小. 按照 SQL 标准, 做 null 判断不能用
【Golang】Go sqlx操作mysql教程
sqlx是Go数据库操作包,它在database/sql包的基础上增加了更加高效的数据库操作函数,也就是说使用sqlx操作数据库比使用database/sql更加方便。 1.sqlx关键概念介绍 sqlx定义了下面几个关键类型: go sqlx.DB 代表一个数据库 sqlx.Tx 代表一个事务 sqlx.Rows 代表sql查询结果的多行
golang实现MySQL数据库事物的提交与回滚
MySQL 事务主要用于处理操作量大,复杂度高的数据。在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务。事务用来管理 insert,update,delete 语句,事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行。 一般来说,事务是必须满足4个条件(ACID)::原子性(Atomicit
MySQL 8.0 创建 user 及允许远程连接
进入 mysql 命令行模式mysql h127.0.0.1 uroot p 查看当前 mysql 版本select version(); 查看当前 mysql 用户列表信息select host, user, authentication_string, plugin from user; 执行完上面的命令后会显示一个表格 查看表格
MySQL 5.7新特性:并行复制原理
众所周知,MySQL的复制延迟是一直被诟病的问题之一,在MySQL 5.7版本已经支持“真正”的并行复制功能,官方称为为enhanced multithreaded slave(简称MTS),因此复制延迟问题已经得到了极大的改进。总之,MySQL 5.7版本后,复制延迟问题永不存在。一、MySQL 5.6并行复制架构从MySQL 5.6.3版本开始
21分钟 MySQL 入门教程
21分钟 MySQL 入门教程 目录 一、MySQL的相关概念介绍(c1) 二、Windows下MySQL的配置(c2) 配置步骤(d1) MySQL服务的启动、停止与卸载(d2) 三、
MySQL(一)MySQL基础介绍
最近的学习内容是数据库相关的一些知识,主要以MySQL为主,参考书籍——《MySQL必知必会》MySQL学习及下载地址:https://dev.mysql.com/MySQL学习使用注意事项:1、必须访问一个已有的MySQL服务器,需要一个服务器账号(一个登录名和一个口令)2、MySQL运行在所有主要平台上,包括Windows、Linux、Solaris、M
Mysql Workbench使用教程
<1 MySQL WorkbenchMySQL Workbench 为数据库管理员、程序开发者和系统规划师提供可视化的Sql开发、数据库建模、以及数据库管理功能。 <2.MySQL Workbench 的下载和安装 (1)安装最新MySql时,有是否安装MySql Workbench的选项,可选择安装。 (2)可以独立安装MySql Workbench。
解决mysql ERROR 1045 (28000)-- Access denied for user
解决mysql ERROR 1045 (28000) Access denied for user问题,出现以下问题D:\develop\ide\mysql\mysql5.7\bin mysql u root p Enter password: ERROR 1045 (28000): Access denied for user 'ODBC'@'localh
一文读懂一条 SQL 查询语句是如何执行的
2001 年 MySQL 发布 3.23 版本,自此便开始获得广泛应用,随着不断地升级迭代,至今 MySQL 已经走过了 20 个年头。为了充分发挥 MySQL 的性能并顺利地使用,就必须正确理解其设计思想,因此,了解 MySQL 的逻辑架构是必要的。本文将通过一条 SQL 查询语句的具体执行过程来详细介绍 MySQL 架构中的各个组件。MySQL 逻辑架构
MySQL最全整理,1200页文档笔记,从高级到实战讲的太清楚了
闲话作为一名编程人员,对MySQL一定不会陌生,尤其是互联网行业,对MySQL的使用是比较多的。对于求职者来说,MySQL又是面试中一定会问到的重点,很多人拥有大厂梦,却因为MySQL败下阵来。实际上,MySQL并不难,今天这份最全的MySQL总结,一共1200页,几乎涵盖了MySQL的所有知识,尤其突出了实战技能和高级知识点,无论是工作还是面试看完这篇就足
阿里Java架构师谈:2021年最新Java面试经历
第一家是美团美团的话,三面下来,设计的内容知识也是挺广的吧,有MySQL、Redis、Kafka、线程、算法、+、volatile、线程、并发、设计模式等等... 一面问题:MySQL+Redis+Kafka+线程+算法 mysql知道哪些存储引擎,它们的区别 mysql索引在什么情况下会失效 mysql在项目中的优化场景,慢查询解决等 my
超详细图解!【MySQL进阶篇】存储过程,视图,索引,函数,触发器
@ 1.1 下载Linux 安装包下载地址: 1.2 安装MySQLcAPACHE1). 卸载 centos 中预安装的 mysql rpm qa | grep i mysql rpm e mysqllibs5.1.711.el6.x8664 nodeps2). 上传 mysql 的安装包 alt + p put E:/test/MySQL5.6.221