首页 > 数据库 >go语言mysql驱动

go语言mysql驱动

时间:2023-07-23 13:12:02浏览次数:33  
标签:Err err 数据库 mysql sql go 驱动

连接数据库是典型的CS编程,服务器端被动等待客户端建立TCP连接,并在此连接上进行特定的应用层 协议。但一般用户并不需要了解这些细节,这些都被打包到了驱动库当中,只需要简单的调用打开就可以指定协议连接到指定的数据库。

数据库的种类和产品太多,协议太多,Go官方很难提供针对不同数据库的驱动程序,往往由各数据库官 方或第三方给出不同开发语言的驱动库。但是,为了Go语言可以提前定义操作一个数据库的所有行为 (接口)和数据(结构体)的规范,这些定义在database/sql下。

MySQL驱动

  • https://github.com/go-sql-driver/mysql 支持 database/sql,使用广泛
  • https://github.com/ziutek/mymysql 支持 database/sql,支持自定义接口
  • https://github.com/Philio/GoMySQL 不支持 database/sql,支持自定义接口

注册驱动:

// github.com/go-sql-driver/mysql/mysql/driver.go 代码中有注册驱动
func init() { // 83行
 sql.Register("mysql", &MySQLDriver{})
}

连接

DSN例子 https://github.com/go-sql-driver/mysql#examples

 使用示例:

package logg

import (
    "io"

    "github.com/rs/zerolog"
)

func InfoLog(out io.Writer) zerolog.Logger {
    zerolog.TimeFieldFormat = "2006-01-02 15:04:05.000 +0800"
    logger := zerolog.New(out).With().Timestamp().Logger().Level(1)
    return logger
}
logg/logg.go
package main

import (
    "cabel/logg"
    "database/sql" // 接口定义库
    "fmt"
    "os"
    "time"

    _ "github.com/go-sql-driver/mysql" // 具体实现,可以不调用,加载一下就行,在init中注册mysql这个名字
    "github.com/rs/zerolog/log"
)

var db0 *sql.DB

func init() {
    connstr := "gopher:123456@tcp(172.0.0.1:3306)/gopher"
    var err error
    // 接口库的方法,指定使用的数据库种类,名称就要找到该名称对应的数据库的驱动
    db0, err = sql.Open("mysql", connstr)
    if err != nil {
        log.Err(err).Send()
    }
    db0.SetConnMaxIdleTime(time.Second * 30) // 连接超时时间
    // 数据库连接最大生命周期,用于指定数据库连接在被重用之前的最大存活时间
    db0.SetConnMaxLifetime(time.Second * 60)
    db0.SetMaxOpenConns(100) // 最大连接数,默认0为不限制
    db0.SetMaxIdleConns(10)  // 空闲连接数
}

// 定义结构体,结构体中字段与数据库中字段顺序最好一一对应
type Emp struct {
    emp_no                            int
    birth_date, first_name, last_name string
    gender                            int
    hire_date                         string
}

