操作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. 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
	}
}

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
	}
}

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
	}
}

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
	}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值