Golang database/sql标准库怎么用_Golang数据库操作基础

发布时间 - 2026-01-30 00:00:00    点击率:
database/sql 是接口规范,需搭配驱动使用;sql.Open 不建连,须用 db.Ping() 校验;Query 用于多行需手动 Close,QueryRow 用于单行自动关闭;防注入须用占位符;事务须配对 Commit/Rollback;连接池参数需调优。

直接用 database/sql 无法执行任何数据库操作——它只是接口规范,必须搭配驱动(如 github.com/go-sql-driver/mysqlgithub.com/lib/pq)才能工作。

为什么 sql.Open 不报错却连不上数据库?

sql.Open 只是初始化连接池配置,并不真正建连。真实校验要靠 db.Ping()

  • 常见错误现象:sql.Open 返回 nil error,但后续 Query"sql: database is closed" 或超时
  • 正确做法:初始化后立刻调用 db.Ping() 并检查 error
  • 注意:db.Ping() 是同步阻塞的,生产环境建议加 context 控制超时,例如 db.PingContext(ctx, time.Second*5)

QueryQueryRow 的核心区别在哪?

本质是结果集数量预期不同,影响资源释放逻辑和 panic 风险。

  • Query 用于多行结果(如 SELECT 多条记录),返回 *sql.Rows,必须显式调用 rows.Close(),否则连接不会归还池中
  • QueryRow 用于单行结果(如 SELECT ... LIMIT 1 或聚合函数),内部自动 close,但若实际无结果会返回 sql.ErrNoRows,不处理就 panic
  • 别用 QueryRow 去查可能返回多行的数据——它只读第一行,其余被丢弃且不报错

怎么安全传参避免 SQL 注入?

永远用 ? 占位符 + 参数列表,不要字符串拼接。

立即学习“go语言免费学习笔记(深入)”;

  • MySQL 驱动用 ?,PostgreSQL 驱动用 $1, $2,SQLite 两者都支持但推荐 ?
  • 错误写法:db.Query("SELECT * FROM users WHERE name = '" + name + "'") —— 直接引入注入风险
  • 正确写法:db.Query("SELECT * FROM users WHERE name = ?", name)
  • 注意:占位符不能用于表名、列名或 ORDER BY 子句,这些需白名单校验后拼接

事务里忘了 Rollback 会怎样?

连接会一直被事务占用,直到超时或进程退出,最终拖垮连接池。

  • 典型陷阱:只写了 tx.Commit(),但没在 defer 或 else 分支里配对 tx.Rollback()
  • 推荐模式:defer func() { if r := recover(); r != nil { tx.Rollback() } }() + 显式 i

    f err != nil { tx.Rollback(); return }
  • 更稳妥的做法:用 tx, err := db.BeginTx(ctx, &sql.TxOptions{Isolation: sql.LevelReadCommitted}),支持 context 取消

最易被忽略的是连接池行为:默认 MaxOpenConns=0(无限制)、MaxIdleConns=2,高并发下很容易耗尽数据库连接数。上线前务必根据 DB 实例规格调优这两个值。


# mysql  # git  # go  # github  # golang  # 区别  # 聚合函数  # 标准库  # 为什么  # sql  # if  # select  # Error  # 字符串  # 接口  # nil  # 并发  # sqlite  # database  # postgresql  # 数据库  # 连接池  # 报错  # 的是  # 子句  # 很容易  # 这两个  # 不上  # 写了  # 要靠  # 多条 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 如何在新浪SAE免费搭建个人博客?  如何在万网主机上快速搭建网站?  jQuery 常见小例汇总  JS弹性运动实现方法分析  Laravel Telescope怎么调试_使用Laravel Telescope进行应用监控与调试  如何用狗爹虚拟主机快速搭建网站?  html5源代码发行怎么设置权限_访问权限控制方法与实践【指南】  HTML5空格和nbsp有啥关系_nbsp的作用及使用场景【说明】  html5audio标签播放结束怎么触发事件_onended回调方法【教程】  JS碰撞运动实现方法详解  C++时间戳转换成日期时间的步骤和示例代码  Linux后台任务运行方法_nohup与&使用技巧【技巧】  韩国网站服务器搭建指南:VPS选购、域名解析与DNS配置推荐  Laravel定时任务怎么设置_Laravel Crontab调度器配置  Windows Hello人脸识别突然无法使用  Laravel如何使用Socialite实现第三方登录?(微信/GitHub示例)  如何在搬瓦工VPS快速搭建网站?  如何在建站之星网店版论坛获取技术支持?  UC浏览器如何设置启动页 UC浏览器启动页设置方法  网站制作企业,网站的banner和导航栏是指什么?  Laravel如何实现一对一模型关联?(Eloquent示例)  如何在IIS管理器中快速创建并配置网站?  Laravel观察者模式如何使用_Laravel Model Observer配置  Laravel怎么实现搜索高亮功能_Laravel结合Scout与Algolia全文检索【实战】  Laravel怎么使用Intervention Image库处理图片上传和缩放  PHP 实现电台节目表的智能时间匹配与今日/明日轮播逻辑  canvas 画布在主流浏览器中的尺寸限制详细介绍  手机钓鱼网站怎么制作视频,怎样拦截钓鱼网站。怎么办?  java中使用zxing批量生成二维码立牌  教你用AI润色文章,让你的文字表达更专业  laravel怎么为应用开启和关闭维护模式_laravel应用维护模式开启与关闭方法  宙斯浏览器怎么屏蔽图片浏览 节省手机流量使用设置方法  在线教育网站制作平台,山西立德教育官网?  什么是javascript作用域_全局和局部作用域有什么区别?  香港网站服务器数量如何影响SEO优化效果?  如何在万网自助建站中设置域名及备案?  Laravel如何集成微信支付SDK_Laravel使用yansongda-pay实现扫码支付【实战】  详解免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)  Windows10如何删除恢复分区_Win10 Diskpart命令强制删除分区  Laravel怎么生成URL_Laravel路由命名与URL生成函数详解  极客网站有哪些,DoNews、36氪、爱范儿、虎嗅、雷锋网、极客公园这些互联网媒体网站有什么差异?  高性能网站服务器配置指南:安全稳定与高效建站核心方案  php增删改查怎么学_零基础入门php数据库操作必知基础【教程】  Internet Explorer官网直接进入 IE浏览器在线体验版网址  Laravel PHP版本要求一览_Laravel各版本环境要求对照  香港服务器租用每月最低只需15元?  Laravel队列由Redis驱动怎么配置_Laravel Redis队列使用教程  Angular 表单中正确绑定输入值以确保提交与验证正常工作  详解Nginx + Tomcat 反向代理 如何在高效的在一台服务器部署多个站点  javascript基本数据类型及类型检测常用方法小结