golang数据库操作初体验
程序员文章站
2023-09-28 18:57:37
在golang中,提供了标准的数据库接口database/sql包,做过数据库开发的应该知道,不同的数据库有不同的数据库驱动。比如mysql等,我们可以去找 这里找自已需要的驱动,这里我就以mysql的驱动为例,用的是go sql driver这个。 安装 直接执行go get,然后会下载到你的$G ......
在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&...¶mn=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{} }
以上只是一些基本的数据库操作,像连接池等还没有做,这个等后续看了再去写。
下一篇: 阿里云esc 安装 mysql8.0