欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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&...&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{}
}

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