惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Hacker News: Ask HN
Hacker News: Ask HN
D
DataBreaches.Net
Microsoft Security Blog
Microsoft Security Blog
U
Unit 42
V
Visual Studio Blog
GbyAI
GbyAI
云风的 BLOG
云风的 BLOG
博客园 - Franky
C
CXSECURITY Database RSS Feed - CXSecurity.com
大猫的无限游戏
大猫的无限游戏
P
Privacy & Cybersecurity Law Blog
T
The Exploit Database - CXSecurity.com
Simon Willison's Weblog
Simon Willison's Weblog
L
LangChain Blog
I
Intezer
V2EX - 技术
V2EX - 技术
Google DeepMind News
Google DeepMind News
T
Threat Research - Cisco Blogs
Apple Machine Learning Research
Apple Machine Learning Research
V
V2EX
腾讯CDC
博客园 - 【当耐特】
Know Your Adversary
Know Your Adversary
TaoSecurity Blog
TaoSecurity Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
F
Fortinet All Blogs
Project Zero
Project Zero
Blog — PlanetScale
Blog — PlanetScale
S
Security @ Cisco Blogs
量子位
M
MIT News - Artificial intelligence
美团技术团队
C
Cisco Blogs
S
Schneier on Security
Recent Commits to openclaw:main
Recent Commits to openclaw:main
G
Google Developers Blog
N
News and Events Feed by Topic
MongoDB | Blog
MongoDB | Blog
The Hacker News
The Hacker News
H
Help Net Security
S
Secure Thoughts
Scott Helme
Scott Helme
SecWiki News
SecWiki News
T
Troy Hunt's Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
博客园 - 叶小钗
O
OpenAI News
Application and Cybersecurity Blog
Application and Cybersecurity Blog
博客园 - 司徒正美
T
Tenable Blog