func main() {
    f0, err := os.OpenFile("logs/info.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
    if err != nil {
        log.Err(err).Send()
    }
    defer f0.Close()
    f1, err := os.OpenFile("logs/error.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
    if err != nil {
        log.Err(err).Caller().Send()
    }
    defer f1.Close()
    l0 := logg.InfoLog(f0)
    l1 := logg.InfoLog(f1)
    err = db0.Ping()
    if err == nil {
        l0.Info().Msg("数据库初始化成功")
    } else {
        l1.Err(err).Msg("数据库连接失败")
    }

    // 单行查询
    row := db0.QueryRow("select * from employees where emp_no > ? limit 1", 10007)
    if row.Err() != nil {
        l1.Err(row.Err()).Caller().Msg("数据库查询失败")
    }
    var r Emp
    row.Scan(&r.emp_no, &r.birth_date, &r.first_name,
        &r.last_name, &r.gender, &r.hire_date)
    fmt.Println(r)

    // 预编译查询,多行查询
    stmt, err := db0.Prepare("select * from employees where emp_no > ? and emp_no < ? order by emp_no limit 3")
    if err != nil {
        l1.Err(err).Caller().Msg("预编译查询语句失败")
    }
    rows, err := stmt.Query("10003", 10008)
    if err != nil {
        l1.Err(err).Caller().Msg("查询失败")
    }
    // Next来遍历,每一次,rows都指向当前行
    for rows.Next() {
        err = rows.Scan(&r.emp_no, &r.birth_date, &r.first_name,
            &r.last_name, &r.gender, &r.hire_date)
        if err != nil {
            l1.Err(err).Msg("填充失败")
        }
        fmt.Println(r)
        t0, err := time.Parse("2006-01-02", r.birth_date) // 时间解析
        if err != nil {
            l1.Err(err).Send()
        }
        fmt.Printf("%T %[1]v\n", t0)
    }
}
main.go

返回结果:

使用db.Prepare预编译并使用参数化查询

  • 对预编译的SQL语句进行缓存,省去了每次解析优化该SQL语句的过程
  • 防止注入攻击
  • 使用返回的sql.Stmt操作数据库

标签:Err,err,数据库,mysql,sql,go,驱动
From: https://www.cnblogs.com/caibao666/p/17574899.html

相关文章

  • mysql auto_increment怎么删除
    MySQL中的auto_increment如何删除在MySQL中,auto_increment是一个非常有用的功能,它允许我们在插入数据时自动为表的主键字段生成唯一的递增值。然而,有时候我们可能需要删除表中的某些数据行,这就会导致auto_increment值出现断层。本文将介绍如何在MySQL中删除数据行时保持auto_incre......
  • mysql rpm包选择
    MySQLRPM包选择MySQL是一种流行的关系型数据库管理系统,被广泛用于开发和生产环境中。在Linux系统上安装MySQL,我们可以选择使用RPM包进行安装。RPM(RedHatPackageManager)是一种软件包管理系统,用于在RedHat系列的Linux发行版上进行软件安装、升级和卸载。本文将介绍如何选择适......
  • mysql arm dockerfile
    MySQLonARMwithDockerfileIntroductionWiththeincreasingpopularityofARM-baseddevices,itisbecomingmorecommontorunapplicationsandservicesonARMarchitecture.OnesuchapplicationisMySQL,apowerfulandwidelyusedrelationaldatabasem......
  • mysql redo_log_buffer_size
    MySQLredo_log_buffer_size详解在MySQL中,redolog是一种用于保证数据持久性的机制。当我们进行数据修改时,MySQL会将这些修改操作记录到redolog中,以便在系统崩溃或重启后,可以使用redolog来恢复数据的一致性。redolog的大小对于系统的性能和可靠性都有着重要的影响,本文将详细介......
  • mysql and 和 &&
    mysql和&&的区别在MySQL中,我们经常会使用AND和&&这两个操作符来组合多个条件。尽管它们都用于连接多个条件,但它们在使用时有一些区别。本文将介绍mysqland和&&的区别,并提供一些代码示例来帮助理解。AND操作符在MySQL中,AND是一个逻辑操作符,用于在WHERE子句中组......
  • mysql rank
    实现MySQLRank的流程实现MySQLRank的过程可以分为以下几个步骤:创建数据表导入数据编写查询语句添加Rank字段计算Rank值查询结果下面我会逐步介绍每个步骤需要做什么,并给出相应的代码说明。1.创建数据表首先,你需要创建一个包含需要排序的字段的数据表。假设......
  • Django:admin后台汉化问题
    Django:admin后台汉化问题1、设置admin站点中文显示,即汉化admin后台管理站点。方法一:修改settings文件LANGUAGE_CODE='en-us'TIME_ZONE='UTC'更改为:LANGUAGE_CODE='zh-Hans'TIME_ZONE='Asia/Shanghai'方法二:添加中间件(注意:中间件是有顺序的,不要随意更改。......
  • mysql执行execute immediate
    实现"mysql执行executeimmediate"的步骤对于刚入行的小白来说,学会如何使用"mysql执行executeimmediate"可能会有些困惑。在本文中,我将向你展示整个实现过程的步骤,并提供每一步所需的代码和注释。步骤概述下面的表格演示了实现"mysql执行executeimmediate"的步骤概述。步......
  • mysql增加两列,并往里面添加数据
    MySQL增加两列,并往里面添加数据在MySQL数据库中,我们经常需要对表结构进行修改,例如添加新的列。本文将介绍如何使用SQL语句在MySQL中添加两列,并向这两列中添加数据。1.创建示例表首先,我们需要创建一个示例表,作为演示的基础。以下是一个简单的表结构:CREATETABLEstudents(i......
  • Go-GoFiber框架
    简介中文文档Fiber 是一个受到 Express 启发的 Web框架,基于使用 Go 语言编写的最快的HTTP引擎 Fasthttp 构建。旨在通过零内存分配和高性能服务,使快速开发更加简便。安装goget-ugithub.com/gofiber/fiber/v2packagemainimport"github.com/gofiber/fibe......