• 操作Mysql


    操作Mysql

    1、使用包database/sql

    database/sql 是 Go 操作数据库的标准库之一,它提供了一系列接口方法,用于访问数据库(mysql,sqllite,oralce,postgresql),它并不会提供数据库特有的方法,那些特有的方法交给数据库驱动去实现

    而通常在工作中,我们更多的是用  https://github.com/jmoiron/sqlx 包来操作数据库,sqlx 是基于标准库 sql 的扩展,并且我们可以通过 sqlx 操作各种类型的数据,如将查询的数据转为结构体等

    github地址

    sqlx 库提供了一些类型,掌握这些类型的用法非常的重要

    1. DB(数据库对象)

    sql.DB 类型代表了数据库,其它语言操作数据库的时候,需要创建一个连接,对于 Go 而言则是需要创建一个数据库类型,它不是数据库连接,Go 中的连接来自内部实现的连接池,连接的建立是惰性的,连接将会在操作的时候,由连接池创建并维护
    使用 sql.Open 函数创建数据库类型,第一个是数据库驱动名,第二个是连接信息的字符串

    var Db *sqlx.DB
    db, err := sqlx.Open("mysql","username:password@tcp(ip:port)/database?charset=utf8")
    Db = db
    
    • 1
    • 2
    • 3
    1. Results 和 Result(结果集)

    新增、更新、删除;和查询所用的方法不一样,所有返回的类型也不同

    • Result 是 新增、更新、删除时返回的结果集
    • Results 是查询数据库时的结果集,sql.Rows 类型表示查询返回多行数据的结果集,sql.Row 则表示单行查询的结果集
    1. Statements(语句)

    sql.Stmt 类型表示 sql 语句,例如 DDL,DML 等类似的 sql 语句,可以当成 prepare 语句构造查询,也可以直接使用 sql.DB 的函数对其操作

    2、Query() 方法使用

    说明

    Query() 方法返回的是一个 sql.Rows 类型的结果集,也可以用来查询多个字段的数据,不过需要定义多个字段的变量进行接收,迭代后者的 Next() 方法,然后使用 Scan() 方法给对应类型变量赋值,以便取出结果,最后再把结果集关闭(释放连接)

    代码示例

    package main
    
    import (
    	"fmt"
    	_ "github.com/go-sql-driver/mysql"
    	"github.com/jmoiron/sqlx"
    )
    
    type mysqlStruct struct {
    	userName  string
    	password  string
    	ipAddress string
    	port      int
    	dbName    string
    	charset   string
    }
    
    func connetMysql(m *mysqlStruct) *sqlx.DB {
    	dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=%s", m.userName, m.password, m.ipAddress, m.port, m.dbName, m.charset)
    	Db, err := sqlx.Open("mysql", dsn)
    	if err != nil {
    		fmt.Printf("mysql connect failed, detail is [%v]\n", err.Error())
    	}
    	return Db
    }
    
    func queryData(Db *sqlx.DB, sql string) (err error) {
    	rows, err := Db.Query(sql)
    	if err != nil {
    		fmt.Printf("query faied, error:[%v]", err.Error())
    	}
    	for rows.Next() {
    		var (
    			id      int
    			project string
    			keyword string
    		)
    		if err := rows.Scan(&id, &project, &keyword); err != nil {
    			fmt.Println("get data failed, error:[%v]", err.Error())
    		}
    		fmt.Println(id, project, keyword)
    	}
    	if err := rows.Close(); err != nil {
    		panic(err)
    	}
    	return err
    }
    
    func main() {
    	var mysqlStruct = mysqlStruct{
    		userName:  "*******",
    		password:  "*******",
    		ipAddress: "*******",
    		port:      3306,
    		dbName:    "********",
    		charset:   "utf8",
    	}
    	var Db *sqlx.DB = connetMysql(&mysqlStruct)
    	defer func(Db *sqlx.DB) {
    		if err := Db.Close(); err != nil {
    			return
    		}
    	}(Db)
    	sql := "select id,project,keyword from xunjia where id = 1"
    	err := queryData(Db, sql)
    	if err != nil {
    		return
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69

    3、Get() 方法使用

    说明

    将查询到的一条记录,保存到结构体
    说明:结构体的字段名首字母必须大写,不然无法寻址

    代码示例

    package main
    
    import (
    	"fmt"
    	_ "github.com/go-sql-driver/mysql"
    	"github.com/jmoiron/sqlx"
    )
    
    type mysqlStruct struct {
    	userName  string
    	password  string
    	ipAddress string
    	port      int
    	dbName    string
    	charset   string
    }
    
    func connetMysql(m *mysqlStruct) *sqlx.DB {
    	dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=%s", m.userName, m.password, m.ipAddress, m.port, m.dbName, m.charset)
    	Db, err := sqlx.Open("mysql", dsn)
    	if err != nil {
    		fmt.Printf("mysql connect failed, detail is [%v]\n", err.Error())
    	}
    	return Db
    }
    
    func getData(Db *sqlx.DB, sql string) (err error) {
    
    	type xunjiaInfo struct {
    		Id      int    `db:"id"`
    		Project string `db:"project"`
    		Keyword string `db:"keyword"`
    	}
    
    	//初始化定义结构体,用来存放查询数据
    	var xunjiaData *xunjiaInfo = new(xunjiaInfo)
    	err = Db.Get(xunjiaData, sql)
    	if err != nil {
    		fmt.Printf("query faied, error:[%v]", err.Error())
    	}
    
    	//打印结构体内容
    	fmt.Println(xunjiaData.Id, xunjiaData.Project, xunjiaData.Keyword)
    
    	return err
    }
    
    func main() {
    	var mysqlStruct = mysqlStruct{
    		userName:  "********",
    		password:  "********",
    		ipAddress: "********",
    		port:      3306,
    		dbName:    "********",
    		charset:   "utf8",
    	}
    	var Db *sqlx.DB = connetMysql(&mysqlStruct)
    	defer func(Db *sqlx.DB) {
    		if err := Db.Close(); err != nil {
    			return
    		}
    	}(Db)
    	sql := "select id,project,keyword from xunjia"
    	err := getData(Db, sql)
    	if err != nil {
    		return
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    4、Select() 方法使用

    说明

    将查询的多条记录,保存到结构体的切片中
    说明:结构体的字段名首字母必须大写,不然无法寻址

    代码示例

    package main
    
    import (
    	"fmt"
    	_ "github.com/go-sql-driver/mysql"
    	"github.com/jmoiron/sqlx"
    )
    
    type mysqlStruct struct {
    	userName  string
    	password  string
    	ipAddress string
    	port      int
    	dbName    string
    	charset   string
    }
    
    func connetMysql(m *mysqlStruct) *sqlx.DB {
    	dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=%s", m.userName, m.password, m.ipAddress, m.port, m.dbName, m.charset)
    	Db, err := sqlx.Open("mysql", dsn)
    	if err != nil {
    		fmt.Printf("mysql connect failed, detail is [%v]\n", err.Error())
    	}
    	return Db
    }
    
    func selectData(Db *sqlx.DB, sql string) (err error) {
    	type xunjiaInfo struct {
    		Id      int    `db:"id"`
    		Project string `db:"project"`
    		Keyword string `db:"keyword"`
    	}
    
    	//定义结构体切片,用来存放多条查询记录
    	var xunjiaInfoSlice []xunjiaInfo
    	err = Db.Select(&xunjiaInfoSlice, sql)
    	if err != nil {
    		fmt.Printf("query faied, error:[%v]", err.Error())
    		return
    	}
    
    	//遍历结构体切片
    	for _, xunjiaData := range xunjiaInfoSlice {
    		fmt.Println(xunjiaData.Id, xunjiaData.Project, xunjiaData.Keyword)
    	}
    	return err
    }
    
    func main() {
    	var mysqlStruct = mysqlStruct{
    		userName:  "***********",
    		password:  "***********",
    		ipAddress: "***********",
    		port:      3306,
    		dbName:    "***********",
    		charset:   "utf8",
    	}
    	var Db *sqlx.DB = connetMysql(&mysqlStruct)
    	defer func(Db *sqlx.DB) {
    		if err := Db.Close(); err != nil {
    			return
    		}
    	}(Db)
    	sql := "select id,project,keyword from xunjia"
    	err := selectData(Db, sql)
    	if err != nil {
    		return
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69

    5、增删改 Exec()方法

    Exec 和 MustExec 从连接池中获取一个连接然后指向对应的 query 操作,对于不支持 ad-hoc query execution 的驱动,在操作执行的背后会创建一个 prepared statement,在结果返回前,这个 connection 会返回到连接池中
    需要注意的是,不同的数据库,使用的占位符不同,mysql 采用 ? 作为占位符

    • Mysql 使用 ?
    • PostgreSQL 使用 1,1,2 等等
    • SQLLite 使用 ? 或 $1
    • Oracle 使用 :name        (注意有冒号)

    代码示例

    package main
    
    import (
    	"fmt"
    	_ "github.com/go-sql-driver/mysql"
    	"github.com/jmoiron/sqlx"
    )
    
    type mysqlStruct struct {
    	userName  string
    	password  string
    	ipAddress string
    	port      int
    	dbName    string
    	charset   string
    }
    
    func connetMysql(m *mysqlStruct) *sqlx.DB {
    	dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=%s",
    		m.userName, m.password, m.ipAddress, m.port, m.dbName, m.charset)
    	Db, err := sqlx.Open("mysql", dsn)
    	if err != nil {
    		fmt.Printf("mysql connect failed, detail is [%v]\n", err.Error())
    	}
    	return Db
    }
    
    func addRecord(Db *sqlx.DB, sql string) (err error) {
    	for i := 0; i < 1; i++ {
    		result, err := Db.Exec(sql)
    		if err != nil {
    			fmt.Printf("data insert faied, error:[%v]", err.Error())
    		}
    		id, _ := result.LastInsertId()
    		fmt.Printf("insert success, last id:[%d]\n", id)
    	}
    	return err
    }
    
    func updateRecord(Db *sqlx.DB, sql string) (err error) {
    	//更新数据
    	result, err := Db.Exec(sql)
    	if err != nil {
    		fmt.Printf("update faied, error:[%v]", err.Error())
    	}
    	num, _ := result.RowsAffected()
    	fmt.Printf("update success, affected rows:[%d]\n", num)
    	return err
    }
    
    func deleteRecord(Db *sqlx.DB, sql string) (err error) {
    	//删除数据
    	result, err := Db.Exec(sql)
    	if err != nil {
    		fmt.Printf("delete faied, error:[%v]", err.Error())
    	}
    	num, _ := result.RowsAffected()
    	fmt.Printf("delete success, affected rows:[%d]\n", num)
    	return err
    }
    
    func main() {
    	var mysqlStruct = mysqlStruct{
    		userName:  "*********",
    		password:  "*********",
    		ipAddress: "*********",
    		port:      3306,
    		dbName:    "*********",
    		charset:   "utf8",
    	}
    	var Db *sqlx.DB = connetMysql(&mysqlStruct)
    	defer func(Db *sqlx.DB) {
    		if err := Db.Close(); err != nil {
    			return
    		}
    	}(Db)
    
    	sql := "delete from **** where id=9"
    	err := deleteRecord(Db, sql)
    	if err != nil {
    		return
    	}
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
  • 相关阅读:
    【Mysql系列】03_系统设计
    SpringBoot集成Redis实现缓存——基于SpringBoot和Vue的后台管理系统项目系列博客(二十)
    AQS之CountDownLatch分析 (八)
    swagger 依赖及应用
    论文笔记:Code Llama: Open Foundation Models for Code
    外包干了一个月,技术明显进步。。。。。
    Spring Boot+MyBatis+MySQL+Spring MVC之论坛首页开发
    【Linux】基础:Linux环境基础开发工具——yum
    Java编码
    mininet搭建SDN环境访问互联网【C4】
  • 原文地址:https://blog.csdn.net/qq_34158880/article/details/127829547