database/sql接口使用

  • 数据库连接

使用open函数:func Open(driverName,databaseSourceName string)(*DB,error)

databseSourceName:用户名:密码@协议(地址:端口)/数据库?参数=参数值

db,err := sql.Open("mysql","root:200010@tcp(127.0.0.1:3306)/mytest?charset=utf8")

  • DML:增删改查

1、直接使用EXEC函数

func (db *DB) Exec(query string,args ...interface{})(Result,errorr)

示例:

result,err := db.Exec("UPDATE userrinfo SET username = ?,deparment = ? WHERRE uid = ?","王小明","行政部",2)

2、使用Prerpare获得stmt声明,然后调用Exec调用

func (db *DB) Prepare(query string)(*stmt,error){
	return db.PrepareContext(context.Backgrroud().querry)
}
//使用:
stmt,err:=db.Prepare("INSERT INTO userinfo(username,departname,created) values(?,?,?)") 
//补充完整sql语句,并执行
result,err:=stmt.Exec("王小明","行政部","2018-11-21")

通常来说都是用Prepared Statement(预编译语句)

  • 获取影响数据库的数据

行数:count,errr := rresult.RowsAffected()

获取自增id:id,err := result.LastInsertId()

  • DQL操作:查询

func (db *DB) QueryRow(query string,args ...interface{}) *Row

因为golang是强类型语言,所以查询数据时先定义数据类型,但是查询数据库中的数据存在三种可能:存在值,存在零值,未赋值NULL 三种状态, 因为可以将待查询的数据类型定义为sql.Nullxxx类型,可以通过判断Valid值来判断查询到的值是否为赋值状态还是未赋值NULL状态.

查询多条数据: func (db *DB) Query(query string,args ...interface{}) (*Rows,err)

使用Scan来获取数据row.Scan(&x)

查询举例:

row,err := db.Query("SELECT uid,username,departname,created FROM userinfo")
	if err != nil {
		fmt.Println("查询有误")
		return
	}
	datas := make([]User,0)
	for row.Next(){
		var uid int
		var username,departname,created string
		if err := row.Scan(&uid,&username,&departname,&created);err!=nil {
			fmt.Println("获取失败")
		}
		user := User{uid,username,departname,created}
		datas = append(datas,user)
	}
  • 事务

事务操作通过三个方法来实现:

Begin()开启事务,Commit()提交事务,Rollback()回滚事务。

示例:

db,_ := sql.Open("mysql","root:200010@tcp(127.0.0.1:3306)/mytest?charset=utf8")
	//开启事务
	tx,_ := db.Begin()
	var aff1,aff2 int64 = 0,0
	result1,_ := tx.Exec("UPDATE account SET money=1000 WHERE id=?",1)
	result2,_ := tx.Exec("UPDATE account SET money=3000 WHERE id=?",2)
	if result1 != nil {
		aff1,_ = result1.RowsAffected()
	}
	if result2 != nil {
		aff2,_ = result2.RowsAffected()
	}
	fmt.Printf("%d,%d",aff1,aff2)
	if aff1 == 1 && aff2 == 1 {
		tx.Commit() //提交事务
		fmt.Println("操作成功")
	}else{
		tx.Rollback()
		fmt.Println("操作失败,回滚数据")
	}

开启一个事务后,一个TX会在整个生命周期中保存一个连接,然后调用commit()或Rollback()的时候释放掉。

  • sqlx扩展包

sqlx在database/sql上加了很多扩展

连接数据库:

var Db *sqlx.DB
db,err := sqlx.Open("mysql","username:password@tcp(ip:port)/database?charset=utf8")

实现将获取的数据直接转换结构体实现:
Get(dest interface{},.....)error

Select(dest interface{},....)error

GET和Select

这两个方法内部封装了StructScan进行转化,GET用于获取单个结果然后Scan,Select用来获取切片。

var users []User
Db.Select(&users,"SELECT uid,username,departname,created FROM userinfo")

查询的结果将直接村粗在users[]切片中

database/sql接口使用

上一篇:MySQL事务


下一篇:将mysql数据从Windows迁移到Linux中