Go如何集成SQLite数据库?

8,456 阅读3分钟

「这是我参与11月更文挑战的第14天,活动详情查看:2021最后一次更文挑战

前文# 三行Go代码让windows帮我保存日志中提到需要开发一个运行在windows平台上的小软件, 并且需要刚好需要结构化的记录数据, 于是就选择使用SQLite来用作数据存储。

go-sqlite3 使用指南

在Golang中目前比较活跃的sqlie3驱动,首推go-sqlite3

安装这个库之前首先确保你启用并且配置好了CGO环境, 并启用了CGO环境CGO_ENABLED=1

image.png

安装CGO

Linux

Linxu环境下直接使用对应发行版本的包管理器安装gcc即可。

sudo apt-get install gcc

并设置环境变量CGO_ENABLE=1即可启用CGO

Windows

Windows环境下安装gcc则需要借助MinGW-64

MinGW-64各个版本的下载地址, 建议挂梯子。

你也可以选择使用TDM-GCC, 衍生自MinGW(32位)和MinGW-w64(64位), 也是我当前安装的版本。安装完成后记得将GCC的路径设置到环境变量PATH里面。

Windows平台同样需要在安装完gcc后, 将CGO_ENABLE环境变量设置为1。

安装go-sqlite3

使用以下命令安装go-sqlite3, 等待安装完成即可。

go get github.com/mattn/go-sqlite3

使用

像Java设计那样抽象出了一套数据库访问接口, Golang官方也抽象出了一套数据库访问接口, 因此本文不打算重点介绍这些, 大伙可以阅读官方文档,或者直接接入ORM框架使用即可。

注: go-sqlie3注册的驱动名称为sqlite3

DSN

DSNData Soure Name实际上就是一个字符串, 其设计目的和Java中的jdbcurl一样都是用来描述数据库源在哪里, 并且可以包含一些特定选项。

go-sqlie3的DSN格式如下所示:

file:文件路径[?选项1=值&选项2=值]

其中常用选项有:

  • _auth_user 加密数据库文件的用户名
  • _auth_pass 加密数据库文件的密码
  • _case_sensitive_like | _cslike 是否大小写敏感
  • _loc 时区, 默认为当前系统的时区
  • _cache_size 允许使用的缓存大小, 默认是2000K(2M), 这个值可以调高一点
  • mode 打开数据库文件的模式, 分别为只读(ro), 读写(rw), 读写以及不存在时创建(rwc), 纯内存数据(memory)更改不会写入到磁盘中

更多选项你可以正在官方README.md文档中找到。

Demo

内存数据库

第一个例子,我们来打开一个纯内存数据库文件并创建一个表, 往其中写入数据,之后再读取数据。

package main

import (
	"database/sql"
	"fmt"
	_ "github.com/mattn/go-sqlite3"
)

func main() {
	db, err := sql.Open("sqlite3", "file:test.db?mode=memory")
	if err != nil {
		panic(err)
	}
	_, err = db.Exec("CREATE TABLE log(id INT, content VARCHAR(1024))")
	if err != nil {
		panic(err)
	}
	result, err := db.Exec("INSERT INTO log(id, content) VALUES(1, 'Hello')")
	if err != nil {
		panic(err)
	}
	affectedRows, err := result.RowsAffected()
	if err != nil {
		panic(err)
	}
	fmt.Printf("受影响的行数: %d\n", affectedRows)
	rows, err := db.Query("SELECT * FROM log")
	for rows.Next() {
		var id int
		var content string
		err := rows.Scan(&id, &content)
		if err != nil {
			panic(err)
		}
		fmt.Printf("id: %d content: %s", id, content)
	}
	rows.Close()
	db.Close()
}

运行之后可以发现,此时没有任何数据库文件生成, 并且输出了以下内容:

image.png

我们将mode的值修改为rwc后,观察发现在同一目录下自动生成了test.db文件。

image.png