- 数据库连接
使用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[]切片中