文章目录
- 前言
- [一、SQLite 介绍](#一、SQLite 介绍)
- [二、ubuntu下SQLite命令行 和 开发库安装](#二、ubuntu下SQLite命令行 和 开发库安装)
- 三、SQLite命令行工具的使用
-
- [1. SQLite命令行工具下的操作命令](#1. SQLite命令行工具下的操作命令)
- [2. 在SQLite命令行下执行操作命令 和 sql语句](#2. 在SQLite命令行下执行操作命令 和 sql语句)
- [四、C++通过SQLite开发库 接入sqlite数据库](#四、C++通过SQLite开发库 接入sqlite数据库)
-
- [1. SQLite库的常用api介绍](#1. SQLite库的常用api介绍)
- [2. 实战演示](#2. 实战演示)
-
- [2.1 sqlite3_exec 直接执行SQL语句](#2.1 sqlite3_exec 直接执行SQL语句)
- [2.2 sqlite3_step 逐步执行预处理语句](#2.2 sqlite3_step 逐步执行预处理语句)
前言
SQLite库的头文件是: <sqlite3.h>
一、SQLite 介绍
SQLite官网: https://sqlite.org/draft/index.html
SQLite菜鸟教程: https://www.runoob.com/sqlite/sqlite-data-types.html
SQLite是⼀个开源、轻量级、零配置、无服务器、自包含、事务性、支持标准SQL、跨平台的数据库管理系统。
- 开源: 免费使用,源码透明
- 轻量级: 整个库非常小,编译之后仅需几百KB
- 零配置: 无需安装、启动、停止 或 配置任何数据库服务器进程
- 无服务器: SQLite没有独立的服务器进程,应用程序直接通过函数调用读写磁盘上的数据库文件
- 自包含: 整个数据库就是⼀个独立的、跨平台的单个文件(通常是.db后缀),文件中包含所有表、索引、数据 和 元信息
- 事务性: 完全支持ACID(原子性、一致性、隔离性、持久性)事务,即使系统崩溃 或 断电也能保证数据完整性
- 支持标准SQL: 它使用SQL语句来管理和查询数据,最多支持128TB
- 跨平台: 数据库文件跨平台
- 简单易用: 只需包含一个 sqlite3.h 和一个库文件即可
一般常用于嵌入式系统、移动开发中。
二、ubuntu下SQLite命令行 和 开发库安装
- 安装 sqlite3命令行工具 和 开发包的命令:
bash
# 安装 sqlite3 命令⾏⼯具
sudo apt install sqlite3
# 安装 sqlite 开发包
sudo apt install libsqlite3-dev
- 列出已安装的 libsqlite3-dev软件包所包含的所有文件及其安装路径:
bash
dpkg -L libsqlite3-dev
bash
ubuntu@VM-0-4-ubuntu:~$ dpkg -L libsqlite3-dev
/.
/usr
/usr/include
/usr/include/sqlite3.h # 核心头文件
/usr/include/sqlite3ext.h
/usr/lib
/usr/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu/libsqlite3.a # 核心静态库
/usr/lib/x86_64-linux-gnu/pkgconfig
/usr/lib/x86_64-linux-gnu/pkgconfig/sqlite3.pc
/usr/share
/usr/share/doc
/usr/share/doc/libsqlite3-dev
/usr/share/doc/libsqlite3-dev/copyright
/usr/lib/x86_64-linux-gnu/libsqlite3.so # 核心动态库
/usr/share/doc/libsqlite3-dev/changelog.Debian.gz
三、SQLite命令行工具的使用
1. SQLite命令行工具下的操作命令
- 进入SQLite命令行工具的命令:
bash
sqlite3
- 数据库操作命令:
| 命令 | 说明 | 示例 |
|---|---|---|
.open 文件名 |
打开 或 创建数据库文件 | .open student.db (student.db是数据库文件名) |
.databases |
显示当前连接的数据库 | .databases |
| .attach 文件 as 别名 | 附加另⼀个数据库 | .attach archive.db as archive |
| .backup 文件名 | 备份当前数据库 | .backup backup.db |
| .restore 文件名 | 从备份恢复数据库 | .restore recovery.db |
.quit |
退出SQLite命令行工具 | .quit |
.exit |
退出SQLite命令行工具 | .exit |
| .help | 显示帮助信息 | .help |
- 表的相关命令
| 命令 | 说明 | 示例 |
|---|---|---|
.tables |
显示所有表 | .tables |
.schema [表名] |
显示表结构 | .schema students (students 是表名) |
| .indexes 表名 | 显示索引 | .indexes students |
注意:sqlite3支持 标准sql语句。
2. 在SQLite命令行下执行操作命令 和 sql语句
- 使用sqlite3命令 进入SQLite命令行工具

- 创建并进入数据库文件

- 查看当前连接的数据库文件

- 在数据库文件下创建 表格

- 向表格插入数据 以及 查看表格中的所有数据
bash
sqlite> INSERT INTO students(name, age, score) VALUES
('张三', 18, 92.0),
('李四', 19, 93.5),
('王五', 18, 76.5);
sqlite> SELECT * FROM students;
1|张三|18|92.0
2|李四|19|93.5
3|王五|18|76.5
- 删除成绩小于80分同学信息
bash
sqlite> DELETE FROM students WHERE score < 80;
sqlite> SELECT * FROM students;
1|张三|18|92.0
2|李四|19|93.5
四、C++通过SQLite开发库 接入sqlite数据库
1. SQLite库的常用api介绍
使用SQLite库的api时,一定要包含头文件 <sqlite3.h>
- 数据库连接管理:
(1)用数据库连接句柄 与 数据库文件进行连接
bash
int sqlite3_open(const char *filename, sqlite3 **ppDb);
-功能:打开⼀个数据库连接。如果数据库文件不存在,则创建它
-参数:filename - 数据库⽂件的路径,
ppDb:⼀个指向sqlite3*的指针。函数成功后会在这个指针里填入数据库连接句柄
-返回值:SQLITE_OK 表示创建成功,否则为错误码
(2)断开数据库连接句柄 与 数据库文件的连接,释放数据库连接句柄的空间
bash
int sqlite3_close(sqlite3* db);
-功能:关闭打开的数据库连接,并释放所有资源
-参数:要关闭的数据库连接句柄
-返回值:SQLITE_OK 表示成功,如果还有未完成的预处理语句
(3)返回某个数据库连接 sqlite3 * db 最近一次错误的文本描述(在操作失败后调用它来获取错误原因)
bash
const char *sqlite3_errmsg(sqlite3* db);
-功能:返回某个数据库连接 sqlite3* db 最近一次错误的文本描述(在操作失败后调用它来获取错误原因);
方便用户在 sqlite3_prepare_v2 、sqlite3_step 、sqlite3_exec等 API调用失败时打印错误日志、定位原因
-参数:db数据库连接句柄
-返回值:只想错误信息字符串的指针。如果还有查询没有完成,将返回SQLITE_BUSY禁止关闭的错误消息
- 执行SQL语句
(1) 直接执行SQL语句
bash
int sqlite3_exec(sqlite3* db, const char *sql, int (*callback)(void*, int, char**, char**),
void *arg, char** errmsg);
-功能:执行一条 或 多条SQL语句,适合不返回数据的语句,如CREATE、INSERT
-参数:db: 数据库连接句柄
sql: 要执⾏的SQL语句字符串
callback: 回调函数指针,每有⼀条结果记录就产生去调用一次回调函数,可以设置为NULL
arg: 传递给回调函数的第⼀个参数,可以设置为NULL
errmsg: 指向错误信息的指针。必须⽤sqlite3_free释放
-返回值:执⾏成功返回SQLITE_OK,否则返回错误码
当 sqlite3_exec函数 执行多条SQL语句,返回多条结果记录时,第三个 和 第四个参数(callback 和 arg)才有用;
当 sqlite3_exec函数 只执行一条SQL语句时,可以将第三个 和 第四个参数(callback 和 arg)置为NULL
(2) 将SQL语句编译成⼀个预处理语句对象,绑定参数后,再执行
将⼀条SQL语句编译成⼀个预处理语句对象
bash
int sqlite3_prepare_v2( sqlite3 *db, const char *zSql,int nByte,
sqlite3_stmt **ppStmt, const char **pzTail);
-功能:将⼀条SQL语句编译成⼀个预处理语句对象,为绑定参数 和 执行做准备
-参数:db: 数据库连接句柄
zSql: 要编译的SQL语句文本
nByte: SQL文本的⻓度(字节),-1表示自动计算到\0结束
ppStmt: 指向sqlite3_stmt*的指针,表示输出预处理结果语句的句柄
pzTail: 指向未使用的SQL部分指针,通常置为NULL
-返回值:编译成功返回SQLITE_K,否则返回错误码
向预处理语句中的指定参数位置绑定参数 (参数的序号,从1开始)
bash
int sqlite3_bind_int64(sqlite3_stmt*, int index, sqlite3_int64 value);
-功能:向预处理语句中的指定参数位置绑定⼀个64位的整数值
-参数:index - 参数的序号,从1开始
value - 要绑定的整数值
-返回值:SQLITE_OK表⽰绑定成功,否则为错误码
bash
int sqlite3_bind_text(sqlite3_stmt*, int index, const char *value, int len,
void(*destructor)(void*));
-功能:向预处理语句的指定参数位置绑定⼀个⽂本字符串
-参数: index - 参数的序号,从1开始
value - 要绑定的⽂本字符串
len - 字符串的⻓度(字节),-1表示自动计算到\0结束
destructor - ⽤于指定SQLite不会尝试释放该字符串
SQLITE_STATIC:SQLite不会尝试释放该字符串
SQLITE_TRANSIENT:SQLite会制作该字符串的副本
-返回值:SQLITE_OK表⽰绑定成功,否则为错误码
用于逐步执行预处理语句。⼀般用于执行查询和更新操作,并返回执行结果。
bash
int sqlite3_step(sqlite3_stmt *pStmt);
-功能:用于逐步执行预处理语句。⼀般用于执行查询和更新操作,并返回执行结果。
对于查询操作,sqlite3_step 需要多次调用,直到返回 SQLITE_DONE
-参数:pstmt - 预处理语句句柄
-返回值:SQLITE_ROW - 表示有⼀行结果数据就绪
SQLITE_DONE - 表示语句执行完成
否则表示有其他错误
从结果行的指定位置提取参数值 (结果行的列号从0开始)
bash
sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
-功能:从当前结果行中,以sqlite3_int64的形式获取指定文本列的值
-参数:iCol表⽰列号,从0开始
-返回值:以 sqlite3_int64 (通常就是 64 位整数)形式返回
bash
const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
-功能:从当前结果行中,以const unsigned char*的形式获取指定文本列的值
-参数:iCol表⽰列号,从0开始
-返回值:指向⽂本数据的指针。
销毁预处理语句对象,释放所有关联资源
bash
int sqlite3_finalize(sqlite3_stmt *pStmt);
-功能:销毁预处理语句对象,释放所有关联资源
-参数:pstmt - 要销毁的预处理语句句柄
-返回值:成功返回SQLITE_OK,否则为错误码
2. 实战演示
2.1 sqlite3_exec 直接执行SQL语句
使用SQLite库的api时,一定要包含头文件 <sqlite3.h>
数据库文件: /home/ubuntu/student.db
bash
sqlite> create table students(
(x1...> id integer primary key autoincrement,
(x1...> name text not null,
(x1...> age integer,
(x1...> };
bash
sqlite> select * from students;
1|张三|18
2|李四|19
3|王五|18
4|赵六|18
- sqlite3_exec 直接执行SQL语句
cpp
#include <sqlite3.h>
void create_table()
{
sqlite3* _db; // 数据库连接句柄
// 将数据库连接句柄_db 与 数据库文件进行连接
if(SQLITE_OK != sqlite3_open("/home/ubuntu/student.db", &_db))
{
// sqlite3_errmsg的作用:返回某个数据库连接 sqlite3* db 最近一次错误的文本描述
// (在操作失败后调用它来获取错误原因)
printf("打开数据库失败, db_name: %s\n", sqlite3_errmsg(_db))
}
printf("数据库初始化成功, db_name: %s\n", _db_path);)
// 构建 SQL语句
const std::string createSessionsTable =
"CREATE TABLE IF NOT EXISTS students ("
"id integer primary key autoincrement, "
"name text not null, "
"age integer, "
");";
char *errmsg = nullptr;
// sqlite3_exec 直接执行SQL语句
if(SQLITE_OK != sqlite3_exec(_db, createSessionsTable.c_str(), nullptr, nullptr, &errmsg))
{
printf("创建sessions表失败, errmsg: %s\n", errmsg);
sqlite3_free(errmsg); // 必须⽤sqlite3_free释放错误信息的指针
errmsg = nullptr;
return false;
}
printf("创建sessions表成功\n");
// 断开数据库连接句柄 与 数据库文件的连接,释放数据库连接句柄的空间
sqlite3_close(_db);
}
2.2 sqlite3_step 逐步执行预处理语句
使用SQLite库的api时,一定要包含头文件 <sqlite3.h>
数据库文件: /home/ubuntu/student.db
bash
sqlite> create table students(
(x1...> id integer primary key autoincrement,
(x1...> name text not null,
(x1...> age integer,
(x1...> };
bash
sqlite> select * from students;
1|张三|18
2|李四|19
3|王五|18
4|赵六|18
- sqlite3_step 执行预处理语句(插入命令,执行一次即可)
cpp
#include <sqlite3.h>
void insert_text(int _id, string _name, int _age)
{
sqlite3* _db; // 数据库连接句柄
// 将数据库连接句柄_db 与 数据库文件进行连接
if(SQLITE_OK != sqlite3_open("/home/ubuntu/student.db", &_db))
{
// sqlite3_errmsg 获取与数据库连接相关的最后⼀次错误操作的英文描述字符串(获取错误原因)
printf("打开数据库失败, db_name: %s\n", sqlite3_errmsg(_db))
}
printf("数据库初始化成功, db_name: %s\n", _db_path);
// 构建 SQL语句
const std::string sql ="INSERT INTO students (id, name, age) VALUES (?, ?, ?);";
// 将 SQL语句sql 编译成⼀个预处理语句对象stmt, 为绑定参数 和 执行做准备
sqlite3_stmt *stmt = nullptr;
if(SQLITE_OK != sqlite3_prepare_v2(_db, sql.c_str(), -1, &stmt, nullptr))
{
printf("准备SQL语句失败, errmsg: %s\n", sqlite3_errmsg(_db));
return false;
}
// 绑定参数
sqlite3_bind_int64(stmt, 1, static_cast<int64_t>(_id));
sqlite3_bind_text(stmt, 2, _name.c_str(), -1, SQLITE_TRANSIENT);
sqlite3_bind_int64(stmt, 3, static_cast<int64_t>(_age));
// 执行预处理语句(插入命令只执行一次)
if(SQLITE_DONE != sqlite3_step(stmt))
{
printf("执行SQL语句 (插入会话) 失败, errmsg: %s\n", sqlite3_errmsg(_db));
sqlite3_finalize(stmt);
return false;
}
sqlite3_finalize(stmt); // 执行完成后, 释放stmt资源
printf("执行SQL语句 (插入会话) 成功\n");
// 断开数据库连接句柄 与 数据库文件的连接,释放数据库连接句柄的空间
sqlite3_close(_db);
return false;
}
- sqlite3_step 逐步执行预处理语句(查询命令,一般执行多次)
cpp
struct stud
{
private:
int id;
string name;
int age;
};
std::vector<stud> insert_text(int _age)
{
sqlite3* _db; // 数据库连接句柄
// 将数据库连接句柄_db 与 数据库文件进行连接
if(SQLITE_OK != sqlite3_open("/home/ubuntu/student.db", &_db))
{
// sqlite3_errmsg 获取与数据库连接相关的最后⼀次错误操作的英文描述字符串(获取错误原因)
printf("打开数据库失败, db_name: %s\n", sqlite3_errmsg(_db))
}
printf("数据库初始化成功, db_name: %s\n", _db_path);
// 构建 SQL语句
const std::string sql ="SELECT id, name, age FROM students WHERE age = ?;";
// 将 SQL语句sql 编译成⼀个预处理语句对象stmt, 为绑定参数 和 执行做准备
sqlite3_stmt *stmt = nullptr;
if(SQLITE_OK != sqlite3_prepare_v2(_db, sql.c_str(), -1, &stmt, nullptr))
{
printf("准备SQL语句失败, errmsg: %s\n", sqlite3_errmsg(_db));
return false;
}
// 绑定参数
sqlite3_bind_int64(stmt, 1, static_cast<int64_t>(_age));
std::vector<stud> vec_stu;
// 执行预处理语句(查询命令一般执行多次,每次返回一行查询结果)
// 比如:查询年龄 18岁的同学,一共有三位,查询一次返回一位同学的信息,一共要执行 3次查询
while(SQLITE_ROW == sqlite3_step(stmt))
{
stud stu;
stu.id = static_cast<int>(sqlite3_column_int64(stmt, 0));
stu.name = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1));
stu.age = static_cast<int>(sqlite3_column_int64(stmt, 2));
vec_stu.push_back(stu);
}
sqlite3_finalize(stmt); // 执行完成后, 释放stmt资源
// 断开数据库连接句柄 与 数据库文件的连接,释放数据库连接句柄的空间
sqlite3_close(_db);
return vec_stu;;
}