使用C++对SQLite3数据库进行增、删、改、查操作实例
使用C++对SQLite3数据库进行增、删、改、查操作实例
- 概述
- 下载和编译SQLiteC++源码
- 构建数据库操作示例工程
概述
SQLite经常被用于嵌入式数据库,经常用于需要本地存储信息(如配置信息、应用数据、日志等)的应用程序,小巧方便,零配置。SQLite提供了C语言的原生接口API对数据库进行操作,但使用起来相对繁琐,不太直观。使用C++操作SQLite,为了提供更加友好和直观的操作,需要将原生C API进行类封装,本文将介绍如何使用SQLiteC++
作为类库对SQLite数据库进行操作。
注:本文将使用 MSVC v19.29 + cmake v3.25.1 进行编译,其中MSVC编译器需要安装Visual Studio 2019。以下操作都在Windows10操作系统进行
下载和编译SQLiteC++源码
-
点击这里下载SQLiteC++的稳定版源码
-
解压源代码压缩包
-
进入解压后的源代码目录,目录结构如下所示:
-
找到
CMakeLists.txt
文件,这是编译该工程的脚本,脚本默认是将工程编译为静态链接库,我们可以通过修改该脚本将其编译为动态链接库,本文将遵循脚本内容,将工程编译为静态库。可选操作: 修改
CMakeLists.txt
文件的第209
行,可以将${SQLITECPP_DOC} ${SQLITECPP_SCRIPT}
两项从静态库编译中去除 -
打开Windows命令行工具(PowerShell或cmd),将命令行中的本地目录定位到解压的源代码目录下(本例为
H:\sqlite3\SQLiteCpp-3.3.1
),执行以下命令进行预编译:mkdir build cd build cmake ../
执行结果如下图所示:
-
预编译完成后,执行下面这个命令对源代码进行编译
cmake --build . --config release
生成的两个静态库如下图红框中标注的文件,这两个文件就是我们项目中操作SQLite数据所需的两个静态库。
其中
sqlite3.lib
封装了sqlite3数据库和APISQLiteCpp.lib
封装了对sqlite3数据库的操作
构建数据库操作示例工程
-
打开Visual Studio 2019,选择
创建新项目
后,在选择新项目模板页面选择CMake项目
,如下图所示: -
点击“下一步”,在
配置新项目
页面中,填写好项目名称后,点击“创建”按钮,如下图所示: -
在新创建的项目根目录下,创建如下目录:
include
,lib
,src
, 拷贝SQLiteC++
源码目录中的中include
文件夹下的SQLiteCpp目录及该目录下的所有文件和sqlite3目录中的sqlite3.h
文件到工程目录的include
目录中。将编译后的SQLiteCpp.lib
和sqlite3.lib
两个文件拷贝至lib
目录中。做完以上操作后,工程目录结构应如下图所示: -
编写
CMakeLists.txt
脚本cmake_minimum_required (VERSION 3.8) project ("sqlite_demo") aux_source_directory(${PROJECT_SOURCE_DIR}/src SRC) include_directories(${PROJECT_SOURCE_DIR}/include) link_directories(${PROJECT_SOURCE_DIR}/lib) set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/out/bin) add_executable (sqlite_demo ${SRC}) target_link_libraries(sqlite_demo SQLiteCpp sqlite3)
-
在
include
目录下创建代码sqlite_demo.h
,内容如下:#pragma once #include <iostream> #include <string> #include "SQLiteCpp/Database.h"
-
在
src
目录下创建代码sqlite_demo.cpp
,内容如下:#include "sqlite_demo.h" struct Command { std::string cmd; std::string arg; }; Command Get() { std::string line; std::getline(std::cin, line); auto space = line.find_first_of(' '); if (space != std::string::npos) { Command cmd; cmd.cmd = line.substr(0, space); cmd.arg = line.substr(space + 1); return cmd; } return Command{ line, "" }; } int main(){ SQLite::Database db("./stocks.db", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE); db.exec("CREATE TABLE IF NOT EXISTS stocks(id INTEGER PRIMARY KEY, company_name TEXT, stock_code TEXT, price DECIMAL(9,3))"); while (1) { std::cout << "Waiting for instruction: (add | chgprice | list | exit) " << std::endl; const Command cmd = Get(); std::cout << "Instruction: "<< cmd.cmd; if (cmd.arg.length() > 0) { std::cout << " Arguments: " << cmd.arg; } std::cout << std::endl; std::cout << "-------------------------------------" << std::endl; if (cmd.cmd == "exit") break; else if (cmd.cmd == "add") { SQLite::Statement addNew(db, "insert into stocks(company_name, stock_code, price) values(:company_name, :stock_code, :price)"); std::string companyName = cmd.arg.substr(0, cmd.arg.find_first_of(' ')); std::string stockCode = cmd.arg.substr(cmd.arg.find_first_of(' ') + 1); stockCode = stockCode.substr(0, stockCode.find_first_of(' ')); std::string price = cmd.arg.substr(cmd.arg.find_last_of(' ')); addNew.bind(":company_name", companyName.c_str()); addNew.bind(":stock_code", stockCode.c_str()); addNew.bind(":price", atof(price.c_str())); addNew.exec(); } else if (cmd.cmd == "chgprice") { SQLite::Statement chgPrice(db, "update stocks set price=:price where stock_code=:stockCode"); chgPrice.bind(":price", atof((cmd.arg.substr(cmd.arg.find_first_of(' ') + 1)).c_str())); chgPrice.bind(":stockCode", cmd.arg.substr(0, cmd.arg.find_first_of(' '))); chgPrice.exec(); } else if (cmd.cmd == "list") { SQLite::Statement listAll(db, "select * from stocks"); while (listAll.executeStep()) { std::cout << listAll.getColumn("id").getInt() << ") " << listAll.getColumn("company_name").getString() << " | " << listAll.getColumn("stock_code").getString() << " | " << listAll.getColumn("price").getDouble() << std::endl; } } } return 0; }
其中
SQLite::Database
类代表一个数据库
使用SQLite::Statement
类完成对数据库的操作,如增删改查等。
使用SQLiteC++包装类比直接使用SQLite C Native API 要更加直观和方便。 -
代码编写完成后,在工程目录
out
下,创建build
目录, 进入build
目录,执行命令:cmake ../../
-
预编译完成后,在当前目录执行以下命令对工程进行编译
cmake --build . --config release
编译完成后,可以在
out\bin\Release
目录下生成sqlite_demo.exe
可执行文件。由于我们采用的是静态库编译,所以该文件可以作为独立程序进行发布,无需任何依赖库或文件。 -
执行效果:
在程序执行后,将会自动建立
stocks.db
数据库文件。