在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{}
}

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

golang数据库操作初体验的更多相关文章

  1. Golang - 数据库操作

    1. 下载安装包 go get github.com/Go-SQL-Driver/MySQL go install github.com/Go-SQL-Driver/MySQL 2. 连接池 This ...

  2. 第13章:MongoDB-聚合操作--初体验

    ①MongoDB 的聚合功能 MongoDB 的聚合功能,聚合操作主要用于对数据的批量处理,往往将记录按条件分组以后,然后再进行一系列操作,例如,求最大值.最小值.平均值,求和等操作. 聚合操作还能够 ...

  3. Golang后台开发初体验

    转自:http://blog.csdn.net/cszhouwei/article/details/37740277 补充反馈 slice 既然聊到slice,就不得不提它的近亲array,这里不太想 ...

  4. Yii框架2.0 数据库操作初接触

    Yii2.0和Yii1.1版本的变动还是挺多的,我发现配置文件有许多不同,Yii1.1版本里有个main.php 好多信息是在这里配置的,比如默认控制器,数据库连接信息:Yii的数据库配置被单独拿出来 ...

  5. 分布式NoSQL数据库MongoDB初体验-v5.0.5

    概述 定义 MongoDB官网 https://www.mongodb.com/ 社区版最新版本5.0,其中5.2版本很快也要面世了 MongoDB GitHub源码 https://github.c ...

  6. Spring Data JPA应用之常规CRUD操作初体验

    基于对于一个陌生的技术框架,先使用后研究其实现的原则(大部分本人如此,就如小朋友学习骑自行车不会先研究自行车是怎么动起来的而是先骑会了),对于Spring JPA先通过案例实践其怎么用吧. 用之前得明 ...

  7. Golang访问Redis初体验

    go语言的client在redis官网上有很多l客户端,个人感觉redigo使用起来更人性化,重要的是源代码结构很清晰,重要的是支持管道.发布和订阅.连接池等等,所以我选择redigo作为尝试. 1. ...

  8. hibernate--CRUD初体验

    hibernate的crud操作初体验. 看具体实例 package com.fuwh.model; import javax.persistence.Column; import javax.per ...

  9. SSH初体验系列--Hibernate--2--crud操作

    Ok,今天比较详细的学习一下hibernate的C(create).R(read).U(update).D(delete) 相关api... 前言 Session: 是Hibernate持久化操作的基 ...

随机推荐

  1. VIM学习(转)

    原文:http://www.cnblogs.com/nerxious/archive/2012/12/21/2827303.html 断断续续的使用VIM也一年了,会的始终都是那么几个命令,效率极低 ...

  2. Sql 中获取年月日时分秒的函数

    getdate():获取系统当前时间 dateadd(datepart,number,date):计算在一个时间的基础上增加一个时间后的新时间值,比如:dateadd(yy,30,getdate()) ...

  3. 【SSH】spring 整合 hibernate

    spring-hibernate-1.2.9.jar applicationContext.xml <bean id="sessionFactory" class=" ...

  4. webRTC中回声消除(AEC)模块编译时aec_rdft.c文件报错:

    webRTC中回声消除(AEC)模块编译时aec_rdft.c文件报错. 原因是: 局部变量ip跟全局变量冲突的问题,可以将局部变量重新命名一下,就可以通过编译了. aec_rdft.c修改以后文件代 ...

  5. opencv python:Canny边缘提取

    Canny是边缘提取算法,在1986年提出的 是一个很好的边缘检测器 Canny算法介绍 非最大信号抑制: 高低阈值连接: example import cv2 as cv import numpy ...

  6. spring 基于xml的申明式AspectH中的后置通知的返回值获取

    spring 基于xml的申明式AspectH中的后置通知的返回值获取 1. 配置文件 <aop:config> <aop:aspect ref="myAspect&quo ...

  7. ZooKeeper下载安装配置-单机版配置

    1,下载地址:http://apache.fayea.com/zookeeper/ 2,检查环境变量(需要确保配置了环境变量): java -version 3,安装配置: (1)解压 tar -zx ...

  8. ZOJ - 3203 Light Bulb(三分)

    题意:灯离地面的高度为$H$,人的身高为$h$,灯离墙的距离为$D$,人站在不同位置,影子的长度不一样,求出影子的最长长度. 思路:设人离灯的距离为$x$,当人走到距离灯长度为$L$时,人在墙上的影子 ...

  9. 用svn客户端checkout时报错RA layer request failed

    用svn客户端checkout时报错: RA layer request failedsvn: Unable to connect to a repository at URL 'https://30 ...

  10. 计算机二级-C语言-对文件的读写操作。链表的定义与赋值。对字符串的遍历和处理。

    //程序填空题:在此程序中,通过定义学生结构体变量,存储了学生的学号,姓名和三门课的成绩.所有学生数据均以二进制方式输出到文件中.函数fun()函数的功能是重写形参filename所指文件中最后一个学 ...