golang操作mysql使用总结
前言
Golang 提供了database/sql包用于对SQL数据库的访问, 作为操作数据库的入口对象sql.DB, 主要为我们提供了两个重要的功能:
- sql.DB 通过数据库驱动为我们提供管理底层数据库连接的打开和关闭操作.
- sql.DB 为我们管理数据库连接池
需要注意的是,sql.DB表示操作数据库的抽象访问接口,而非一个数据库连接对象;它可以根据driver打开关闭数据库连接,管理连接池。正在使用的连接被标记为繁忙,用完后回到连接池等待下次使用。所以,如果你没有把连接释放回连接池,会导致过多连接使系统资源耗尽。
操作mysql
1.导入mysql数据库驱动
1 |
import ( |
通常来说, 不应该直接使用驱动所提供的方法, 而是应该使用 sql.DB, 因此在导入 mysql 驱动时, 这里使用了匿名导入的方式(在包路径前添加 _), 当导入了一个数据库驱动后, 此驱动会自行初始化并注册自己到Golang的database/sql上下文中, 因此我们就可以通过 database/sql 包提供的方法访问数据库了.
2.连接数据库
1 |
type DbWorker struct {
|
通过调用sql.Open函数返回一个sql.DB指针; sql.Open函数原型如下:
1 |
func Open(driverName, dataSourceName string) (*DB, error) |
driverName: 使用的驱动名. 这个名字其实就是数据库驱动注册到 database/sql 时所使用的名字.dataSourceName: 数据库连接信息,这个连接包含了数据库的用户名, 密码, 数据库主机以及需要连接的数据库名等信息.
- sql.Open并不会立即建立一个数据库的网络连接, 也不会对数据库链接参数的合法性做检验, 它仅仅是初始化一个sql.DB对象. 当真正进行第一次数据库查询操作时, 此时才会真正建立网络连接;
- sql.DB表示操作数据库的抽象接口的对象,但不是所谓的数据库连接对象,sql.DB对象只有当需要使用时才会创建连接,如果想立即验证连接,需要用Ping()方法;
- sql.Open返回的sql.DB对象是协程并发安全的.
- sql.DB的设计就是用来作为长连接使用的。不要频繁Open, Close。比较好的做法是,为每个不同的datastore建一个DB对象,保持这些对象Open。如果需要短连接,那么把DB作为参数传入function,而不要在function中Open, Close。
3.数据库基本操作
数据库查询的一般步骤如下:
- 调用 db.Query 执行 SQL 语句, 此方法会返回一个 Rows 作为查询的结果
- 通过 rows.Next() 迭代查询数据.
- 通过 rows.Scan() 读取每一行的值
- 调用 db.Close() 关闭查询
现有user数据库表如下:
1 |
CREATE TABLE `user` ( |
MySQL 5.5 之前, UTF8 编码只支持1-3个字节,从MYSQL5.5开始,可支持4个字节UTF编码utf8mb4,一个字符最多能有4字节,utf8mb4兼容utf8,所以能支持更多的字符集;关于emoji表情的话mysql的utf8是不支持,需要修改设置为utf8mb4,才能支持。
查询数据
1 |
func (dbw *DbWorker) QueryData() {
|
- rows.Scan 参数的顺序很重要, 需要和查询的结果的column对应. 例如 “SELECT * From user where age >=20 AND age < 30” 查询的行的 column 顺序是 “id, name, age” 和插入操作顺序相同, 因此 rows.Scan 也需要按照此顺序 rows.Scan(&id, &name, &age), 不然会造成数据读取的错位.
- 因为golang是强类型语言,所以查询数据时先定义数据类型,但是查询数据库中的数据存在三种可能:存在值,存在零值,未赋值NULL 三种状态, 因为可以将待查询的数据类型定义为sql.Nullxxx类型,可以通过判断Valid值来判断查询到的值是否为赋值状态还是未赋值NULL状态.
- 每次db.Query操作后, 都建议调用rows.Close(). 因为 db.Query() 会从数据库连接池中获取一个连接, 这个底层连接在结果集(rows)未关闭前会被标记为处于繁忙状态。当遍历读到最后一条记录时,会发生一个内部EOF错误,自动调用rows.Close(),但如果提前退出循环,rows不会关闭,连接不会回到连接池中,连接也不会关闭, 则此连接会一直被占用. 因此通常我们使用 defer rows.Close() 来确保数据库连接可以正确放回到连接池中; 不过阅读源码发现rows.Close()操作是幂等操作,即一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同, 所以即便对已关闭的rows再执行close()也没关系.
单行查询
1 |
var name string |
- err在Scan后才产生,上述链式写法是对的
- 需要注意Scan()中变量和顺序要和前面Query语句中的顺序一致,否则查出的数据会映射不一致.
插入数据
1 |
func (dbw *DbWorker) insertData() {
|
通过db.Exec()插入数据,通过返回的err可知插入失败的原因,通过返回的ret可以进一步查询本次插入数据影响的行数RowsAffected和最后插入的Id(如果数据库支持查询最后插入Id).
4.预编译语句(Prepared Statement)
预编译语句(PreparedStatement)提供了诸多好处, 因此我们在开发中尽量使用它. 下面列出了使用预编译语句所提供的功能:
- PreparedStatement 可以实现自定义参数的查询
- PreparedStatement 通常来说, 比手动拼接字符串 SQL 语句高效.
- PreparedStatement 可以防止SQL注入攻击
一般用Prepared Statements和Exec()完成INSERT, UPDATE, DELETE操作。
下面是将上述案例用Prepared Statement 修改之后的完整代码
1 |
package main import ( |
db.Prepare()返回的statement使用完之后需要手动关闭,即defer stmt.Close()
golang操作mysql使用总结的更多相关文章
- [转帖]golang操作mysql使用总结
golang操作mysql使用总结 https://www.cnblogs.com/hanyouchun/ 讲解的很详细~ 前言 Golang 提供了database/sql包用于对SQL数据库的访问 ...
- golang操作mysql数据库
golang操作mysql数据库 代码: mysql的增.删.改.查 package main import ( "database/sql" "fmt" &q ...
- Golang操作MySQL的正确姿势
封装原因: 查看了很多网上提供的ORM类型的数据库操作,觉得比较麻烦,需要提前配置很多的表结构体,然后才能使用,对于数据表很多的项目就配置起来就比较麻烦,所以对golang的mysql包进行了外层包装 ...
- Golang 操作mysql使用举例---连接本地数据库
连接数据库的方式有两种:TCP和Unix域socket. 本文使用Unix domain sockets连接数据库.关于TCP连接数据库可以参考Go 操作mysql使用举例 下面例子中,演示了使用sh ...
- Mysql学习(一)添加一个新的用户并用golang操作Mysql
Mysql添加一个新的用户并赋予权限 添加一个自己的用户到mysql 首先我们需要先用root用户登录mysql,但是刚安装完没有密码,我们先跳过密码 ailumiyana@ailumiyana:~/ ...
- golang操作mysql
1. 安装mysql驱动库和sqlx基于官方sql库的扩展库 go get github.com/go-sql-driver/mysql go get github.com/jmoiron/sqlx ...
- go语言之行--golang操作redis、mysql大全
一.redis 简介 redis(REmote DIctionary Server)是一个由Salvatore Sanfilippo写key-value存储系统,它由C语言编写.遵守BSD协议.支持网 ...
- Go基础之--操作Mysql(一)
关于标准库database/sql database/sql是golang的标准库之一,它提供了一系列接口方法,用于访问关系数据库.它并不会提供数据库特有的方法,那些特有的方法交给数据库驱动去实现. ...
- Golang原生sql操作Mysql数据库增删改查
Golang要操作mysql数据库,首先需要在当期系统配置GOPATH,因为需要使用go get命令把驱动包下载到GOPATH下使用. 首先配置好你的GOPATH,执行以下命令,下载安装mysql驱动 ...
随机推荐
- hover效果的几种方式
1.改变透明度 #share_wrap a{display: inline-block;width: 48px;height: 44px;background: url(/images/finance ...
- 转 jQuery中的$.extend方法来扩展JSON对象
$.extend方法可以扩展JSON对象,用一个或多个其他对象来扩展一个对象,返回被扩展的对象. 例一 合并 settings 和 options,修改并返回 settings var setting ...
- [matlab] 16.多约束非线性规划 ga工具箱解决 [带不等式约束]
下面举例说明如何运用GA工具箱求解多约束非线性规划问题: function f =fitness(x) f=exp(x(1))*(4*x(1)^2+2*x(2)^2+4*x(1)*x(2)+2*x(2 ...
- BZOJ5197:[CERC2017]Gambling Guide(最短路,期望DP)
Description 给定一张n个点,m条双向边的无向图. 你要从1号点走到n号点.当你位于x点时,你需要花1元钱,等概率随机地买到与x相邻的一个点的票,只有通过票才能走到其它点. 每当完成一次交易 ...
- Nginx 反向代理 -- 一路上的坑转载
个人学习之用转子https://www.cnblogs.com/xjbBill/p/7477825.html 前些天刚过来新公司上班,公司的项目都挺多的,只不过项目都是第三方公司团队开发的,现在本公司 ...
- 15.io流,递归
一.file的常用api 二.算法:递归1.定义:递归算法是把问题转化为规模缩小了的同类问题的子问题.然后递归调用函数(或过程)来表示问题的解.一个过程(或函数)直接或间接调用自己本身,这种过程(或函 ...
- Python2 处理 Unicode 字符串的规则
在 Python2 中处理 Unicode 字符串,需遵循如下规则: 1. 程序中的字符串要加前缀 u 2. 不要用 str(),而应该用 unicode() 作为字符串转换函数.不要使用 chr() ...
- 用return关键字实现求和操作
package com.Summer_0419.cn; /** * @author Summer * 用return关键字的知识,实现求和操作 */ public class Test_Method0 ...
- WPF(一)
什么是WPF WPF(Windows Presentation Foundation)是用于Windows的现代图形显示系统.与之前出现的技术相比,WPF发生了根本性变化.WPF引用了"内置 ...
- 2018年JavaScript现状报告
前言 JavaScript(后面统称JS)在过去五年得到飞速地增长,早期JS实现类似微博的“点赞”这样的功能都需要刷新一次页面. 后来开发者通过JS来制作SPA(单页面应用程序),在浏览器加载一次,后 ...