在golang中,提供了标准的数据库接口database/sql包,做过数据库开发的应该知道,不同的数据库有不同的数据库驱动。比如mysql等,我们可以去找 https://golang.org/s/sqldrivers 这里找自已需要的驱动,这里我就以mysql的驱动为例,用的是go-sql-driver这个。

安装

直接执行go get,然后会下载到你的$GOPATH中,如果用的go mod也一样,只不过下载的路径不一样。

go get -u github.com/go-sql-driver/mysql

导入驱动

database/sql这个包是要导入的,然后导入go-sql-driver,包前面的 “_"表示执行包的init函数,函数init里面直接将自已注册到database/sql包中,然后就能用这个包里面的方法访问数据库了。

import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
) func init() {
sql.Register("mysql", &MySQLDriver{})
}

连接数据库

type dbObj struct {
db *sql.DB
} func (d *dbObj) Open() *sql.DB{
var err error
d.db, err = sql.Open("mysql", "lc:111111@/test")
if err != nil {
panic(err)
}
return d.db
}

使用 sql.Open 来连接数据库,但是这个只是返回一个数据库的抽象实例,并没有真正的连接到数据库中,在后续的对数据库的操作中才会真正去网络连接,如果要马上验证,可以用 db.ping().

sql.Open的签名如下:

func Open(driverName, dataSourceName string) (*DB, error) {

它接受两个参数:

  • driverName就是我们在init函数注册的那个名字
  • dataSourceName为数据库链接dsn,格式为 [username[:password]@][protocol[(address)]]/dbname[?param1=value1&...&paramN=valueN]

示例

来点基本的CURD操作,还是挺简单的。

package db

import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
"log"
) type userInfo struct {
id int
orgcode string
name string
version int
} type dbObj struct {
db *sql.DB
} func (d *dbObj) Open() *sql.DB{
var err error
d.db, err = sql.Open("mysql", "lc:111111@/test")
if err != nil {
panic(err)
}
return d.db
}
func (d *dbObj) Close(){
d.Close()
} func SelectAll() {
dbc :=&dbObj{}
db := dbc.Open()
defer db.Close() stmt ,_ :=db.Prepare("SELECT orgcode,`name` FROM userinfo WHERE id > ?")
rows, _ :=stmt.Query(0) //query为多行
defer rows.Close()
user :=&userInfo{} for rows.Next() {
err :=rows.Scan(&user.orgcode,&user.name)
if err != nil {
log.Fatal(err)
}
fmt.Println(user.orgcode , ":", user.name)
}
} func Select() {
dbc :=&dbObj{}
db := dbc.Open()
defer db.Close() stmt ,_ :=db.Prepare("SELECT orgcode,`name` FROM userinfo WHERE ID= ?")
rows :=stmt.QueryRow(1008) //QueryRow为单行 user :=&userInfo{} err :=rows.Scan(&user.orgcode,&user.name)
if err != nil {
log.Fatal(err)
}
fmt.Println(user.orgcode , ":", user.name) } func Insert() {
dbc :=&dbObj{}
db := dbc.Open()
defer db.Close() result, err :=db.Exec("INSERT userinfo (orgcode,imei,`name`) VALUE(?,?,?)","cccc",1009,"cccc")
if err != nil {
log.Fatal(err)
}
rowsaffected,err := result.RowsAffected()
if err != nil {
fmt.Printf("获取受影响行数失败,err:%v",err)
return
}
fmt.Println("受影响行数:" ,rowsaffected )
} func Delete() {
dbc :=&dbObj{}
db := dbc.Open()
defer db.Close() result, err :=db.Exec("DELETE FROM userinfo WHERE id=?",1009)
if err != nil {
log.Fatal(err)
}
rowsaffected,err := result.RowsAffected()
if err != nil {
fmt.Printf("获取受影响行数失败,err:%v",err)
return
}
fmt.Println("受影响行数:" ,rowsaffected )
} func Update() {
dbc :=&dbObj{}
db := dbc.Open()
defer db.Close() result, err :=db.Exec("UPDATE userinfo SET `name`= ? WHERE id=?", "lcbbb",1008)
if err != nil {
log.Fatal(err)
} rowsaffected,err := result.RowsAffected()
if err != nil {
fmt.Printf("获取受影响行数失败,err:%v",err)
return
}
fmt.Println("受影响行数:" ,rowsaffected )
} func Transaction() {
dbc :=&dbObj{}
db := dbc.Open()
defer db.Close() tx ,_:=db.Begin()
tx.Exec("UPDATE userinfo SET `name`= ? WHERE id=?", "lcaaa",1007)
result, err :=tx.Exec("UPDATE userinfo SET `name`= ? WHERE id=?", "lcbbb",1008)
if err != nil {
log.Fatal(err)
}
tx.Commit() //提交事务
rowsaffected,err := result.RowsAffected()
if err != nil {
fmt.Printf("获取受影响行数失败,err:%v",err)
return
}
fmt.Println("受影响行数:" ,rowsaffected )
} func ConcurrenceUpdate() {
dbc :=&dbObj{}
db := dbc.Open()
defer db.Close() getone :=func(db *sql.DB,id int) *userInfo{ stmt ,_ :=db.Prepare("SELECT orgcode,`name`,version FROM userinfo WHERE ID= ?")
rows :=stmt.QueryRow(id) // user :=&userInfo{} err :=rows.Scan(&user.orgcode,&user.name, &user.version)
if err != nil {
log.Fatal(err)
} return user } udateone :=func(db *sql.DB,name string,id int,version int){
result, err :=db.Exec("UPDATE userinfo SET `name`= ?, version=version+1 WHERE id=? AND version=?", name,id,version)
if err != nil {
log.Fatal(err)
} rowsaffected,err := result.RowsAffected()
if err != nil {
fmt.Printf("并发更新获取受影响行数失败,err:%v",err)
return
}
fmt.Println("并发更新受影响行数:" ,rowsaffected )
} num :=10
for i:=0; i<num ;i++{
go func(){
u :=getone(db,1008)
fmt.Printf("获取数据:%v\r\n",u)
udateone(db,"lc并发更新测试", 1008,u.version)
}()
} select{}
}

