当前位置: 首页 > 工具软件 > go-sqlite3 > 使用案例 >

Go 与 SQLite 数据库

罗睿识
2023-12-01


SQLite 的介绍与安装


SQLite 简介

SQLite 是一个开放源代码的数据库引擎,具有独立,无服务器依赖,零配置,支持事务等特点,SQLite 一直以轻量级为特点,在移动和嵌入式设备上使用广泛,官方称其是世界上部署最广泛的数据库引擎。

SQLite 是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。

SQLite 具有如下的特点与优势:

  • 不需要一个单独的服务器进程或操作的系统(无服务器的)。

  • SQLite 不需要配置,这意味着不需要安装或管理。

  • 一个完整的 SQLite 数据库是存储在一个单一的跨平台的磁盘文件。

  • SQLite 是非常小的,是轻量级的,完全配置时小于 400 KiB,省略可选功能配置时小于 250KiB

  • SQLite 是自给自足的,这意味着不需要任何外部的依赖。

  • SQLite 事务是完全兼容 ACID 的,允许从多个进程或线程安全访问。

  • SQLite 支持 SQL92(SQL2)标准的大多数查询语言的功能。

  • SQLite 使用 ANSI-C 编写的,并提供了简单和易于使用的 API。

  • SQLite 可在 UNIX(Linux, Mac OS-X, Android, iOS)和 Windows(Win32、WinCE、 WinRT)中运行。


SQLite 的安装

Linux 命令行安装方式:

  • 更新 apt-cache ,输入如下命令:
sudo apt update
  • 检查 apt 储存库中是否有可用的 SQLite 软件包,输入如下命令:
sudo apt-cache search sqlite
  • 安装软件包(一般 Linux 系统都有 SQLite ),输入如下命令:
sudo apt install sqlite3 -y
  • 验证是否安装成功,输入 sqlite3 启动命令,输出如下信息表示安装成功:
SQLite version 3.27.2 2020-02-20 14:08:51
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> 

源码安装方式:

  • 使用 curl / wgetSQLite 官网 )下载安装包,输入如下命令:
curl https://www.sqlite.org/2022/sqlite-tools-linux-x86-3400100.zip

wget https://www.sqlite.org/2022/sqlite-autoconf-3400100.tar.gz
  • 解压安装包,输入如下命令:
tar -zxvf https://www.sqlite.org/2022/sqlite-autoconf-3400100.tar.gz
  • 重命名,输入如下命令:
mv sqlite-autoconf-3400100 sqlite
  • 移动文件到 /usr/local/ 目录下,输入如下命令:
mv sqlite /usr/local/
  • 生成 makefile 文件,输入如下命令:
./configure
  • 编译项目,输入如下命令:
make
  • 安装 SQLite ,输入如下命令:
make install
  • 验证是否安装成功,输入 sqlite3 启动命令,输出如下信息表示安装成功:
SQLite version 3.27.2 2020-02-20 14:08:51
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> 

图形化管理界面 DB Browser for SQLite 安装与使用

  • apt 安装 DB Browser for SQLite ,在终端输入如下命令:
sudo apt-get install sqlitebrowser -y
  • 打开 GUI 界面,输入如下命令:
sqlitebrowser  &
  • 软件的使用

参考 如何在 Linux 上使用 DB Browser for SQLite|应用程序|sql|sqlite_网易订阅


SQLite 基础入门


SQLite 基本命令说明

  • 系统命令 以 “.” 开头。

  • 普通命令 ,以 “;” 结束。

  • 命令都是在 sqlite> 后输入。

命令含义
.schema查看表的结构
.quit退出数据库
.exit退出数据库
.help查看帮助信息
.databases查看数据库
.tables显示数据库中所有的表的表名
.open创建数据库

数据库管理命令

sqlite3 test.db -- 创建数据库
.open test.db -- 创建数据库
.databases -- 查看数据库
.quit -- 退出

sqlite3 testDB.db .dump > testDB.sql -- 导出数据库到txt文件
sqlite3 testDB.db < testDB.sql -- txt文件导入数据库

ATTACH DATABASE 'test.db' as 'TEST'; -- 附加数据库
DETACH DATABASE 'TEST'; -- 分离数据库

数据表操作

  • 创建数据表
CREATE TABLE database_name.table_name(
   		column1 datatype  PRIMARY KEY(one or more columns),
   		column2 datatype,
  		column3 datatype,
   		.....
   		columnN datatype,
);
  • 查看数据表
 .tables
  • 获取表的完整信息
.schema COMPANY
  • 删除数据表
DROP TABLE database_name.table_name;
DROP TABLE COMPANY;

数据表操作示例

CREATE TABLE COMPANY(
   		ID INT PRIMARY KEY     NOT NULL,
   		NAME           TEXT    NOT NULL,
   		AGE            INT     NOT NULL,
   		ADDRESS        CHAR(50),
   		SALARY         REAL
);

数据库语句

  • 新增数据
INSERT INTO TABLE_NAME [(column1, column2, column3,...columnN)]  
VALUES (value1, value2, value3,...valueN);

