[TOC]
## 1\. 下载依赖
~~~
go get -u github.com/go-sql-driver/mysql
~~~
## 2\. 使用Mysql驱动
~~~
func Open(driverName, dataSourceName string) (*DB, error)
~~~
Open方法打开一个指定的数据库
driverName为驱动名称,例mysql
dataSourceName为数据库连接信息
返回DB 和 error
demo1
~~~
func main() {
// dsn: Data Source Name
// 用户名为root,密码为123456,数据库为test
dsn := "root:123456@tcp(127.0.0.1:3306)/test"
// Open()方法对dsn的一个格式校验,并没有实际连接到数据库
db, err := sql.Open("mysql", dsn)
if err != nil {
panic(err)
}
defer db.Close()
}
~~~
### **Mysql Demo:**
~~~
// 定义一个全局变量
var db *sql.DB
// 定义初始化mysql的方法
func initMysql() (err error) {
// dsn: Data Source Name
// 用户名为root,密码为123456,数据库为test
dsn := "root:123456@tcp(127.0.0.1:3306)/test"
// Open()方法对dsn的一个格式校验,并没有实际连接到数据库
db, err = sql.Open("mysql", dsn)
if err != nil {
panic(err)
}
// 与数据库建立连接
err = db.Ping()
if err != nil {
fmt.Printf("connect to db failed, err:%v\n", err)
return
}
return
}
func main() {
if err := initMysql(); err != nil {
panic(err)
}
defer db.Close()
fmt.Println("connected to db...")
}
~~~
## 3\. 单行查询
单行查询`db.QueryRow()`执行一次查询,并期望返回最多一行结果(即Row)。QueryRow总是返回非nil的值,直到返回值的Scan方法被调用时,才会返回被延迟的错误。
~~~
func (db *DB) QueryRow(query string, args ...interface{}) *Row
~~~
代码示例:
~~~
// 单行查询
func queryRowDemo() {
// sql语句
sqlStr := "select id, name, age from user where id=?"
var u user
err := db.QueryRow(sqlStr, 1).Scan(&u.id, &u.name, &u.age)
if err != nil {
fmt.Printf("scan failed, err:%v\n", err)
return
}
fmt.Printf("id:%d name:%s age:%d\n", u.id, u.name, u.age)
}
~~~
## 4\. 多行查询
多行查询`db.Query()`执行一次查询,返回多行结果(即Rows),一般用于执行select命令。参数args表示query中的占位参数。
~~~
func (db *DB) Query(query string, args ...interface{}) (*Rows, error)
~~~
代码示例:
~~~
// 多行查询
func queryMultiRowDemo() {
sqlStr := "select id, name, age from user where id > ?"
rows, err := db.Query(sqlStr, 0)
if err != nil {
fmt.Printf("query failed, err:%v\n", err)
return
}
// 关闭rows释放持有的数据库链接
defer rows.Close()
// 循环读取结果集中的数据
for rows.Next() {
var u user
err := rows.Scan(&u.id, &u.name, &u.age)
if err != nil {
fmt.Printf("scan failed, err:%v\n", err)
return
}
fmt.Printf("id:%d name:%s age:%d\n", u.id, u.name, u.age)
}
}
~~~
## 5\. 插入数据
插入、更新和删除操作都使用`Exec`方法。
~~~
func (db *DB) Exec(query string, args ...interface{}) (Result, error)
~~~
Exec执行一次命令(包括查询、删除、更新、插入等),返回的Result是对已执行的SQL命令的总结。参数args表示query中的占位参数。
代码示例:
~~~
// 插入数据
func insertRowDemo(name string, age int) {
sqlStr := "insert into user(name, age) values (?,?)"
result, err := db.Exec(sqlStr, name, age)
if err != nil {
fmt.Printf("insert failed, err:%v\n", err)
return
}
// RowsAffected()方法,表示影响的行数
// num, err := result.RowsAffected()
lastId, err := result.LastInsertId() // 新插入数据的id
if err != nil {
fmt.Printf("get lastinsert ID failed, err:%v\n", err)
return
}
fmt.Printf("insert successfully, the id is %d.\n", lastId)
}
~~~
## 6\. 更新数据
~~~
// 更新数据
func updateRowDemo() {
sqlStr := "update user set age=? where id = ?"
result, err := db.Exec(sqlStr, 23, 1)
if err != nil {
fmt.Printf("update data failed, err:%v\n", err)
return
}
// 操作影响的行数
num, err := result.RowsAffected()
if err != nil {
fmt.Printf("get RowsAffected failed, err:%v\n", err)
return
}
fmt.Printf("update data successfully, %d rows affected\n", num)
}
~~~
## 7\. 删除数据
~~~
// 删除数据
func deleteRowDemo() {
sqlStr := "delete from user where id = ?"
result, err := db.Exec(sqlStr, 3)
if err != nil {
fmt.Printf("delete failed, err:%v\n", err)
return
}
num, err := result.RowsAffected() // 操作影响的行数
if err != nil {
fmt.Printf("get RowsAffected failed, err:%v\n", err)
return
}
fmt.Printf("delete success, affected rows:%d\n", num)
}
~~~
## 8\. Go实现Mysql预处理
为什么要预处理?
1. 优化MySQL服务器重复执行SQL的方法,可以提升服务器性能,提前让服务器编译,一次编译多次执行,节省后续编译的成本。
2. 避免SQL注入问题
`database/sql`中使用下面的`Prepare`方法来实现预处理操作。
~~~
func (db *DB) Prepare(query string) (*Stmt, error)
~~~
~~~
// 预处理
func prepareQueryDemo() {
sqlStr := "select id, name, age from user where id > ?"
stmt, err := db.Prepare(sqlStr)
if err != nil {
fmt.Printf("prepare failed, err:%v\n", err)
return
}
defer stmt.Close()
rows, err := stmt.Query(0)
if err != nil {
fmt.Printf("query failed, err:%v\n", err)
return
}
defer rows.Close()
// 循环读取结果集中的数据
for rows.Next() {
var u user
err := rows.Scan(&u.id, &u.name, &u.age)
if err != nil {
fmt.Printf("scan failed, err:%v\n", err)
return
}
fmt.Printf("id:%d name:%s age:%d\n", u.id, u.name, u.age)
}
}
~~~
## 9\. Go实现Mysql事务
Go语言中使用以下三个方法实现MySQL中的事务操作。
开始事务
~~~
func (db *DB) Begin() (*Tx, error)
~~~
提交事务
~~~
func (tx *Tx) Commit() error
~~~
回滚事务
~~~
func (tx *Tx) Rollback() error
~~~
示例代码
~~~
// 事务操作
func transactionDemo() {
tx, err := db.Begin() // 开启事务
if err != nil {
if tx != nil {
tx.Rollback() // 回滚
}
fmt.Printf("begin trans failed, err:%v\n", err)
return
}
sqlStr1 := "update user set age=30 where id=?"
result1, err := tx.Exec(sqlStr1, 1)
if err != nil {
tx.Rollback() // 回滚
fmt.Printf("exec sql failed, err:%v\n", err)
return
}
num1, err := result1.RowsAffected()
if err != nil {
tx.Rollback() // 回滚
fmt.Printf("exec result.RowsAffected failed, err:%v\n", err)
return
}
sqlStr2 := "update user set age=30 where id=?"
result2, err := tx.Exec(sqlStr2, 2)
if err != nil {
tx.Rollback() // 回滚
fmt.Printf("exec sql failed, err:%v\n", err)
return
}
num2, err := result2.RowsAffected()
if err != nil {
tx.Rollback() // 回滚
fmt.Printf("exec result.RowsAffected failed, err:%v\n", err)
return
}
fmt.Println(num1, num2)
if num1 == 1 && num2 == 1 {
fmt.Println("事务提交啦。。。")
tx.Commit()
} else {
tx.Rollback()
fmt.Println("事务回滚啦。。。")
}
fmt.Println("exec trans success!")
}
~~~
- Golang
- 基础知识
- 基本数据类型
- 运算符
- 变量&常量
- 流程控制
- 数组
- 切片
- string操作
- Map及实现原理
- Go其他
- CLI命令
- Golang内置类型和函数
- init函数和main函数
- 网络编程
- 互联网协议
- socket编程
- 单元测试
- 并发编程
- channel
- 优雅地关闭channel
- Mutex
- GMP原理与调度
- Go Web
- HTTP Server
- gin框架
- 快速入门
- HTML渲染
- JSONP
- Multipart/Urlencoded绑定
- PureJSON
- gin路由
- beego框架
- Bee工具安装
- 配置模块
- Web模块
- 路由
- 数据操作
- Go操作Mysql数据库
- Go操作redis
- mongo-driver
- sqlx库
- 操作etcd
- msgpack
- 网络爬虫
- 获取页面
- 标准库
- IO操作
- 文件操作
- fmt
- 格式化输出
- flag
- log
- time
- strconv
- template
- os
- sync.Mutex
- Context
- 第三方库
- zap库
- viper
- validator参数校验
- GORM
- 基础
- CRUD接口
- INI
- GoFrame
- 快速开始
- 微服务
- go-kit
- gRPC
- Protocol Buffers 语法指南
- go-zero
- 相关名词解释
- 数据结构和算法
- 基础知识
- 链表
- Golang GUI
- fyne基础
- 显示时间
- RabbitMQ-Go
- centos7 安装rabbitmq-server
- RabbitMQ介绍
- 工作队列
- Go设计模式
- 设计模式的分类
- 简单工厂模式
- golang自举编译
- 了解sync.Once
- 知识碎片
- 常见问题
- 开源项目
- Python
- Anaconda
- 介绍、使用教程
- Python基础知识
- Python之禅
- 变量和类型
- 流程控制
- Python运维
- Python内置工具
- 命令行工具
- 包管理工具pip
- 小爬虫笔记
- I/O操作
- requests库
- requests基本使用
- BeautifulSoup库
- BeautifulSoup基本使用
- Scrapy框架
- 数据可视化
- Django
- Django起步
- OpenCV
- OpenCV入门
- 前端
- HTML
- CSS
- CSS权重计算
- Javascript
- 基础
- JS基础知识
- 监听事件
- 字符串操作
- 数组操作
- 输入输出
- 定时器
- 样式操作
- 获取url参数
- Typescript
- Pick 与 Omit TS内置类型
- Vue.js
- Vue.js介绍
- Vue.js基础
- Vue指令
- v-model
- v-for
- 指令修饰符
- Q&A
- 命令
- Vue3
- node.js
- node.js基础
- npm遇到的问题
- 相关工具安装
- nvm使用教程
- 工程化webpack
- Linux
- Linux基础
- 符号链接
- Shell
- 脚本执行方式
- 数据的输入输出
- 脚本执行中的问题
- tcpdump
- 正则表达式
- Elasticsearch
- Docker
- Docker的基础概念与操作
- Docker 安装
- 容器技术原理
- Docker核心概念
- Docker基本操作
- 镜像相关操作
- 容器相关操作
- 镜像加速器
- Dockerfile
- COPY复制文件
- Docker所遇问题
- ansible
- ansible入门
- k8s
- 安装工具
- kubectl
- Git
- gitlab
- gitlab备份与恢复
- gitlab基本使用
- git使用
- git常用命令
- git提交问题
- git提交规范
- 数据库
- MySQL
- MySQL介绍
- mariadb安装
- 主主复制
- 数据库问题集结
- 开启binlog
- MySQL常用命令
- SQL总结
- MySQL性能优化系列
- 第一章 初始化安装和简单安全加固
- 第二章 认识performance_schema
- 第三章 MySQL体系结构
- MySQL配置模板
- Redis
- Redis简单使用
- Redis常见问题
- Redis集群
- Redis Cluster概述
- 数据分布
- 搭建集群
- MongoDB
- mongodb分片
- MongoDB分片集群设置密码验证
- TiDB
- 单机模拟部署生产环境集群
- 服务器
- CentOS
- 配置阿里云的yum源和epel源
- centos7 实现NFS文件共享
- rsync
- centos7 源码编译rsync
- rsync实现文件同步
- 添加删除swap分区
- 清除buff/cache
- 配置ntp时间同步
- centos7安装pip
- centos7虚拟机启动报xfs错误
- centos7常用命令
- centos7安装mysql
- centos7安装python3.x
- centos7升级gcc、g++
- centos7安装nginx
- centos7部署Nexus
- centos7离线安装python3
- centos7.6编译mariadb10.5.22
- CentOS8
- 银河麒麟V4
- nginx编译
- 银河麒麟V10_x86
- 安装VNC
- 单用户模式
- UOS
- 配置本地apt源
- apt安装vnc-server
- UOS单用户模式
- UOS创建自启动脚本
- 源码编译
- oniguruma编译
- Proxmox VE
- PVE基本使用
- PVE故障
- KVM
- KVM相关命令
- 银河麒麟V10_x86安装kvm
- UOS_arm64安装kvm
- yum、rpm、apt
- dpkg、apt-get、yum和rpm的区别
- rpm打包
- yum相关问题
- 内建银河麒麟的apt源
- 其他软件
- JuiceFS
- nacos
- 常见命令
- 硬盘分区
- Linux常见问题
- 测试
- sysbench
- 其他
- Cloc代码统计工具
- onlyoffice 在线文档编辑
- onlyoffice添加中文字体
- 遇到的问题
- 网络通信协议
- 部署相关记录
- Vmware workstation虚拟机迁移到PVE指南
- 小操作