前言:完全没接触过数据库,但老师课程设计要求数据存储在数据库怎么办???主包看了些网络上的资源,觉得讲得都不是很能快速上手,所以决定自己写一篇博客
SQLiteCpp是一个基于 C++ 封装的 SQLite 操作库,简化原生 C API 使用,可以用面向对象的方式更方便地操作数据库。
准备工作
安装 SQLiteCpp
从GitHub上下载 SQLiteCpp 源码
地址:https://github.com/SRombauts/SQLiteCpp
点击右上角绿色按钮「Code」→ 「Download ZIP」,解压得到一个 SQLiteCpp-master
文件夹
下载并准备 sqlite3.c/.h
SQLiteCpp 依赖原生 SQLite 的源码,所以我们去官网 https://www.sqlite.org/download.html
下载sqlite3.c
(源码),sqlite3.h
(头文件)这两个文件,用于编译
点击第二个“sqlite-amalgamation-*.zip”压缩包,
解压后就能得到.c和.h文件
往下滑,我的电脑是64位的windows系统,所以还下载了“Precompiled Binaries for Windows”的第二个压缩包sqlite3.dll,用于程序运行时动态链接
第三个压缩包“sqlite-tools-win-x64-3500100.zip”,是带命令行工具的,sqlite3.exe
可以在终端里手动打开 .db
文件查看和操作(非常适合调试数据库),推荐下载
把这些文件放入你的C++项目的一个 “sqlite”
文件夹中备用
用 Code::Blocks 创建 SQLiteCpp 静态库项目
后面需要连接SQL静态库,但我想直接连自己的(也可以网上下载别人的先测试,那就自己跳过这一部分)
打开 Code::Blocks → File → New → Project,创建一个Static Library
将 SQLiteCpp 源码添加进来
把SQLiteCpp-master/src/
下的所有 .cpp
文件和SQLiteCpp-master/include/SQLiteCpp/下所有
的.h文件
都添加进项目
再把 sqlite3.c
和 sqlite3.h
和sqlite3ext.h加进来(SQLiteCpp 依赖它)
设置头文件搜索路径
虽然你添加了文件,但 编译器默认不会自动搜索别的文件夹,你需要手动告诉它在哪里找
Build options → Search directories → Compiler,添加SQLiteCpp-master/include的文件地址
以及SQLiteCpp\sqlite-amalgamation-3500100的地址(是 sqlite3.h
所在目录)
构建静态库
编译后,会生成一个 .a
文件(MinGW 下是 libSQLiteCppStatic.a
,MSVC 是 .lib
)
编译成功
.a文件在bin目录的debug文件下
添加 SQLite3 源码文件
创建一个C++项目
在项目中点击右键 → Add files...
添加你下载的 sqlite3.c文件(噢我的文件夹好像有点多,下次注意)
添加 SQLiteCpp 的头文件路径
主包第一次弄哈,为了安全起见只修改当前项目的编译器配置,而不会影响整个 Code::Blocks 环境。
右键项目 → Build Options...,
左边选你的项目名(不是 "Debug"也不是 "Release")这样设置就只对当前项目生效。
点击Search directories → Compiler,点击"Add"
复制你SQLiteCpp-master/include的文件地址和\sqlite-amalgamation-3500100(sqlite3.h 所在目录)的文件地址,添加
添加库文件路径
Search directories → Linker,添加.a的包含文件
SQLiteCppStatic\bin\Debug
链接库文件
Linker settings →
Link libraries,点击 Add
尝试运行
输入以下代码,如能正常编译并运行 → 就代表 .a
链接库成功了
#include <SQLiteCpp/SQLiteCpp.h>
#include <iostream>
int main() {
try {
SQLite::Database db("test.db", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
db.exec("CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY, name TEXT);");
db.exec("INSERT INTO test (name) VALUES ('Alice');");
std::cout << "数据库操作成功!" << std::endl;
} catch (std::exception& e) {
std::cerr << "错误:" << e.what() << std::endl;
}
return 0;
}
哇哦,主包运行成功了,成功一小步,go on!go on!
接下来可以开始在你的系统中使用 SQLite 数据库来替代 CSV 或手动数据管理了
把原项目代码连接数据库
前面创建的静态库(.a 文件)是你程序的“工具箱”,提供操作数据库的各种 C++ 接口
它只需要被链接进你的课设项目;不需要单独写代码去操作它;编译一次即可,后续只用它就行
手动向 school.db
数据库插入数据
下载 DB Browser for SQLite(图形界面,操作简单,无需写代码)
网址:https://sqlitebrowser.org/dl/
我下载的第三个,我看到下面还有个轻便版(portable)的
生成school.db文件
在你的项目运行如下(类似,根据你的需要)代码
void initDatabase() {
// 如果数据库文件已存在,则跳过创建
if (std::filesystem::exists("school.db")) return;
try {
SQLite::Database db("school.db", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
// 创建 users 表
db.exec("CREATE TABLE users ("
"type TEXT NOT NULL,"
"id TEXT PRIMARY KEY,"
"username TEXT,"
"password TEXT,"
"phone TEXT,"
"class TEXT,"
"major TEXT"
");");
// 创建 courses 表
db.exec("CREATE TABLE courses ("
"id TEXT PRIMARY KEY,"
"name TEXT,"
"time TEXT,"
"location TEXT,"
"teacherId TEXT"
");");
// 创建 student_courses 表
db.exec("CREATE TABLE student_courses ("
"stuId TEXT,"
"courseId TEXT,"
"PRIMARY KEY (stuId, courseId)"
");");
// 创建 student_grades 表
db.exec("CREATE TABLE student_grades ("
"stuId TEXT,"
"courseId TEXT,"
"grade INTEGER,"
"PRIMARY KEY (stuId, courseId)"
");");
cout << "数据库和表创建成功。" << std::endl;
} catch (const std::exception& e) {
cerr << "创建数据库或表时出错: " << e.what() << std::endl;
}
}
运行后,Code::Blocks 项目所在的目录下就会生成一个 school.db
文件
向表中插入数据
打开DB Browser for SQLite,点击左上角,打开school.db
点击“浏览数据”,可以在“表”处选择要编辑的表格,点击图示“插入”
录入完数据后,点击“写入更改”
这个软件真实太好用了,欢迎大家前去探索实操!!!
补充
嘻嘻,主包已经成了,在现在的AI大环境下其实还是蛮简单的嘛~
再补充几个主包操作过程中学习到的东西,是自己的小总结,可能有些不太准确的,欢迎大家前来探讨.
通过codeblocks程序向数据库载入数据,写入中文时会在数据库中自动以二进制存储,再读取数据时能直接正常显示中文;但如果直接在数据库插入数据时写入中文不能正常显示(数据库的字符编码是utf-8,但codeblocks不是,若自己改动的话输出框会显示乱码,这点codeblocks还是挺不好的‘很多编辑器的字符编码现在都是utf-8了’)
再来分享几个数据库常用简单操作
数据库的打开/创建
SQLite::Database db("school.db", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
//SQLite::Database是SQLite C++封装库(数据库文件路径‘一般当前目录下’,读写|打开模式‘不存在则创建’)
创建表
db.exec("CREATE TABLE users (" //CREATE TABLE是SQLite建表语句,定义users表结构
"type TEXT NOT NULL," //TEXT定义文本类型,NOT NULL表示必填
"id TEXT PRIMARY KEY," //主键(PRIMARY KEY),保证唯一
"username TEXT,"
"password TEXT,"
"phone TEXT,"
"class TEXT,"
"major TEXT"
");");
数据库连接与查询
SQLite::Statement query(db, "SELECT type, id, username, password, phone, class, major FROM users"); //创建一个SQLite::Statement对象query,执行SQL查询语句(从users表中选择type,id…这些列的数据)
while (query.executeStep()) { //执行查询并移动到下一行(只要还有下一行就返回true)
string type = query.getColumn(0).getString(); //从查询结果行的第0列获取字符串类型的数据
string id = query.getColumn(1).getString(); //第1列
}
清空表数据
db.exec("DELETE FROM users"); //使用exec方法执行SQL语句DELETE FROM,删除users表中的所有记录
SQLite::Statement insert(db, "INSERT INTO users VALUES (?, ?, ?, ?, ?, ?, ?)"); //创建了一个SQLite::Statement对象insert,绑定到db数据库,并准备了一条插入数据的SQL语句,“?”是占位符
insert.bind(1, u->getUserType()); //使用bind方法将数据绑定到第一个占位符
insert.bind(2, u->getId()); //第二个
insert.bind(3, u->getUsername());
insert.exec(); //执行插入语句
insert.reset(); //重置insert语句对象,为下一次插入操作做准备
好了,拜拜,有些事情好像真的还是不要将就的好,努力努力,学习到了东西,这种充实感其实好像也很不错~