INSERT INTO TABLE_NAME VALUES (value1,value2,value3,...valueN);
  • 查询数据
SELECT column1, column2, columnN FROM table_name;
.header on
.mode column
  • 修改数据
UPDATE table_name SET column1 = value1, column2 = value2...., columnN = valueN WHERE [condition];
  • 删除数据
DELETE FROM table_name WHERE [condition];

数据库语句示例

INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (6, 'Kim', 22, 'South-Hall', 45000.00 );

INSERT INTO COMPANY VALUES (7, 'James', 24, 'Houston', 10000.00 );

SELECT * FROM COMPANY;
SELECT ID, NAME, SALARY FROM COMPANY;

UPDATE COMPANY SET ADDRESS = 'Texas' WHERE ID = 6;
UPDATE COMPANY SET ADDRESS = 'Texas', SALARY = 20000.00;

DELETE FROM COMPANY WHERE ID = 7;
DELETE FROM COMPANY;

Go 访问 SQLite


获取访问接口

  • 安装驱动,输入如下命令:
go get -u github.com/mattn/go-sqlite3
  • 在项目中导入数据库包,使用的如下方式:
import (
		_ "github.com/mattn/go-sqlite3"
)

Go 操作 SQLite

启动 SQLite ,创建数据库和数据表 user,输入如下命令:

CREATE TABLE `user` (
	`uid` INT PRIMARY KEY NOT NULL,
	`name` TEXT NOT NULL,
	`phone` CHAR(50)
);

INSERT INTO `user` (`uid`, `name`, `phone`) VALUES (15, 'yx', '138888888');
INSERT INTO `user` (`uid`, `name`, `phone`) VALUES (111, 'yx', '138888888');

编写 Go 程序连接数据库,该程序的具体代码如下:

package main

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

func main() {
		db, err := sql.Open("sqlite3", "/home/Tao/test.db")
		if err != nil {
				log.Fatal(err)
		}
		defer db.Close()
}
  • 导出数据库数据,输入如下命令:
sqlite3 test.db > test.sql
  • 初始化连接
package main

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

var db *sql.DB

// 定义一个初始化数据库的函数
func initDB() (err error) {
		//连接数据库
		db, err = sql.Open("sqlite3", "/home/Tao/test.db")
		if err != nil {
				return err
		}
		// 尝试与数据库建立连接(校验dsn是否正确)
		err = db.Ping()
		if err != nil {
				return err
		}
		return nil
}

func main() {
		if err := initDB(); err != nil {
				fmt.Printf("Initing the db is failed, err: %v\n", err)
		} else {
				fmt.Plintln("Connecting the db is ok!")
		}
}

设置最大连接数:n<=0,无限制,默认为 0(不会超过数据库默认配置)。

func (db *DB) SetMaxOpenConns(n int)

设置最大闲置连接数:n<=0,无限制,默认为 0(不会超过数据库默认配置)。

func (db *DB) SetMaxOpenConns(n int)

示例

示例的数据库表结构如下所示,相应的建表 SQL :

CREATE TABLE `userinfo` (
    	`uid` INTEGER PRIMARY KEY AUTOINCREMENT,
    	`username` VARCHAR(64) NULL,
    	`departname` VARCHAR(64) NULL,
    	`created` DATE NULL
);
CREATE TABLE `userdetail` (
    	`uid` INT(10) NULL,
    	`intro` TEXT NULL,
    	`profile` TEXT NULL,
    	PRIMARY KEY (`uid`)
);

编写一个 Go 程序实现对该数据库表中数据的增删改查操作,该程序的具体代码如下:

package main

import (
    	"database/sql"
    	"fmt"
    	"time"
    	_ "github.com/mattn/go-sqlite3"
)
func main() {
    	db, err := sql.Open("sqlite3", "./foo.db")
    	checkErr(err)
    	// 插入数据
    	stmt, err := db.Prepare("INSERT INTO userinfo(username, departname, created) values(?,?,?)")
    	checkErr(err)
    	res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09")
    	checkErr(err)
    	id, err := res.LastInsertId()
    	checkErr(err)
    	fmt.Println(id)
    	// 更新数据
    	stmt, err = db.Prepare("update userinfo set username=? where uid=?")
    	checkErr(err)
    	res, err = stmt.Exec("astaxieupdate", id)
    	checkErr(err)
    	affect, err := res.RowsAffected()
    	checkErr(err)
    	fmt.Println(affect)
    	// 查询数据
    	rows, err := db.Query("SELECT * FROM userinfo")
    	checkErr(err)
    	for rows.Next() {
        		var uid int
        		var username string
        		var department string
        		var created time.Time
        		err = rows.Scan(&uid, &username, &department, &created)
        		checkErr(err)
        		fmt.Println(uid)
        		fmt.Println(username)
        		fmt.Println(department)
        		fmt.Println(created)
    	}
    	// 删除数据
    	stmt, err = db.Prepare("delete from userinfo where uid=?")
    	checkErr(err)
    	res, err = stmt.Exec(id)
    	checkErr(err)
    	affect, err = res.RowsAffected()
    	checkErr(err)
    	fmt.Println(affect)
    	db.Close()
}

