附录:SQLite介绍

目录

[1. SQLite介绍](#1. SQLite介绍)

[2. ubuntu下SQLite命令行和开发库安装](#2. ubuntu下SQLite命令行和开发库安装)

[3. 终端使用介绍](#3. 终端使用介绍)

[3.1 常用命令](#3.1 常用命令)

[3.2 使用演示](#3.2 使用演示)

[4. 常用api介绍](#4. 常用api介绍)

[5. 使用案例](#5. 使用案例)


1. SQLite介绍

SQLite官网:SQLite Home Page

SQLite菜鸟教程:SQLite 数据类型 | 菜鸟教程

SQLite是一个开源、轻量级、零配置、无服务器、自包含、事务性、支持标准SQL、跨平台的数据库管理系统。

  • 开源:免费使用,源码透明
  • 轻量级:整个库非常小,编译之后仅需几百KB
  • 零配置:无需安装、启动、停止或配置任何数据库服务器进程
  • 无服务器:SQLite没有独立的服务器进程,应用程序直接通过函数调用读写磁盘上的数据库文件
  • 自包含:整个数据库就是一个独立的、跨平台的单个文件(通常是.db后缀),文件中包含所有表、索引、数据和元信息
  • 事务性:完全支持ACID(原子性、一致性、隔离性、持久性)事务,即使系统崩溃或断电也嗯呢保证数据完整性
  • 支持标准SQL:它使用SQL语句来管理和查询数据,最多支持128TB
  • 跨平台:数据库文件跨平台
  • 简单易用:只需包含一个sqlite3.h和一个库文件即可

一般常用于嵌入式系统、移动开发中。

2. ubuntu下SQLite命令行和开发库安装

bash 复制代码
> sudo apt install sqlite3 # 安装 sqlite3 命令⾏⼯具
> sudo apt install libsqlite3-dev # 安装 sqlite 开发包
> dpkg -L libsqlite3-dev # 列出已安装的 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

编译时链接sqlite3库

bash 复制代码
makefile⽂件:
g++ main.cpp -o my_program -lsqlite3
CMakelists.txt:
target_link_libraries(${SDK_NAME} sqlite3)

3. 终端使用介绍

3.1 常用命令

数据库操作命令:

|------------------|------------|-------------------------------|
| 命令 | 说明 | 示例 |
| .open ⽂件名 | 打开或创建数据库⽂件 | .open 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 |
| .indexes [表名] | 显示索引 | .indexes students |

3.2 使用演示

sql 复制代码
> sqlite3 # 打开 sqlite 命令⾏⼯具
sqlite> .help # 查看帮助信息
sqlite> .open student.db # 创建student数据库,数据库⽂件名称为student.db
sqlite> .databases # 验证数据库。检查当前连接了哪些数据库,以及数据库的详细状态
信息
sqlite> .tables # 查看所有表
sqlite> CREATE TABLE students( #创建学⽣表
(x1...> id INTEGER PRIMARY KEY AUTOINCREMENT,
(x1...> name TEXT NOT NULL,
(x1...> age INTEGER,
(x1...> score REAL
(x1...> );
sqlite> .schema students # 查看表结构
sqlite> INSERT INTO students(name, age, score) VALUES # students中插⼊数据
...> ('张三', 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
sqlite> DELETE FROM students WHERE score < 80; # 删除成绩⼩于80分同学信息
sqlite> SELECT * FROM students;
1|张三|18|92.0
2|李四|19|93.5

4. 常用api介绍

sql 复制代码
数据库连接管理:
int sqlite3_open(const char *filename, sqlite3 **ppDb);
功能:打开⼀个数据库连接。如果数据库⽂件不存在,则创建它
参数:filename - 数据库⽂件的路径,
ppDb:⼀个指向sqlite3*的指针。函数成功后会在这个指针⾥填⼊数据库连接句柄
返回值:SQLITE_OK 表⽰创建成功,否则为错误码

int sqlite3_close(sqlite3* db);
功能:关闭打开的数据库连接,并释放所有资源
参数:要关闭的数据库连接句柄
返回值:SQLITE_OK表⽰成功,如果还有未完成的预处理语句

const char *sqlite3_errmsg(sqlite3* db);
功能:获取与数据库连接相关的最后⼀次错误操作的英⽂描述字符串。在操作失败后调⽤它来获取错误
原因
参数:db数据库连接句柄
返回值:只想错误信息字符串的指针。如果还有查询没有完成,将返回SQLITE_BUSY禁⽌关闭的错误消息 

执⾏SQL语句
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,否则返回错误码

int sqlite3_bind_int64(sqlite3_stmt*, int index, sqlite3_int64 value);
功能:向预处理语句中的指定参数位置绑定⼀个64位的整数值
参数:index - 参数的序号,从1开始
value - 要绑定的整数值
返回值:SQLITE_OK表⽰绑定成功,否则为错误码

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表⽰绑定成功,否则为错误码

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:传递给回调函数的第⼀个参数
errmsg:只想错误信息的指针。必须⽤sqlite3_free释放
返回值:执⾏成功返回SQLITE_OK,否则返回错误码

int sqlite3_step(sqlite3_stmt *pStmt);
功能:⽤于逐步执⾏预处理语句。⼀般⽤于执⾏查询和更新操作,并返回执⾏结果。对于查询操作,
sqlite3_step 需要多次调⽤,直到返回 SQLITE_DONE
参数:pstmt - 预处理语句句柄
返回值: SQLITE_ROW - 表⽰有⼀⾏结果数据就绪
SQLITE_DONE - 表⽰语句执⾏完成
否则表⽰有其他错误

const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
功能:从当前结果⾏中,以const unsigned cht*的形式获取制定⽂本列的值
参数:iCol表⽰列号,从0开始
返回值:指向⽂本数据的指针。

int sqlite3_finalize(sqlite3_stmt *pStmt);
功能:销毁预处理语句对象,释放所有关联资源
参数:pstmt - 要销毁的预处理语句句柄
返回值:成功返回SQLITE_OK,否则为错误码

5. 使用案例

下面持久化存储学生信息,学生基本信息包括学号、姓名、性别、年龄、学分

cpp 复制代码
#include <iostream>
using namespace std;
#include <sqlite3.h>
struct StudentInfo
{
    StudentInfo(const std::string &name, const std::string &gender, int age,
                double gap)
        : name(name), gender(gender), age(age), gap(gap)
    {
    }
    std::string name;
    std::string gender;
    int age;
    double gap;
};

class StudentDB
{
public:
    StudentDB(const std::string &dbName)
    {
        // 创建数据库
        if (SQLITE_OK != sqlite3_open("student.db", &_db))
        {
            std::cout << "open student.db failed" << std::endl;
            exit(-1);
        }
        // 对数据库初始化 - 创建学⽣表
        if (!initDataBase())
        {
            std::cout << "init database failed" << std::endl;
            exit(-1);
        }
    }
    ~StudentDB()
    {
        if (_db)
        {
            sqlite3_close(_db);
            _db = nullptr;
        }
    }
    bool
    insertStudentInfo(const StudentInfo &info)
    {
        // 构建sql语句
        std::string sql = "INSERT INTO student(name, gender, age, gap)"
                          "VALUES(?, ?, ?, ?);";
        // 准备SQL语句
        sqlite3_stmt *stmt = nullptr;
        if (SQLITE_OK != sqlite3_prepare_v2(_db, sql.c_str(), -1, &stmt,
                                            nullptr))
        {
            std::cout << "prepare sql failed: " << sqlite3_errmsg(_db) << std::endl;
            return false;
        }
        // 绑定参数 sqlite3_bind_text(stmt, 1, info.name.c_str(), -1, SQLITE_TRANSIENT);
        sqlite3_bind_text(stmt, 2, info.gender.c_str(), -1, SQLITE_TRANSIENT);
        sqlite3_bind_int(stmt, 3, info.age);
        sqlite3_bind_double(stmt, 4, info.gap);
        // 执⾏SQL语句,检查是否执⾏成功
        if (SQLITE_DONE != sqlite3_step(stmt))
        {
            std::cout << "execute sql failed: " << sqlite3_errmsg(_db) << std::endl;
            sqlite3_finalize(stmt);
            return false;
        }
        // 执⾏完sql,释放stmt
        sqlite3_finalize(stmt);
        std::cout << "insert student info success" << std::endl;
        return true;
    }
    bool
    queryStudentInfo(const std::string &name)
    {
        // 构建sql语句
        std::string sql = "SELECT * FROM student WHERE name = ?";
        // 准备SQL语句
        sqlite3_stmt *stmt = nullptr;
        if (SQLITE_OK != sqlite3_prepare_v2(_db, sql.c_str(), -1, &stmt, nullptr))
        {
            std::cout << "prepare sql failed: " << sqlite3_errmsg(_db) << std::endl;
            return false;
        }
        // 绑定参数 sqlite3_bind_text(stmt, 1, name.c_str(), -1, SQLITE_TRANSIENT);
        // 执⾏SQL语句,检查是否执⾏成功
        int result = sqlite3_step(stmt);
        if (SQLITE_ROW != result && SQLITE_DONE != result)
        {
            std::cout << "execute sql failed: " << sqlite3_errmsg(_db) << std::endl;
            sqlite3_finalize(stmt);
            return false;
        }
        // 执⾏完sql,释放stmt sqlite3_finalize(stmt);
        std::cout << "query student info success" << std::endl;
        return true;
    }

    bool queryAllStudentInfo()
    {
        // 构建sql语句
        std::string sql = "SELECT * FROM student";
        // 准备SQL语句
        sqlite3_stmt *stmt = nullptr;
        if (SQLITE_OK != sqlite3_prepare_v2(_db, sql.c_str(), -1, &stmt,
                                            nullptr))
        {
            std::cout << "prepare sql failed: " << sqlite3_errmsg(_db) << std::endl;
            return false;
        }
        // 执⾏SQL语句,检查是否执⾏成功
        int result = sqlite3_step(stmt);
        if (SQLITE_ROW != result && SQLITE_DONE != result)
        {
            std::cout << "execute sql failed: " << sqlite3_errmsg(_db) << std::endl;
            sqlite3_finalize(stmt);
            return false;
        }
        std::cout
            << "-------------------student table info:-----------------"
            << std::endl;
        // 遍历结果集
        while (SQLITE_ROW == result)
        {
            // 表结构是 id, name, gender, age, gap,所以列索引从1开始获取我们需要的值
            std::string name(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1)));
            std::string gender(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 2)));
            int age = sqlite3_column_int(stmt, 3);
            double gap = sqlite3_column_double(stmt, 4);
            std::cout << "name: " << name << ", gender: " << gender << ", age:" << age << ",gap : " << gap << std::endl;
            result = sqlite3_step(stmt);
        }
        // 检查是否还有更多的⾏ if (SQLITE_DONE != result)
        {
            std::cout << "execute sql failed: " << sqlite3_errmsg(_db) << std::endl;
            return false;
        }
        std::cout << "-------------------student table info end-----------------"<< std::endl;
        // 执⾏完sql,释放stmt
        sqlite3_finalize(stmt);
        std::cout << "query all student info success" << std::endl;
        return true;
    }
    // 修改学⽣信息
    bool updateStudentInfo(const std::string &name, const StudentInfo &info)
    {
        // 构建sql语句
        std::string sql = "UPDATE student SET name = ?, gender = ?, age = ?,gap =? WHERE name = ? ";
        // 准备SQL语句
        sqlite3_stmt *stmt = nullptr;
        if (SQLITE_OK != sqlite3_prepare_v2(_db, sql.c_str(), -1, &stmt,
                                            nullptr))
        {
            std::cout << "prepare sql failed: " << sqlite3_errmsg(_db) << std::endl;
            return false;
        }
        // 绑定参数 sqlite3_bind_text(stmt, 1, info.name.c_str(), -1, SQLITE_TRANSIENT);
        sqlite3_bind_text(stmt, 2, info.gender.c_str(), -1, SQLITE_TRANSIENT);
        sqlite3_bind_int(stmt, 3, info.age);
        sqlite3_bind_double(stmt, 4, info.gap);
        sqlite3_bind_text(stmt, 5, name.c_str(), -1, SQLITE_TRANSIENT);
        // 执⾏SQL语句,检查是否执⾏成功
        if (SQLITE_DONE != sqlite3_step(stmt))
        {
            std::cout << "execute sql failed: " << sqlite3_errmsg(_db) << std::endl;
            sqlite3_finalize(stmt);
            return false;
        }
        // 执⾏完sql,释放stmt sqlite3_finalize(stmt);
        std::cout << "update student info success" << std::endl;
        return true;
    }
    // 删除学⽣信息
    bool deleteStudentInfo(const std::string &name)
    {
        // 构建sql语句
        std::string sql = "DELETE FROM student WHERE name = ?";
        // 准备SQL语句
        sqlite3_stmt *stmt = nullptr;
        if (SQLITE_OK != sqlite3_prepare_v2(_db, sql.c_str(), -1, &stmt,
                                            nullptr))
        {
            std::cout << "prepare sql failed: " << sqlite3_errmsg(_db) << std::endl;
            return false;
        }
        // 绑定参数 sqlite3_bind_text(stmt, 1, name.c_str(), -1, SQLITE_TRANSIENT);
        // 执⾏SQL语句,检查是否执⾏成功
        if (SQLITE_DONE != sqlite3_step(stmt))
        {
            std::cout << "execute sql failed: " << sqlite3_errmsg(_db) << std::endl;
            sqlite3_finalize(stmt);
            return false;
        }
        // 执⾏完sql,释放stmt sqlite3_finalize(stmt);
        std::cout << "delete student info success" << std::endl;
        return true;
    }

private:
    bool initDataBase()
    {
        // 创建数据库表
        const std::string studentTab = "CREATE TABLE IF NOT EXISTS student( "
                                       "id INTEGER PRIMARY KEY, "
                                       "name TEXT NOT NULL, "
                                       "gender TEXT NOT NULL, "
                                       "age INTEGER NOT NULL, "
                                       "gap REAL NOT NULL)";
        char *errMsg = nullptr;
        if (SQLITE_OK != sqlite3_exec(_db, studentTab.c_str(), nullptr,
                                      nullptr, &errMsg))
        {
            std::cout << "create table failed: " << errMsg << std::endl;
            sqlite3_free(errMsg);
            return false;
        }
        std::cout
            << "create studentTab success" << std::endl;
        return true;
    }

private:
    sqlite3 *_db;
};
int main()
{
    StudentInfo info1("张三", "男", 18, 3.5);
    StudentInfo info2("李四", "男", 19, 3.8);
    StudentInfo info3("王五", "男", 20, 2.9);
    StudentInfo info4("赵六", "⼥", 21, 3.0);
    StudentDB db("student.db");
    db.insertStudentInfo(info1);
    db.insertStudentInfo(info2);
    db.insertStudentInfo(info3);
    db.insertStudentInfo(info4);
    db.queryAllStudentInfo();
    info1.age = 20;
    db.updateStudentInfo("张三", info1);
    db.queryAllStudentInfo();
    db.deleteStudentInfo("张三");
    db.queryAllStudentInfo();
    return 0;
}

运行程序,会在当前目录下生成一个student.db的数据库文件,里面存储表结构和数据信息。

bash 复制代码
bit@bit08:~/will/test-cpp-proj/testsqlite3$ g++ testSQLite.cpp -o testsqlite3 -
lsqlite3
bit@bit08:~/will/test-cpp-proj/testsqlite3$ ./testsqlite3
create studentTab success
insert student info success
insert student info success
insert student info success
insert student info success
-------------------student table info:-----------------
name: 张三, gender: 男, age: 18, gap: 3.5
name: 李四, gender: 男, age: 19, gap: 3.8
name: 王五, gender: 男, age: 20, gap: 2.9
name: 赵六, gender: ⼥, age: 21, gap: 3
-------------------student table info end-----------------
query all student info success
update student info success
-------------------student table info:-----------------
name: 张三, gender: 男, age: 20, gap: 3.5
name: 李四, gender: 男, age: 19, gap: 3.8
name: 王五, gender: 男, age: 20, gap: 2.9
name: 赵六, gender: ⼥, age: 21, gap: 3
-------------------student table info end-----------------
query all student info success
delete student info success
-------------------student table info:-----------------
name: 李四, gender: 男, age: 19, gap: 3.8
name: 王五, gender: 男, age: 20, gap: 2.9
name: 赵六, gender: ⼥, age: 21, gap: 3
-------------------student table info end-----------------
query all student info success
相关推荐
毕设十刻2 小时前
基于Vue的新生入学报道管理系统(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js
Vic101012 小时前
Redis防重复点击与分布式锁
java·数据库·redis·分布式
罗政2 小时前
mybatis-plus插件解决sql报错:this is incompatible with sql_mode=only_full_group_by ”
数据库·sql·mybatis
leo_qiu_s2 小时前
MERGE INTO语句
数据库
未来之窗软件服务2 小时前
幽冥大陆(六十二) 多数据库交叉链接系统Go语言—东方仙盟筑基期
数据库·人工智能·oracle·golang·数据库集群·仙盟创梦ide·东方仙盟
U-52184F693 小时前
【CGAL实战】深入理解二维受约束 Delaunay 网格生成
数据库·算法
rannn_1113 小时前
【SQL题解】力扣高频 SQL 50题|DAY4
数据库·后端·sql·leetcode·题解
q行3 小时前
MySQL学习日志--DQL和它的七大字句
数据库·学习·mysql
张人玉3 小时前
WPF HTTPS 通信示例使用说明
数据库·网络协议·http·c#·wpf