Razeen`s Blog

Let's Encrypt 推出 Gen Y 根证书架构:揭示 Web PKI 的五大未来趋势 通过 Wi-Fi 自动备份你的 iPhone 到 Nas 管理培训感悟:从技术视角看管理之路 UPS 一拖多:保护你的 NAS 和 Linux 服务器 从影音中心到 AI 助手:我的50款 Homelab 服务清单 从SSL证书有效期将缩短到47天聊开去 部署一个自己的 Running Page 谈谈特斯拉 Model Y 用车一年的感受和费用分析 弃用 Disqus 评论,使用自建 Waline 使用 Prometheus 和 Grafana 搭建你的证书监控面板 服务器迁移记:一次磁盘换板引发的Linux分区与挂载的学习 改善信息来源, 利用 RSS 高效获取资讯 (RSShub + Reeder5 + WeWe RSS) 多种 Docker 镜像拉取解决方案与实践 App分享 | AppCleaner - Mac上的卸载神器 Azure OpenAI API 申请和使用 如何开通 OneKey 虚拟信用卡,并充值消费 如何拥有一个可长期在国内使用的国外手机号码 分享开通 ChatGPT Plus 过程 如何开通 Depay 虚拟信用卡,并充值消费 如何开通欧易Web3钱包, 交易入账 如何5分钟内1块钱注册 ChatGPT 如何注册美区的 Apple ID (2023年/无需科学上网) NAS折腾记(11): NASTool3.0体验和降级 NAS折腾记(10): Docker版本的NASTool配置 NAS折腾记(9): NASTool与微信交互,微信发送消息远程下载电影【多图】 NAS折腾记(8):群晖安装 NASTool 实现影音半自动化【多图】 内网穿透(2):Tailscale 组网实现内网穿透,操作简单,无成本 内网穿透(1):总结了11中内网穿透的方式,总有一种适合你 NAS折腾记(7):从零开始设置(黑)群晖系统 NAS折腾记(6):黑群晖系统安装好后怎么洗白? NAS折腾记(5):群晖硬盘休眠设置与分析 NAS折腾记(4): 20分钟手把手带你完美安装 DS918+ 黑群晖7.1.1 NAS折腾记(3):NAS 装机 NAS折腾记(2):B360-ITX 双M.2 双2.5G网口 6 SATA主版 开箱 NAS折腾记(1):328元的4盘位Nas机箱开箱 Openwrt + Clash 全局科学上网 Newifi3 刷入 OpenWrt 固件 v21.02 利用 Markdown 画一些流程图、时序图、甘特图等 Homelab(8): 搭建自用 Gitlab 与 Docker 仓库 Nginx Tcp 转发保留客户端真实 IP (PROXY Protocol) Homelab (7):IPSec VPN(基于证书认证)客户端设置 Homelab (6): 基于自签发证书的 IPSec VPN 搭建 Homelab (5): DDNS 动态域名解析 Homelab (4): Linux 服务器基础环境准备 Homelab (3): 整体网络与基础硬件介绍 Go学习笔记(十)老项目迁移 go module 大型灾难记录 Github Actions 初体验之自动化部署 Hexo 博客 记一次 Nginx DNS 缓存导致转发问题 Homelab (2): 电信悦me网关修改桥接模式,路由器拨号 Homelab (1):5分钟上手黑群晖 NAS 终极 Bash 脚本指南 Typora 自动上传图片到七牛云 Ubuntu 20.04 LTS 有线网卡驱动安装 折腾 Ubuntu 20.04 LTS 开发环境 Go学习笔记(九) 计时器的生命周期[译] 利用 git hook 规范你的代码与 commit message 规范 git commit message 与自动化版本控制 超详细 vim 配置 (with MacVim) Golang 中的 RESTful API 最佳实践 折腾服务器(开篇) 我的第一台个人服务器 Newifi3 实现低成本家庭级科学上网 Go学习笔记(八) | 使用 os/exec 执行命令 如何用 Go 调用 Windows API Mac OS 自动根据 WI-FI 名字改变网络位置 关于 Docker 清理 MIME Types 速查表 Go学习笔记(七) | 理解OAuth 2.0并实现一个客户端 我又又又把博客迁移了 Go学习笔记(六) | 使用swaggo自动生成Restful API文档 Go学习笔记(五) | 使用代码片段(snippets)提高编码效率 书单 - 2018 IPFS 初体验,利用 IPFS 托管你的静态网站 记一次 PostgreSQL LIKE 索引优化,联合字段 LIKE 查询优化。 Disqus 添加有趣的 Reactions 的功能 TLS 1.3 详解 (RFC 8446解读) gRPC在Go中的使用(三)gRPC实现TLS加密通信与流模式 gRPC在Go中的使用(二)gRPC实现简单通讯 gRPC在Go中的使用(一)Protocol Buffers语法与相关使用 CentOS 安装 tshark 抓包工具 Go学习笔记(四) | win上使用VSCode搭建Go开发环境 日常 Postgres 数据库点滴记录 简单了解 PKCS 规范 美食篇 | DIY戚风蛋糕(烤箱做蛋糕) Go学习笔记(三) | 怎么写Go基准测试(性能测试) TLS1.3正式更新,为Nginx添加TLS1.3的支持 一次诡异的数据库删除 GitHub Pages自定义域名开启HTTPS 证书透明度是什么?它是怎么工作的? Go学习笔记(二) | 我对 recover 的一点误解 搭建证书透明度(certificate-transparency)日志服务之从入门到放弃 修复远程登陆 Centos 时,出现 UTF-8 Warning HTTPS篇之SSL握手过程详解 AWS 命令行界面(aws-cli)从安装到快速上手 数字证书分类及怎么区分各类数字证书 常用 linux 命令小结(一)文件目录操作 云服务器搭建 hexo 博客,git hooks自动更新 SSH 免密登陆, SSH Config 配置 Golang CGO Mac 交叉编译 Windows 使用 goose 让数据库迁移更加轻松 开始使用Ghost
Go学习笔记(一) | postgres与golang点点滴滴
2017-11-27 · via Razeen`s Blog