以上只是一些基本的数据库操作,像连接池等还没有做,这个等后续看了再去写。

最新文章

  1. class.forname()用法 转
  2. android中文件操作的四种枚举
  3. Python - DICT 字典排序 - OrderedDict
  4. NSStream
  5. java 高精度
  6. 我用dedecms有感
  7. ###Maintainable C++
  8. Delphi GDI+ Library
  9. leetcode面试准备: Substring with Concatenation of All Words
  10. 综合查询员工和datetime.now和datetime.today区别
  11. 《windows程序设计》学习_3.4:实现雷区翻转
  12. python 一个包中的文件调用另外一个包文件 实例
  13. 用pip下载的python模块怎么在PyCharm中引入报错
  14. (.NET高级课程笔记)反射总结
  15. MyBatis-day2
  16. VSCode插件开发全攻略(九)常用API总结
  17. Java开发人员必须掌握的两个Linux魔法工具(四)
  18. mysql常用压测工具
  19. 图片训练:使用卷积神经网络(CNN)识别手写数字
  20. layer插件学习——icon样式

热门文章

  1. C语言随笔4:指针数组、数组指针
  2. ColorPix——到目前为止最好用的屏幕取色器
  3. linux搭建常用命令
  4. MySQL 避免使用字符串类型作为标识列
  5. py1
  6. P&amp;R 5
  7. js相关--浅拷贝和深拷贝
  8. hackinglab-脚本关1——key又又找不到了
  9. go语言下载及安装
  10. 计算机网络 --- IP 地址