Golang 数据库操作(sqlx)和不定字段结果查询
一、Mysql数据库
为什么要使用数据库
- 一开始人手动记录数据,不能长期保存,追溯;
- 然后创建了文件系统,能够长期保存,但是查询追溯更新麻烦,数据可以发生冗余重复;
- 实现了数据库的方式,能够长期保存,方便查询,追溯,更新等等一系列操作,能设置一些约束进行数据的自我管控等等。
简单介绍下Mysql数据库的特点:关系型数据库、体积小、速度快、成本低、开源代码、中小网站适用、非常适合初学者学习
二、Golang操作Mysql
1. 现有test数据库表格user
2. 连接mysql数据库
2.1. 使用到的第三方库
github.com/go-sql-driver/mysql(驱动)
github.com/jmoiron/sqlx(对驱动的操作封装)
2.2. 连接
package main import ( "fmt" _ "github.com/go-sql-driver/mysql" "github.com/jmoiron/sqlx" ) func main() { db, err := sqlx.Open("mysql", "username:password@(127.0.0.1:3306)/test?charset=utf8mb4") if err != nil { fmt.Println("open mysql failed,", err) } db.SetMaxIdleConns(5) //设置最大的空闲数 db.SetMaxOpenConns(15) //设置最大的连接数 } //db, err := sqlx.Open("数据库类型", "用户名:密码@tcp(地址:端口)/数据库名")
3. SELECT数据库查询操作
package main import ( "fmt" _ "github.com/go-sql-driver/mysql" "github.com/jmoiron/sqlx" ) var db *sqlx.DB func initDB() { var err error db, err = sqlx.Open("mysql", "username:password@(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=true&loc=Local") if err != nil { fmt.Println("open mysql failed,", err) } db.SetMaxIdleConns(5) db.SetMaxOpenConns(15) } type User struct { Id int64 `db:"id"` Name string `db:"name"` Age int64 `db:"age"` Sex string `db:"sex"` } func main() { initDB() defer db.Close() var user []User sqlStr := "SELECT * FROM user" err := db.Select(&user, sqlStr) if err != nil { fmt.Println(err) } fmt.Println(user) }
得到结果->
[{1 张三 20 男} {2 李四 21 女} {3 王五 25 男}]
4. Insert数据库插入操作
package main import ( "fmt" _ "github.com/go-sql-driver/mysql" "github.com/jmoiron/sqlx" ) var db *sqlx.DB func initDB() { var err error db, err = sqlx.Open("mysql", "superxon:superxon@(172.20.3.12:3306)/test?charset=utf8mb4") if err != nil { fmt.Println("open mysql failed,", err) } db.SetMaxIdleConns(5) db.SetMaxOpenConns(15) } type User struct { Id int64 `db:"id"` Name string `db:"name"` Age int64 `db:"age"` Sex string `db:"sex"` } func main() { initDB() defer db.Close() var user = User{ Name: "小六", Age: 18, Sex: "女", } sqlStr := "INSERT INTO user(name, age, sex) VALUES (?,?,?)" res, err := db.Exec(sqlStr, user.Name, user.Age, user.Sex) if err != nil { fmt.Println(err) } c, _ := res.RowsAffected() fmt.Println("有多少行被创建", c) }
得到结果->
有多少行被创建 1
5. Update数据库更新操作
package main import ( "fmt" _ "github.com/go-sql-driver/mysql" "github.com/jmoiron/sqlx" ) var db *sqlx.DB func initDB() { var err error db, err = sqlx.Open("mysql", "superxon:superxon@(172.20.3.12:3306)/test?charset=utf8mb4") if err != nil { fmt.Println("open mysql failed,", err) } db.SetMaxIdleConns(5) db.SetMaxOpenConns(15) } type User struct { Id int64 `db:"id"` Name string `db:"name"` Age int64 `db:"age"` Sex string `db:"sex"` } func main() { initDB() defer db.Close() var user = User{ Id: 4, Age: 20, } sqlStr := "UPDATE user SET age=? WHERE id=?" res, err := db.Exec(sqlStr, user.Age, user.Id) if err != nil { fmt.Println(err) } c, _ := res.RowsAffected() fmt.Println("有多少行被更改", c) }
得到结果->
有多少行被更改 1
6. DELETE数据库删除操作
package main import ( "fmt" _ "github.com/go-sql-driver/mysql" "github.com/jmoiron/sqlx" ) var db *sqlx.DB func initDB() { var err error db, err = sqlx.Open("mysql", "superxon:superxon@(172.20.3.12:3306)/test?charset=utf8mb4") if err != nil { fmt.Println("open mysql failed,", err) } db.SetMaxIdleConns(5) db.SetMaxOpenConns(15) } type User struct { Id int64 `db:"id"` Name string `db:"name"` Age int64 `db:"age"` Sex string `db:"sex"` } func main() { initDB() defer db.Close() deleteId := 3 sqlStr := "DELETE FROM user WHERE id=?" res, err := db.Exec(sqlStr, deleteId) if err != nil { fmt.Println(err) } c, _ := res.RowsAffected() fmt.Println("有多少行被删除", c) }
得到结果->
有多少行被删除 1
三、生成动态字段数据库查询结果
在项目中经常会遇到一个问题:在同一个函数中,查询不同的表格,生成不同的结果,每次都要重新构建结构体
思路:把结果弄成[]map[string]string类型,这样就能把查询得到的数据都填充进去。
使用的是内置的库
database/sql
package main import ( "database/sql" "fmt" _ "github.com/go-sql-driver/mysql" ) var db *sql.DB func initDB() { var err error db, err = sql.Open("mysql", "superxon:superxon@(172.20.3.12:3306)/test?charset=utf8mb4") if err != nil { fmt.Println("open mysql failed,", err) } db.SetMaxIdleConns(5) db.SetMaxOpenConns(15) } func main() { initDB() defer db.Close() sqlStr := "SELECT * FROM user" //可以换成其它的查询语句,可以得到相应的查询结果,不用每次都去构建存放的结构体 rows, err := db.Query(sqlStr) if err != nil { fmt.Println(err) } defer rows.Close() //列出所有查询结果的字段名 cols, _ := rows.Columns() //values是每个列的值,这里获取到byte里 values := make([][]byte, len(cols)) //query.Scan的参数,因为每次查询出来的列是不定长的,用len(cols)定住当次查询的长度 scans := make([]interface{}, len(cols)) //让每一行数据都填充到[][]byte里面 for i := range values { scans[i] = &values[i] } res := make([]map[string]string, 0) for rows.Next() { _ = rows.Scan(scans...) row := make(map[string]string) for k, v := range values { //每行数据是放在values里面,现在把它挪到row里 key := cols[k] row[key] = string(v) } res = append(res, row) } fmt.Println(res) }
得到结果->
[map[age:20 id:1 name:张三 sex:男] map[age:21 id:2 name:李四 sex:女] map[age:20 id:4 name:小六 sex:女]]
关于Golang 数据库操作(sqlx)和不定字段结果查询的文章就介绍至此,更多相关Golang 数据库操作和不定字段结果查询内容请搜索编程宝库以前的文章,希望大家多多支持编程宝库!
golang数据结构之golang稀疏数组sparsearray详解: 一、稀疏数组1. 先看一个实际的需求编写的五子棋程序中,有存盘退出和续上盘的功能分析按照原始的方式来的二维数组的问题因为该二维数组的很多值是默认值0,因此记录 ...