使用C++对SQLite3数据库进行增、删、改、查操作实例

使用C++对SQLite3数据库进行增、删、改、查操作实例

概述

SQLite经常被用于嵌入式数据库,经常用于需要本地存储信息(如配置信息、应用数据、日志等)的应用程序,小巧方便,零配置。SQLite提供了C语言的原生接口API对数据库进行操作,但使用起来相对繁琐,不太直观。使用C++操作SQLite,为了提供更加友好和直观的操作,需要将原生C API进行类封装,本文将介绍如何使用SQLiteC++ 作为类库对SQLite数据库进行操作。

注:本文将使用 MSVC v19.29 + cmake v3.25.1 进行编译,其中MSVC编译器需要安装Visual Studio 2019。以下操作都在Windows10操作系统进行

下载和编译SQLiteC++源码

  1. 点击这里下载SQLiteC++的稳定版源码

  2. 解压源代码压缩包

  3. 进入解压后的源代码目录,目录结构如下所示:

    在这里插入图片描述

  4. 找到CMakeLists.txt文件,这是编译该工程的脚本,脚本默认是将工程编译为静态链接库,我们可以通过修改该脚本将其编译为动态链接库,本文将遵循脚本内容,将工程编译为静态库。

    可选操作: 修改CMakeLists.txt文件的第209行,可以将${SQLITECPP_DOC} ${SQLITECPP_SCRIPT}两项从静态库编译中去除

  5. 打开Windows命令行工具(PowerShell或cmd),将命令行中的本地目录定位到解压的源代码目录下(本例为H:\sqlite3\SQLiteCpp-3.3.1),执行以下命令进行预编译:

    mkdir build
    cd build
    cmake ../
    

    执行结果如下图所示:
    在这里插入图片描述

  6. 预编译完成后,执行下面这个命令对源代码进行编译

    cmake --build . --config release

    生成的两个静态库如下图红框中标注的文件,这两个文件就是我们项目中操作SQLite数据所需的两个静态库。

    其中sqlite3.lib封装了sqlite3数据库和API

    SQLiteCpp.lib封装了对sqlite3数据库的操作

在这里插入图片描述

构建数据库操作示例工程

  1. 打开Visual Studio 2019,选择创建新项目后,在选择新项目模板页面选择CMake项目 ,如下图所示:

    在这里插入图片描述

  2. 点击“下一步”,在配置新项目页面中,填写好项目名称后,点击“创建”按钮,如下图所示:

    在这里插入图片描述

  3. 在新创建的项目根目录下,创建如下目录:include, lib, src , 拷贝SQLiteC++源码目录中的中include 文件夹下的SQLiteCpp目录及该目录下的所有文件和sqlite3目录中的sqlite3.h文件到工程目录的include目录中。将编译后的SQLiteCpp.libsqlite3.lib 两个文件拷贝至 lib 目录中。做完以上操作后,工程目录结构应如下图所示:

    在这里插入图片描述

  4. 编写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)
    
  5. include目录下创建代码 sqlite_demo.h,内容如下:

    #pragma once
    
    #include <iostream>
    #include <string>
    #include "SQLiteCpp/Database.h"
    
  6. 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 要更加直观和方便。

  7. 代码编写完成后,在工程目录 out 下,创建 build目录, 进入build目录,执行命令:

    cmake ../../
    

    在这里插入图片描述

  8. 预编译完成后,在当前目录执行以下命令对工程进行编译

    cmake --build . --config release
    

    在这里插入图片描述

    编译完成后,可以在out\bin\Release目录下生成sqlite_demo.exe 可执行文件。由于我们采用的是静态库编译,所以该文件可以作为独立程序进行发布,无需任何依赖库或文件。

  9. 执行效果:

    效果图

    在程序执行后,将会自动建立 stocks.db 数据库文件。

  • 21
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值