一、SQLite与DbGate简介
(一)SQLite[1][3]
SQLite 是一个部署最广泛、用 C 语言编写的数据库引擎,属于嵌入式数据库,其作为库被软件开发人员嵌入到应用程序中。
SQLite 的设计允许在不安装数据库管理系统或不需要数据库管理员的情况下运行程序。与客户端 - 服务器数据库管理系统不同,SQLite 引擎没有应用程序与之通信的独立进程。相反,链接器将 SQLite 库(静态或动态)集成到应用程序中,该应用程序通过简单的函数调用使用 SQLite 的功能,减少数据库操作的延迟;对于并发很少的简单查询,SQLite 性能受益于避免进程间通信的开销。
SQLite使用优势:
①不需要一个单独的服务器进程或操作的系统(无服务器的);
②SQLite是轻量级的,完全配置时小于400KiB。同时,不依赖于任何外部库/模块;
③一个完整的SQLite数据库是存储在一个单一的跨平台的磁盘文件;
④SQLite事务完全兼容ACID,允许从多个进程或线程安全访问。同时,SQLite支持SQL92标准的大多数查询语言的功能;
⑤可多操作系统运行,包括Windows(Win32/WinCE/WinRT)、UNIX(Linux/Mac OS-X/Android/iOS)。
(二)DbGate[2]
DbGate(Community)是一个开源免费的SQL+noSQL数据库的智能化管理、数据可视化客户端。
DbGate目标:
①免费和开源;
②简单且功能强大,在工具栏中大量使用上下文菜单,提供便捷、易懂的使用体验;
③能够在多操作系统/多平台运行,包括Windows、Linux、Mac、Web browser、Mobile web(未来构想);
④稳定且鲁棒,保证数据库的安全正确运行;
⑤为大型数据库做准备,永远不将完整的表或查询结果加载到内存中,全部使用流操作;
⑥可使用脚本,基于dbgate nodejs 库包。
二、回调函数简述
回调函数是一种在特定事件发生或特定条件满足时被调用的函数。回调函数通常作为参数传递给另一个函数,这个接收回调函数的函数在执行过程中,当满足特定条件时,会调用传递进来的回调函数。它的作用是允许在特定的时刻或特定的操作完成后执行自定义的逻辑。
回调函数的使用场景:
①异步编程;
②事件处理;
③遍历数据结构对元素进行特定操作等。
使用回调函数的优势:
①增加代码的灵活性。可以根据不同的需求传递不同的回调函数,从而在相同的执行流程中实现不同的行为;
②分离关注点。将特定操作的逻辑封装在回调函数中,使主函数更加专注于核心任务,从而提高代码的可读性和可维护性;
③实现异步执行。在异步编程中,回调函数使得程序能够在等待异步操作完成的同时继续执行其他任务,提高程序的相应性能。
注释:
异步编程:异步编程是一种编程方式,它允许程序在执行某些耗时操作时,不会阻塞主线程的执行,而是继续执行其他任务,当耗时操作完成后,再通过回调函数、事件触发或其他机制来处理操作结果(传统的同步编程中,程序会按照顺序依次执行每个任务,等待一个任务完成后才会开始下一个任务)。
三、实践Demo
Demo主要参考资料:SQLite – C/C++ | 菜鸟教程 (runoob.com)
1、Windows操作系统下安装编译SQLite3的方法详见参考资料[5-6],已编译好的3.46.1版本SQLite文件库可见绑定资源。
2、常规配置测试项目的VC++目录和链接器:
①项目属性页->VC++目录->添加SQLite包含目录->添加SQLite库目录->应用;
②项目属性页->链接器->输入->添加附加依赖项sqlite3.lib->应用。
3、测试代码:
#include <iostream>
#include <sqlite3.h>
using namespace std;
static int callback(void* NotUsed, int argc, char** argv, char** azColName) {
NotUsed = 0;
for (int i = 0; i < argc; i++) {
std::cout << azColName[i] << " = " << (argv[i] ? argv[i] : "NULL") << std::endl;
}
std::cout << std::endl;
return 0;
}
int main() {
sqlite3* db;
char* errMsg = 0;
int rc;
// 打开数据库,如果不存在则创建
rc = sqlite3_open("example.db", &db);
if (rc) {
std::cerr << "无法打开数据库: " << sqlite3_errmsg(db) << std::endl;
sqlite3_close(db);
return 1;
}
else {
std::cout << "数据库打开成功" << std::endl;
}
// 创建表
std::string sql = "CREATE TABLE IF NOT EXISTS MyTable("
"ID INTEGER PRIMARY KEY AUTOINCREMENT,"
"Name TEXT,"
"Age INTEGER);";
rc = sqlite3_exec(db, sql.c_str(), callback, 0, &errMsg);
if (rc != SQLITE_OK) {
std::cerr << "SQL 错误: " << errMsg << std::endl;
sqlite3_free(errMsg);
}
else {
std::cout << "表创建成功" << std::endl;
}
// 插入数据
sql = "INSERT INTO MyTable(Name, Age) VALUES('John', 30);";
rc = sqlite3_exec(db, sql.c_str(), callback, 0, &errMsg);
if (rc != SQLITE_OK) {
std::cerr << "SQL 错误: " << errMsg << std::endl;
sqlite3_free(errMsg);
}
else {
std::cout << "数据插入成功" << std::endl;
}
// 查询数据
sql = "SELECT * FROM MyTable;";
rc = sqlite3_exec(db, sql.c_str(), callback, 0, &errMsg);
if (rc != SQLITE_OK) {
std::cerr << "SQL 错误: " << errMsg << std::endl;
sqlite3_free(errMsg);
}
// 关闭数据库
sqlite3_close(db);
return 0;
}
4、打开DbGate连接数据库:
①.db数据库文件获取。若未设置特定的数据库文件存储位置,那么VS2019编程平台会将其存储在解决方案(.sln)同目录下;
②连接SQLite数据库。File->Add connection->select connection type->选择对应的数据库类型(此处为SQLite)->在Database file处导入.db文件->Connect->即可。
四、实践结果
SQLite下载地址
Tags · sqlite/sqlite · GitHub(旧版本源码)
SQLite Download Page(最新版本,包含预编译二进制文件)
DbGate下载地址
DbGate | Open Source SQL+noSQL Database Client
DB Browser for SQLite下载地址(Github 21.1k星)
https://github.com/sqlitebrowser/sqlitebrowser
参考资料:
[1] https://en.wikipedia.org/wiki/SQLite
[2] An Introduction To The SQLite C/C++ Interface
[3] SQLite 教程 | 菜鸟教程 (runoob.com)
[4] 10 个 SQLite 数据库可视化工具(GUI)推荐 (zzxworld.com)
[5] Win11下基于VS2022编译SQLite3源码_sqlite下载 win11-CSDN博客(最新版本使用方法)
[6] sqlite/doc/compile-for-windows.md at master · sqlite/sqlite · GitHub(旧版本源码MSVC编译方法)