在golang中使用数据库主要依赖database/sql库以及pg的驱动库。而目前我们常用的pg的驱动库是 github.com/lib/pq。这里我想说的不是如何去使用它们,毕竟人家文档已经很详细了,这里主要总结了一下自己日常使用中学到的一些技巧。

相同标记重复使用

database/sql库没有规定查询字符串中参数标记的任何特定格式,pq使用了postgres - native序号,像下面例子一样,相同的标记可以被重复使用,用于相同的参数:

// $2 使用了两次 都标记的值是64
rows, err := db.Query(`SELECT name FROM users WHERE favorite_fruit = $1
	OR age BETWEEN $2 AND $2 + 3`, "orange", 64)

操作时返回ID

pq不支持database/sqlLastInsertId()方法,所以当你需要插入(更新or删除)数据后获取自增长的id值时,你可以利用pg的RETURNING语法:

var userid int
err := db.QueryRow(`INSERT INTO users(name, favorite_fruit, age)
	VALUES('beatrice', 'starfruit', 93) RETURNING id`).Scan(&userid)

插入时存在更新

在数据看操作时,很多时候时候会存在唯一冲突,主键冲突等等,而我们又是需要在冲突时更新数据或者其他操作,这时我们可以这样:

// 其中name是唯一的,当name冲突时,更新其他字段
err := db.Exec(`INSERT INTO users(name,favorite_fruit,age)
    VALUES($1, $2, $3) 
    ON CONFLICT (name) DO UPDATE 
        SET favorite_fruit=$2,
            age=$3`)

// 当然,有时候你有条件更新
err := db.Exec(`INSERT INTO users(name,favorite_fruit,age)
    VALUES($1, $2, $3) 
    ON CONFLICT (name) DO UPDATE 
        SET favorite_fruit=$2 
        WHERE age > $4`)

// 你也可以什么都不做
err := db.Exec(`INSERT INTO users(name,favorite_fruit,age)
    VALUES($1, $2, $3) 
    ON CONFLICT (name) DO NOTHING`)

只有单行数据简化代码

这个其实上面就用到了,就是queryRow。当你确定只取一行数据的时候你可以使用该函数。但是需要注意的是:当你查询的数据为空的时候,他会返回sql.ErrNoRaw错误。

var count int
err := db.QueryRow(`SELECT count(*) FROM users`).Scan(&count)
if err != nil {
    if err == sql.ErrNoRaw {
        count = 0
        ...
    }
    ...
}

结果集中空值处理

在查询的时候,有时候难以保证字段一定有值,如果为空,在scan的时候就会报错,为了解决这种情况,我们可以使用下面这些来代替可能为空的字段。

--- 字符串       sql.NullString
--- bool        sql.NullBool
--- int         sql.NullInt64
--- float       sql.NullFloat64 
--- timestamp   pq.NullTime

这里前面4个go驱动带的,后面是pq库带的。如果你还需要其他类型的,你可以自定义,只要实现Scanner接口就OK了。

查询时需要嵌入数组

在使用pg语句的时候我们常用到WHERE xxx IN ('XXX','XXX'...)这样的IN数组操作,在go中也有对应的操作。

// 查找数组中对应id的所有人名
ids := []int64{12,16,33,55}
rows,err := db.Query(`SELECT name FROM users WHERE id=ANY($1),pq.Int64Array(ids))
...

当然其他类型对应的数组驱动也有

pq.BoolArray

pq.ByteaArray

pq.StringArray

pq.Float64Array

结果集中数组处理

同上,用到上面pq中的数组

var ids := pq.Int64Array{}
err := db.QueryRow(`SELECT array_agg(id) FROM users WHERE "age" > $1`,18).Scan(&ids)
...