前言:完全沒接觸過數據庫,但老師課程設計要求數據存儲在數據庫怎么辦???主包看了些網絡上的資源,覺得講得都不是很能快速上手,所以決定自己寫一篇博客
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語句對象,為下一次插入操作做準備
?好了,拜拜,有些事情好像真的還是不要將就的好,努力努力,學習到了東西,這種充實感其實好像也很不錯~