go 操作mysql

53 篇文章 0 订阅
27 篇文章 0 订阅

go-sql-driver/mysql

Go使用SQL与类SQL数据库的惯例是通过标准库database/sql。这是一个对关系型数据库的通用抽象,它提供了标准的、轻量的、面向行的接口。Go本身不提供具体数据库驱动,只提供驱动接口和管理,要使用数据库,除了database/sql包本身,还需要引入想使用的特定数据库驱动。

现推荐一个我在项目中用到的驱动:

https://github.com/go-sql-driver/mysql

特征

  • 轻巧快速
  • Native Go实现。没有C-bindings,只是纯粹的Go
  • 通过TCP / IPv4,TCP / IPv6,Unix域套接字或自定义协议进行连接
  • 自动处理断开的连接
  • 自动连接池*(通过database / sql包)*
  • 支持大于16MB的查询
  • 全力sql.RawBytes支持。
  • LONG DATA准备好的报表中的智能处理
  • LOAD DATA LOCAL INFILE通过文件白名单和io.Reader支持提供安全支持
  • 可选的time.Time解析
  • 可选的占位符插值

要求

  • 去1.8或更高。我们的目标是支持Go的3个最新版本。
  • MySQL(4.1 +),MariaDB,Percona Server,Google CloudSQL或Sphinx(2.2.3+)

安装

使用shell中的go工具将包简单地安装到$ GOPATH

$ go get -u github.com/go-sql-driver/mysql

确保Git已安装在您的计算机和系统中PATH

用法

使用sql.Open方法会创建一个数据库连接池db。这个db不是数据库连接,它是一个连接池,只有当真正数据库通信的时候才创建连接。例如这里的db.Ping的操作。db.SetMaxIdleConns(20)db.SetMaxOpenConns(20)分别设置数据库的空闲连接和最大打开连接,即向Mysql服务端发出的所有连接的最大数目。

注意:sql.DB对象是为了长连接而设计的,不要频繁Open()Close()数据库。而应该为每个待访问的数据库创建一个sql.DB实例,并在用完前一直保留它。需要时可将其作为参数传递,或注册为全局对象。

如果没有按照database/sql设计的意图,不把sql.DB当成长期对象来用而频繁开关启停,就可能遭遇各式各样的错误:无法复用和共享连接,耗尽网络资源,由于TCP连接保持在TIME_WAIT状态而间断性的失败等

实例:

package main

import (
   "database/sql"
   _ "github.com/go-sql-driver/mysql"
   "log"
)

func main() {

   db, err := sql.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/testdb?charset=utf8mb4&parseTime=true")
   defer db.Close()
   if err != nil {
      log.Fatalln(err)
   }
   //用于设置闲置的连接数。如果 <= 0, 则没有空闲连接会被保留
   db.SetMaxIdleConns(0)
   //用于设置最大打开的连接数,默认值为0表示不限制。
   db.SetMaxOpenConns(30)
   if err := db.Ping(); err != nil {
      log.Fatalln(err)
   }

}

测试表

CREATE TABLE `user` (
  `id` int(10) NOT NULL COMMENT '主键',
  `name` varchar(100) NOT NULL DEFAULT '' COMMENT '名字',
  `ctime` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

实例:

package main

import (
   "database/sql"
   "fmt"
   _ "github.com/go-sql-driver/mysql"
   "log"
   "time"
)

var db *sql.DB

func main() {
   var err error
   db, err = sql.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/testdb?charset=utf8mb4&parseTime=true&&loc=Local")
   //parseTime是查询结果是否自动解析为时间。
   //loc是MySQL的时区设置。
   defer db.Close()
   if err != nil {
      log.Fatalln(err)
   }
   //用于设置闲置的连接数。如果 <= 0, 则没有空闲连接会被保留
   db.SetMaxIdleConns(0)
   //用于设置最大打开的连接数,默认值为0表示不限制。
   db.SetMaxOpenConns(30)
   if err := db.Ping(); err != nil {
      log.Fatalln(err)
   }
   //插入
   insert()
   //更新
   update()
   //查询
   query()
   //删除
   delete()
}
func insert() {
   tx, err := db.Begin()
   if err != nil {
      return
   }
   ctime := time.Now().Unix()
   defer tx.Rollback()
   stmt, err := tx.Prepare("INSERT INTO user (name,ctime) VALUES (?,?)")
   if err != nil {
      return
   }
   rs, err := stmt.Exec("李四", ctime)
   if err != nil {
      return
   }
   err = tx.Commit()
   if err != nil {
      return
   }
   id, err := rs.LastInsertId()
   fmt.Println(id)
   defer stmt.Close() //runs here!
   return
}
func update() {
   tx, err := db.Begin()
   if err != nil {
      return
   }
   defer tx.Rollback()
   stmt, err := tx.Prepare("UPDATE user SET name=?  WHERE id=?")
   if err != nil {
      return
   }
   _, err = stmt.Exec("zhangsan", 1)
   if err != nil {
      return
   }
   err = tx.Commit()
   if err != nil {
      return
   }
   defer stmt.Close()
   return
}
func query() {
   rows, err := db.Query("SELECT id,name,ctime FROM user  ")
   defer rows.Close()
   if err != nil {
      return
   }
   for rows.Next() {
      var id, ctime int64
      var name string
      rows.Scan(&id, &name, &ctime)
      fmt.Println(id, name, ctime)
   }
   if err = rows.Err(); err != nil {
      return
   }
   return
}
func delete() {
   tx, err := db.Begin()
   if err != nil {
      return
   }
   defer tx.Rollback()
   stmt, err := tx.Prepare("DELETE FROM user  WHERE id=?")
   if err != nil {
      return
   }
   _, err = stmt.Exec(1)
   if err != nil {
      return
   }
   err = tx.Commit()
   if err != nil {
      return
   }
   defer stmt.Close()
   return
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值