首页 > 数据库 >mysql、sqlx

mysql、sqlx

时间:2023-05-24 14:55:47浏览次数:49  
标签:sqlx err DB db id mysql 连接 连接池

1.导包

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

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

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

1 dsn := "root:123456@tcp(127.0.0.1:3306)/test_db"
2 db, err := sql.Open("mysql", dsn)
3 db.SetMaxIdleConns(10) //设立连接池的最大连接数
4 if err != nil {
5 panic(err)
6 }
7 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和影响的行数。 

查询

 

 1 rows, err := db.Query("select * from test_db.user_table")
 2 for rows.Next() {
 3 var id, age int
 4 var name string
 5 err := rows.Scan(&id, &name, &age)
 6 if err != nil {
 7 panic(err)
 8 }
 9 fmt.Println(id, name, age)
10 }
View Code

 



查询单行:

1 var id, age int
2 var name string
3 _ = db.QueryRow("select * from test_db.user_table").Scan(&id, &name, &age)
4 println(id, name, age)
View Code

 


 插入

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

 



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

 事务

 

 1 func Transaction(db *sql.DB) {
 2 //事务开启
 3 tx, err := db.Begin()
 4 if err != nil {
 5 tx.Rollback()
 6 log.Println(err)
 7 return
 8 }
 9 _, err = tx.Exec("update online_info set Status=? where User_id=?", "online", 1)
10 if err != nil {
11 tx.Rollback()
12 log.Println(err)
13 return
14 }
15 //提交事务
16 err = tx.Commit()
17 if err != nil {
18 tx.Rollback()
19 log.Println(err)
20 return
21 }
22 }
View Code

 


 sqlx库

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

sqlx特性

db.Get():查询一行

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

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

 


db.Select():查询多行结果
dest需要为slice类型的指针,

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

 



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

 

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

 



 namedExec():与namedQuery作用相同,用于Exec()
 StructScan():Scan增强版,直接将结果中的值赋给结构体变量。

 连接池

源码分析:[https://zhuanlan.zhihu.com/p/430993402](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

标签:sqlx,err,DB,db,id,mysql,连接,连接池
From: https://www.cnblogs.com/yihengye/p/17428294.html

相关文章

  • MySQL8.0清空binlog
    环境centos7.9mysql Ver8.0.32登录MySQL,查看binlog日志#查看binlog日志开启状态,log_bin值为ON表示开启状态mysql>showvariableslike'log_bin';+---------------+-------+|Variable_name|Value|+---------------+-------+|log_bin|ON|+---------......
  • MySQL8.0配置my.cnf
    环境centos7.9因为是源码安装的MySQL8.0.32,查了一下MySQL8.0之后源码中不包含my.cnf文件和my-default.cnf文件了。手动创建一个my.cnf,放到默认目录/etc下,以后修改配置可以从my.cnf文件中修改,重启生效,相当于永久生效。文件内容:暂时先配这些,后期再扩展[client]port=3306soc......
  • MySQL保证主备一致,如何解决循环复制?
    备库只读,是如何和主库同步数据的?你可能会问,我把备库设置成只读了,还怎么跟主库保持同步更新呢?这个问题,你不用担心。因为readonly设置对超级(super)权限用户是无效的,而用于同步更新的线程,就拥有超级权限。主备同步的详细流程?可以看到:主库接收到客户端的更新请求后,执行内部......
  • 【MySQL】MySQL 事务以及隔离级别和MVCC
    1  前言这节我们来看看MySQL中的事务,比如我们生活中的转账,要保证转账业务里的所有数据库的操作是不可分割的,要么全部执行成功,要么全部失败,不允许出现中间状态的数据。数据库中的「事务(Transaction)」就能达到这样的效果。我们在转账操作前先开启事务,等所有数据库操作执行完成......
  • mysql 导出表数据
    mysql导出表数据导出数据库为dbname的表结构mysqldump-uuser-pdbpasswd-ddbname>db.sql;导出数据库为dbname某张表结构mysqldump-uuser-pdbpasswd-ddbnametable_name>db.sql;导出数据库为dbname所有表结构及表数据mysqldump-uuser-pdbpasswddbname>db.sql;......
  • MySQL数据基础知识整理—4
        今天我们了解下MySQL数据库中的索引和最基础的事务是什么吧。注意:本次的索引会作为主要讲解部分,事务会分两部分讲解;希望大家在看本文章前先看完我之前的MySQL数据基础知识整理。索引    索引:是一种用于快速查找数据库中特定数据的数据结构。它类似于书籍的目录,可......
  • mysql的继续学习第二天
    在mysql中读取文件的函数load_file使用方法:select*fromarticlewhereid=-1unionselect1,1,1,1,load_file('c:/boot.ini');//load_file会占一位,并且路径使用括号包围intooutfile写入函数:(来自csdn查找)要使用intooutfile把代码写到web目录取得webshell首先需要3大先天......
  • Ubuntu22.04 MySQL 8.0安装修改密码以及远程连接
    安装sudoapt-getinstallmysql-server-y卸载sudoaptpurgemysql-*sudorm-rf/etc/mysql//var/lib/mysqlsudoaptautoremovesudoaptautoclean`修改/etc/mysql/mysql.conf.d/mysqld.cnf配置文件重启:注释掉地址绑定:#bind-address=127.0.0.1#mysqlx-bind-a......
  • 2)MySQL表管理之创建删除、约束实施、自增长字段、复制表结构
    一、表操作:创建表:createtabletablename(字段名1数据类型,...字段名n数据类型);查看当前数据库中所有表:showtables;查看指定表的结构:desc[ribe]table_name;查看指定表的详细信息:showcreatetabletable_name;......
  • MySQL学习基础篇Day8
    5.7多表查询案例数据环境准备:createtablesalgrade(gradeint,losalint,hisalint)comment'薪资等级表';insertintosalgradevalues(1,0,3000);insertintosalgradevalues(2,3001,5000);insertintosalgradevalues(3,5001,8000);insertin......