• Golang:go1.18.2 windows/amd64
  • github.com/go-sql-driver/mysql:1.6.0

1. 简介

当我们想执行一些mysql语句同时需要获得返回值时(例如SELECT),可以使用 database/sql 包里的 Query 方法;如果不需要获取返回值(例如INSERT,DELETE,UPDATE),可以使用 Exec 方法

2. 准备

2.1 如果您当前环境没有mysql,建议使用容器方式部署,可参考我之前的文章 【Golang | Database】利用database/sql访问容器化的MySQL
2.2 使用 go get github.com/go-sql-driver/mysql 下载mysql驱动,用作插件注册
2.3 新建一个数据库gosql

mysql> create database gosql;
Query OK, 1 row affected (0.00 sec)
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| gosql              |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)
mysql>

3. 示例

3.1 连接数据库gosql

导入database/sqlgithub.com/go-sql-driver/mysql,并使用sql.Open建立与数据库gosql的连接

import (
	"database/sql"
	_ "github.com/go-sql-driver/mysql"
// 此处192.168.67.92是容器所在主机的ip,1234是容器在主机上的映射端口
// docker run --name mysql -d -p 1234:3306 -e MYSQL_ROOT_PASSWORD=root docker.io/mysql:latest
db, err := sql.Open("mysql", "root:root@tcp(192.168.67.92:1234)/gosql")
if err != nil {
	log.Panic(err)
// 使用Ping判断连接是否正常
if err := db.Ping(); err != nil {
	log.Panic(err)

3.2 使用Exec新建一个表users,并插入两条记录

如果直接用SQL语句新建一个table,形如:

CREATE TABLE users (
    id INT AUTO_INCREMENT,
    username TEXT NOT NULL,
    password TEXT NOT NULL,
    created_at DATETIME,
    PRIMARY KEY (id)

如果用go语句来新建table,可以使用Exec方法

	query := `
	CREATE TABLE users (
	   id INT AUTO_INCREMENT,
	   username TEXT NOT NULL,
	   password TEXT NOT NULL,
	   created_at DATETIME,
	   PRIMARY KEY (id)
	_, err = db.Exec(query)
	if err != nil {
		log.Panic(err)

插入两个user记录

import "time"
_, err = db.Exec(`INSERT INTO users (username, password, created_at) VALUES (?, ?, ?)`, "foo", "foo", time.Now())
result, err := db.Exec(`INSERT INTO users (username, password, created_at) VALUES (?, ?, ?)`, "bar", "bar", time.Now())

注:返回值result是一个接口,有两个方法LastInsertId() (int64, error)(一般等于"auto increment"属性列的值)RowsAffected() (int64, error)(执行update, insert, or delete等操作后影响的行数)

3.3 使用Query获取多行记录

使用Query方法获取多行记录,并使用Scan方法将需要的值保存到变量中

	rows, _ := db.Query("select id, username from users")
	for rows.Next() {
		var name string
		var id int
		rows.Scan(&id, &name)
		fmt.Printf("id=%d的用户名是:%s\n", id, name)

3.4 使用QueryRow获取单行记录

	// 单行指定查询,获取id=1的username
	var nameSpecified string
	db.QueryRow("select username from users where id= ?", 1).Scan(&nameSpecified)
	fmt.Printf("指定id=1获取的用户名是:%s\n", nameSpecified)

3.5 完整代码

package main
import (
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"log"
	"time"
func main() {
	// 此处192.168.67.92是容器所在主机的ip,1234是容器在主机上的映射端口
	// docker run --name mysql -d -p 1234:3306 -e MYSQL_ROOT_PASSWORD=root docker.io/mysql:latest
	db, err := sql.Open("mysql", "root:root@tcp(192.168.67.92:1234)/gosql")
	if err != nil {
		log.Panic(err)
	// 使用Ping判断连接是否正常
	if err := db.Ping(); err != nil {
		log.Panic(err)
	defer db.Close()
	// 新建table
	query := `
	CREATE TABLE users (
	   id INT AUTO_INCREMENT,
	   username TEXT NOT NULL,
	   password TEXT NOT NULL,
	   created_at DATETIME,
	   PRIMARY KEY (id)
	_, err = db.Exec(query)
	if err != nil {
		log.Panic(err)
	// 插入两个user记录
	_, err = db.Exec(`INSERT INTO users (username, password, created_at) VALUES (?, ?, ?)`, "foo", "foo", time.Now())
	result, err := db.Exec(`INSERT INTO users (username, password, created_at) VALUES (?, ?, ?)`, "bar", "bar", time.Now())
	lastInsertId, _ := result.LastInsertId()
	rowsAffected, _ := result.RowsAffected()
	fmt.Printf("最后插入的id是:%d\n", lastInsertId)
	fmt.Printf("insert后影响的行数:%d\n", rowsAffected)
	// 多行查询
	rows, _ := db.Query("select id, username from users")
	for rows.Next() {
		var name string
		var id int
		rows.Scan(&id, &name)
		fmt.Printf("id=%d的用户名是:%s\n", id, name)
	// 单行指定查询,获取id=1的username
	var nameSpecified string
	db.QueryRow("select username from users where id= ?", 1).Scan(&nameSpecified)
	fmt.Printf("指定id=1获取的用户名是:%s\n", nameSpecified)

执行后,数据库中内容如下

mysql> select * from users;
+----+----------+----------+---------------------+
| id | username | password | created_at          |
+----+----------+----------+---------------------+
|  1 | foo      | foo      | 2022-06-08 15:59:35 |
|  2 | bar      | bar      | 2022-06-08 15:59:35 |
+----+----------+----------+---------------------+
2 rows in set (0.00 sec)
mysql>

代码的返回值如下

最后插入的id是:2
insert后影响的行数:1      
id=1的用户名是:foo        
id=2的用户名是:bar        
指定id=1获取的用户名是:foo

4. 总结

  • 使用Exec执行不需要返回值的SQL语句,使用Query执行需要返回值的SQL语句
  • 使用ScanQuery获取的返回值保存到变量中
环境:当我们想执行一些mysql语句同时需要获得返回值时(例如SELECT),可以使用包里的方法;如果不需要获取返回值(例如INSERT,DELETE,UPDATE),可以使用方法2.1 如果您当前环境没有mysql,建议使用容器方式部署,可参考我之前的文章【Golang | Database】利用database/sql访问容器化的MySQL2.2 使用下载mysql驱动,用作插件注册2.3 新建一个数据库gosql3. 示例3.1 连接数据库gosql导入和,并使用建立与数据库gosql的连接 golang的”database/sql”是操作数据库时常用的,这个定义了一些sql操作的接口,具体的实现还需要不同数据库的实现,mysql比较优秀的一个驱动是:github.com/go-sql-driver/mysql,在接口、驱动的设计上”database/sql”的实现非常优秀,对于类似设计有很多值得我们借鉴的地方,比如beego框架cache的实现模式就是借鉴了这个的实现;”database/sql”除了定义接口外还有一个重要的功能:连接池,我们在实现其他网络通信时也可以借鉴其实现。 连接池的作用这里就不再多说了,我们先从一个简单的示例看下”database/sql”怎么 navicat是mysql可视化工具中最棒的,但是,在处理视图的导入导出方面,它是按照视图名称的字母顺序来处理的,若视图存在依赖,在导入过程中就会报错。前面已经用python写了一个,但在使用过程中,遇到xfffd编码,python的pymysql会直接崩溃。发现golang没有这个问题,正好用go重写,来熟悉golang。 一些关键点 map & json,在处理主键与外键信息时,需要用到json数据结构来存储中间结果,因为要灵活处理,在golang中只能用map[string]interface{}来处理。 interface{} 相当于java中的object,能接受任意数 Golang官方并没有提供数据库驱动,但通过database/sql/driver来提供了实现驱动的标准接口。可以在Github上找到很多开源的驱动。 其中go-sql-driver/mysql是一个比较推荐的驱动,其完全支持database/sql接口。 使用这个驱动, 在项目里import进: import ( database/sql _ github.com/go-sql-driver/mysql 在正式使用database/sql之前,首先得明白sql.DB并不代表一个数据库连接,它并不会与数据库建立任何连接,也不会验证参数的合法性,要想知道DSN的合
go-oci8描述符合Go数据库/ sql界面的Golang Oracle数据库驱动程序安装安装Oracle完整客户端或Instant Client:https://www.oracle.com/technetwork/database/data go-oci8描述Golang符合以下条件的Oracle数据库驱动程序Go数据库/ sql界面安装安装Oracle完整客户端或Instant Client:https://www.oracle.com/technetwork/database/database-technologies/instant-client/downloads/index.html安装C / C ++编译器安装pkg -config,编辑软件配置文件oci8.pc(下面的示例),然后将环境变量PKG_CONFIG_PATH设置为oci8.pc文件位置(或者可以使用Go标记noPkgConfig然后设置环境变量 Lightweight and Native Go implementation. No C-bindings, just pure Go Connections over TCP/IPv4, TCP/IPv6, Unix domain sockets or Automatic handling of broken connections Automatic Connection Pooling (by database/sql package) Supports queries larger than 16MB Full support. Intelligent LONG DATA handling in prepared statements Secure LOAD
在项目中我们通常可能会使用database/sql连接MySQL数据库。本文借助使用sqlx实现批量插入数据的例子,介绍sqlx中可能被你忽视了的sqlx.In和DB.NamedExec方法。 31.1 sqlx介绍 在项目中我们通常可能会使用database/sql连接MySQL数据库sqlx可以认为是Go语言内置database/sql的超集,它在优秀的内置database/sql基础上提供了一组扩展。这些扩展中除了大家常用来查询的Get(dest interface{}, ...) error Golang 提供了database/sql用于对SQL数据库的访问, 作为操作数据库的入口对象sql.DB, 主要为我们提供了两个重要的功能: •sql.DB 通过数据库驱动为我们提供管理底层数据库连接的打开和关闭操作. •sql.DB 为我们管理数据库连接池 需要注意的是,sql.DB表示操作数据库的抽象访问接口,而非一个数据库连接对象;它可以根据driver打开关闭数据库连接,管理连接池。正在使用的连接被标记为繁忙,用完后回到连接池等待下次使用。所以,如果你没有把连接释放回连接池,会导致过多连接使系统资源耗尽。 Golang操作mysql简介 Golang操作mysql数据库
golang.org/x放到了https://github.com/golang/text中,下载时需要先在本地建立golang.org/x的目录后,再下载。 mkdir -p golang.org/x git clone https://github.com/golang/text.git go get github.com/golang/text后将移到x目录 以上这篇下载golang.org/x操作方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持软件开发网。 您可能感兴趣的文章:go 下载非标准库(
Go-MySQL-Driver GoMySQL-Driver数据库/ sql软件的功能要求安装用法DSN(数据源名称)密码协议地址参数示例Go-MySQL-Driver GoMySQL-Driver数据库/ sql软件的功能要求安装用法DSN (数据源名称)密码协议地址参数示例连接池和超时上下文。上下文支持ColumnType支持LOAD DATA LOCAL INFILE支持时间。时间支持Unicode支持测试/开发许可功能轻巧且快速的Native Go实现。 没有C绑定,只有通过TCP / IPv4,TCP / IPv6,Unix域套接字或cus的纯Go连接
本文记录了我在实际工作中关于数据库操作上一些小经验,也是新手入门golang时我认为一定会碰到问题,没有什么高大上的东西,所以希望能抛砖引玉,也算是对这个问题的一次总结。 其实我也是一个新手,机缘巧合几个月前开始做golang开发,以前一直是以.NET技术栈为主,文章如有错误不吝指正。 访问数据库 相信大家第一次碰到这个问题的时候应该和我一样,去网上找个例子参考一下。没错,这样的例子...
go.org/x是Go语言官方提供的一个扩展集合,用于收集社区维护的扩展和实验性的功能。这些和功能没有正式发布和支持,但它们可能含有用的实验性功能和社区维护的扩展。 这些扩展和实验性功能通常被认为是不稳定的,因为它们可能会在未来的版本中发生变化或被删除。因此,如果你在你的应用程序中使用这些或功能,你需要自己承担风险,并且需要根据官方文档进行更新和维护。 如果你想要使用这些和功能,你可以通过导入它们来使用它们。例如,如果你想要使用"go.crypto",你可以在你的代码中添加以下导入语句: ```go import "golang.org/x/crypto" 你可以在Go语言官方网站的"x"页面中找到完整的扩展列表,以及每个的文档和说明。