• golang数据库操作初体验


    在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
    ",u)
    			udateone(db,"lc并发更新测试", 1008,u.version)
    		}()
    	}
    
    	select{}
    }
    

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

  • 相关阅读:
    Xampp 环境问题集合
    linux VI模式下批量修改文件内容
    shell 获取文件名
    shell 遍历所有文件包括子目录
    jmeter java 请求 payload
    [转]postman 官方文档解说
    承上启下——牛腩新闻发布系统总结
    ASP.NET——实现两个下拉框动态联动
    ASP.NET——真假分页
    HTML快速入门
  • 原文地址:https://www.cnblogs.com/smartrui/p/12116042.html
Copyright © 2020-2023  润新知