func checkErr(err error) {
    	if err != nil {
        		panic(err)
    	}
}

可以看到上面的程序·代码和 MySQL 操作的代码几乎是一模一样的,唯一改变的就是导入的驱动改变了,然后调用sql.Open() 方法是采用了 SQLite 的方式打开。


SQL查询

  • QueryRow() 单行查询
func (db *DB) QueryRow(query string, args ...interface{}) *Row
package main

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

var db *sql.DB

// 定义一个初始化数据库的函数
func initDB() (err error) {
		//连接数据库
		db, err = sql.Open("sqlite3", "/home/Tao/test.db")
		if err != nil {
				return err
		}
		// 尝试与数据库建立连接(校验dsn是否正确)
		err = db.Ping()
		if err != nil {
				return err
		}
		return nil
}

type User struct {
		Uid	 	int
		Name 	string
		Phone	string
}

func queryRow() {
		var u User;
		if err := db.QueryRow("select uid, name, phone from user where uid=?;", 111).Scan(&u.Uid, &u.Name, &u.Phone); err != nil {
				fmt.Printf("scan failed, err:%v\n", err)
				return
		}
		fmt.Printf("uid:%d name:%s phone:%s\n", u.Uid, u.Name, u.Phone)
}

func main() {
		if err := initDB(); err != nil {
				fmt.Printf("init db failed, err: %v\n", err)
		}
		queryRow()
}
  • Query() 多行查询
func (db *DB) Query(query string, args ...interface{}) (*Rows, error)
package main

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

var db *sql.DB

// 定义一个初始化数据库的函数
func initDB() (err error) {
		//连接数据库
		db, err = sql.Open("sqlite3", "/home/Tao/test.db")
		if err != nil {
				return err
		}
		// 尝试与数据库建立连接(校验dsn是否正确)
		err = db.Ping()
		if err != nil {
				return err
		}
		return nil
}

type User struct {
		Uid	 	int
		Name 	string
		Phone 	string
}

func queryMultiRow() {
		var u User;
		rows, err := db.Query("select uid, name, phone from user where uid>?;", 0)
		if err != nil {
				fmt.Printf("query failed, err:%v\n", err)
				return
		}
		defer rows.Close()

		for rows.Next() {
				err := rows.Scan(&u.Uid, &u.Name, &u.Phone)
				if err != nil {
					fmt.Printf("scan failed, err:%v\n", err)
					return
				}
				fmt.Printf("uid:%d name:%s phone:%s\n", u.Uid, u.Name, u.Phone)
		}
}

func main() {
		if err := initDB(); err != nil {
				fmt.Printf("init db failed, err: %v\n", err)
		}
		queryMultiRow()
}
  • Exec() 执行一次命令(查询、删除、更新、插入等)
func (db *DB) Exec(query string, args ...interface{}) (Result, error)
func (db *DB) Exec(query string, args ...interface{}) (Result, error)
package main

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

var db *sql.DB

// 定义一个初始化数据库的函数
func initDB() (err error) {
		//连接数据库
		db, err = sql.Open("sqlite3", "/home/Tao/test.db")
		if err != nil {
				return err
		}
		// 尝试与数据库建立连接(校验dsn是否正确)
		err = db.Ping()
		if err != nil {
				return err
		}
		return nil
}

//插入数据
func insertRow() {
		ret, err := db.Exec("insert into user(uid, name, phone) values(?, ?, ?);", 12, "ml", "15906693677")
		if err != nil {
				fmt.Printf("insert failed, err:%v\n", err)
				return
	}
	
		uid, err := ret.LastInsertId()
		if err != nil {
				fmt.Printf("get lastinsert ID failed, err:%v\n", err)
				return
		}
		fmt.Printf("insert success, the id is %d.\n", uid)
	
}

//更新数据
func updateRow() {
		ret, err := db.Exec("update user set name=? where uid=?;", "tt", 12)
		if err != nil {
				fmt.Printf("update failed, err:%v\n", err)
				return
		}
	
		n, err := ret.RowsAffected()
		if err != nil {
				fmt.Printf("get lastinsert ID failed, err:%v\n", err)
				return
		}
		fmt.Printf("update success, affected rows:%d\n", n)
}

//删除数据
func deleteRow() {
		ret, err := db.Exec("delete from user where uid=?;", 12)
		if err != nil {
				fmt.Printf("delete failed, err:%v\n", err)
				return
		}
	
		n, err := ret.RowsAffected()
		if err != nil {
				fmt.Printf("get lastinsert ID failed, err:%v\n", err)
			return
		}
		fmt.Printf("delete success, affected rows:%d\n", n)
}

func main() {
		if err := initDB(); err != nil {
				fmt.Printf("init db failed, err: %v\n", err)
		}
		insertRow()
		updateRow()
		deleteRow()
}

  • 参考书籍:《Go Web 编程从入门到精通》(廖显东 著)

  • 参考书籍: 《Go Web 编程》(谢孟军 著)

  • 参考链接:SQLite 官网

 类似资料: