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和影响的行数。
查询
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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
查询单行:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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
插入
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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
更新,删除与插入类似,不多叙述。
事务
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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():查询一行
在查询的时候将结果通过反射赋值给结构体。
注意:需要传入结构体实例的地址,结构体字段要大写!
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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类型的指针,
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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字段
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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