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&...¶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{}
}
以上只是一些基本的数据库操作,像连接池等还没有做,这个等后续看了再去写。
golang数据库操作初体验的更多相关文章
- Golang - 数据库操作
1. 下载安装包 go get github.com/Go-SQL-Driver/MySQL go install github.com/Go-SQL-Driver/MySQL 2. 连接池 This ...
- 第13章:MongoDB-聚合操作--初体验
①MongoDB 的聚合功能 MongoDB 的聚合功能,聚合操作主要用于对数据的批量处理,往往将记录按条件分组以后,然后再进行一系列操作,例如,求最大值.最小值.平均值,求和等操作. 聚合操作还能够 ...
- Golang后台开发初体验
转自:http://blog.csdn.net/cszhouwei/article/details/37740277 补充反馈 slice 既然聊到slice,就不得不提它的近亲array,这里不太想 ...
- Yii框架2.0 数据库操作初接触
Yii2.0和Yii1.1版本的变动还是挺多的,我发现配置文件有许多不同,Yii1.1版本里有个main.php 好多信息是在这里配置的,比如默认控制器,数据库连接信息:Yii的数据库配置被单独拿出来 ...
- 分布式NoSQL数据库MongoDB初体验-v5.0.5
概述 定义 MongoDB官网 https://www.mongodb.com/ 社区版最新版本5.0,其中5.2版本很快也要面世了 MongoDB GitHub源码 https://github.c ...
- Spring Data JPA应用之常规CRUD操作初体验
基于对于一个陌生的技术框架,先使用后研究其实现的原则(大部分本人如此,就如小朋友学习骑自行车不会先研究自行车是怎么动起来的而是先骑会了),对于Spring JPA先通过案例实践其怎么用吧. 用之前得明 ...
- Golang访问Redis初体验
go语言的client在redis官网上有很多l客户端,个人感觉redigo使用起来更人性化,重要的是源代码结构很清晰,重要的是支持管道.发布和订阅.连接池等等,所以我选择redigo作为尝试. 1. ...
- hibernate--CRUD初体验
hibernate的crud操作初体验. 看具体实例 package com.fuwh.model; import javax.persistence.Column; import javax.per ...
- SSH初体验系列--Hibernate--2--crud操作
Ok,今天比较详细的学习一下hibernate的C(create).R(read).U(update).D(delete) 相关api... 前言 Session: 是Hibernate持久化操作的基 ...
随机推荐
- 记一次if控制器的使用
1.添加if控制器 2.输入判断条件:常见的就是某个变量是不是等于某个值 3.或者用函数助手中的函数 每个版本jmeter函数助手的入口不同,我的直接在菜单上: 选择__jexl3,输入判断条件,点击 ...
- 8.14-T1村通网(pupil)
题目大意 要建设一个村庄的网络 有两种操作可选 1.给中国移动交宽带费,直接连网,花费为 A. 2.向另外一座有网的建筑,安装共享网线,花费为 B×两者曼哈顿距离. 题解 显然的最小生成树的题 见 ...
- 7_6 带宽(UVa140)<回溯法:最优性剪枝>
给定一个图(V,E),其中V为顶点的集合,E为边的集合,属于VxV.给定V中元素的一种排序,那么顶点v的带宽定义如下:在当前给定的排序中,与v距离最远的且与v有边相连的顶点与v的距离.给定排序的带宽定 ...
- XSS 3
打开第三题然后会看到 然后进行一下添加数据 然后会发现数据被添加到 value=""双引号中然后然后我们会想到提前闭合 代码 然后进行编码 然后就可以通过了 此题与xss 2类似 ...
- Java进阶学习(5)之设计原则(上)
设计原则 城堡游戏 扩展 字符串被分割 String line = in.nextLine(); String[] words = line.split(" "); 消除代码复制 ...
- JSP技术(二)
参考网址:https://blog.csdn.net/king_cannon_fodder/article/details/79835463 (1)JSP隐式对象(9个内置对象) Servlet容器会 ...
- Codeforces Round #614 (Div. 2)E(思维,构造,DP)
构造边权,从0开始给边赋值,初始选取一条边权为0,每次赋值的贡献为这一条链两侧的结点(包含链的端点)个数之积,下一次赋值以当前链其一端点续一条边,边权为上次赋的值+1.先DFS找到点的组合这条链两侧结 ...
- 转载:WAV header
转自:http://www.cnblogs.com/CoderTian/p/6657844.html WAV为微软公司(Microsoft)开发的一种声音文件格式,它符合RIFF(Resource I ...
- C#中字符串常用方法
string str = "123@163.com"; int index = str.IndexOf('@'); // 返回3 从左向右第一个@ int index = str ...
- Java开发中模拟接口工具moco的使用
场景 在开发中需要依赖一些接口,比如需要请求一个返回Json数据的接口,但是返回Json数据的接口要么是没搭建,要么是交互比较复杂. 此时,就可以使用moco来模拟接口返回接口数据,以便开发和测试工作 ...