行业资讯
用 C++ 封装 SQLite 数据库,并测试“建表、插入数据、查询数据、删除表”的完整流程。
1.Sqlite.h定义数据库工具类Sqlite.h声明了一个Sqlite类用来管理 SQLite 数据库连接。它主要提供两个功能intExec(...);用于执行不需要返回表格结果的 SQL例如CREATETABLEINSERTUPDATEDELETEDROPTABLE另一个是intQuery(...);专门用于执行查询语句例如SELECT*FROMBELLA;并把查询结果保存到std::vectorstd::vectorstd::stringresult;其中外层vector表示多行内层vector表示一行中的多个字段columns保存列名。这个类内部用sqlite3*m_db;保存数据库连接同时禁止复制构造和复制赋值防止两个对象同时管理并关闭同一个数据库连接。2.Sqlite.cpp实现数据库操作打开数据库创建Sqlite对象时Sqlitesqlite(_T(test.db));会调用构造函数Sqlite::Sqlite(consttstringdbPath)内部通过SqliteOpen(dbPath.c_str(),m_db);打开或创建test.db数据库文件。如果test.db不存在SQLite 通常会自动创建它。关闭数据库对象销毁时析构函数会ClearResult();sqlite3_close(db);先释放查询结果占用的动态内存再关闭数据库连接。这体现了 C 的 RAII 思想对象创建时获得资源对象销毁时自动释放资源。执行普通 SQLExec()内部调用sqlite3_exec(...)执行建表、插入和删除表等操作。如果 SQL 执行失败SQLite 会把错误信息放进errmsg然后代码把它复制到strMsg供主函数打印。执行查询Query()也是调用sqlite3_exec(...)但这次给它传入了回调函数Sqlite::SelectCallbackEntrySQLite 每查询到一行数据就会调用一次这个回调函数。调用流程是sqlite3_exec ↓ SelectCallbackEntry ↓ SelectCallback ↓ 保存列名和当前行数据SelectCallback()把每一行保存为std::vectorstd::string然后将这一行的指针加入m_result最后Query()再把内部查询结果复制到主函数传入的result和columns中。3.SqliteStudy.cpp测试数据库功能主函数实际执行了下面几步。第一步打开数据库Sqlitesqlite(_T(test.db));打开或创建test.db第二步删除可能已经存在的旧表DROPTABLEIFEXISTSBELLA;这样可以保证程序重复运行时不会因为BELLA表已经存在而建表失败。第三步创建表CREATETABLEBELLA(IDINTEGERPRIMARYKEYNOTNULL,NAMETEXTNOTNULL);创建了一张名为BELLA的表包含两个字段ID 整数主键不能为空 NAME 文本不能为空第四步插入两条记录第一条ID 1 NAME sunshine1第二条ID 2 NAME sunshine2第五步查询全部数据执行SELECT*FROMBELLA;将结果保存进results columns然后用两层循环输出ID 1 NAME sunshine1 ---------------- ID 2 NAME sunshine2 ----------------第六步删除表最后执行DROPTABLEBELLA;把刚才创建的表删除。整体执行流程程序开始 ↓ 打开或创建 test.db ↓ 删除旧的 BELLA 表 ↓ 创建新的 BELLA 表 ↓ 插入 sunshine1 ↓ 插入 sunshine2 ↓ 查询 BELLA 表 ↓ 通过回调函数逐行保存查询结果 ↓ 在控制台打印结果 ↓ 删除 BELLA 表 ↓ Sqlite 对象析构 ↓ 释放查询结果并关闭数据库sqlite.cpp的代码#includesqlite.hSqlite::Sqlite(consttstringdbPath){m_stmtNULL;intretSqliteOpen(dbPath.c_str(),m_db);// 如果打开错误就抛出错误if(ret!0)throwret;}Sqlite::~Sqlite(){ClearResult();sqlite3*dbm_db;m_dbNULL;sqlite3_close(db);}intSqlite::Query(conststd::stringsql,std::vectorstd::vectorstd::stringresult,std::vectorstd::stringcolumns,std::stringstrMsg){// 对其中的内容进行清除ClearResult();char*errmsgNULL;intretsqlite3_exec(m_db,sql.c_str(),Sqlite::SelectCallbackEntry,this,errmsg);if(ret!SQLITE_OK){strMsgerrmsg;sqlite3_free(errmsg);returnret;}result.resize(m_result.size());if(m_result.size()0){std::liststd::vectorstd::string*::iterator itm_result.begin();for(size_t i0;im_result.size()(it!m_result.end());i,it){result[i].resize((*it)-size());for(size_t j0;j(*it)-size();j){result[i][j](**it)[j];}}}columns.resize(m_column.size());for(size_t i0;im_column.size();i){columns[i]m_column[i];}return0;}intSqlite::QueryBlob(conststd::stringsql,std::vectorstd::vectorstd::stringresult,std::vectorstd::stringcolumns,std::stringstrMsg){char*errmsgNULL;ClearResult();intretsqlite3_prepare(m_db,sql.c_str(),sql.size(),m_stmt,NULL);if(ret!SQLITE_OK){strMsgsqlite3_errmsg(m_db);returnret;}while(sqlite3_step(m_stmt)SQLITE_ROW){}result.resize(m_result.size());if(m_result.size()0){std::liststd::vectorstd::string*::iterator itm_result.begin();for(size_t i0;im_result.size()(it!m_result.end());i,it){result[i].resize((*it)-size());for(size_t j0;j(*it)-size();j){result[i][j](**it)[j];}}}columns.resize(m_column.size());for(size_t i0;im_column.size();i){columns[i]m_column[i];}sqlite3_finalize(m_stmt);m_stmtNULL;return0;}intSqlite::Exec(conststd::stringsql,std::stringstrMsg){char*errmsgNULL;intretsqlite3_exec(m_db,sql.c_str(),NULL,this,errmsg);if(ret!SQLITE_OK){strMsgerrmsg;sqlite3_free(errmsg);returnret;}returnret;}intSqlite::SelectCallbackEntry(void*thiz,intargc,char*argv[],char*names[]){((Sqlite*)thiz)-SelectCallback(argc,argv,names);return0;}intSqlite::SelectCallback(intargc,char*argv[],char*names[]){//只是对结果进行查询名称无所谓if(m_column.size()0argc0){m_column.resize(argc);for(inti0;iargc;i){m_column[i]names[i];}}if(argc0){std::vectorstd::string*presultnewstd::vectorstd::string();presult-resize(argc);for(inti0;iargc;i){sqlite3_column_type(m_stmt,i);(*presult)[i]argv[i];}m_result.push_back(presult);}return0;}intSqlite::ClearResult(){while(m_result.size()0){std::vectorstd::string*presultm_result.front();m_result.pop_front();if(presult){presult-clear();deletepresult;}}m_column.clear();return0;}SqliteStudy.cpp的代码#includeSqlite.h#includeiostream#includestring#includetchar.h#includevectorconstchar*dropTableIfExistsDROP TABLE IF EXISTS BELLA;;constchar*createTableCREATE TABLE BELLA(ID INTEGER PRIMARY KEY NOT NULL, NAME TEXT NOT NULL);;constchar*insert1INSERT INTO BELLA (ID, NAME) VALUES (1, sunshine1);;constchar*insert2INSERT INTO BELLA (ID, NAME) VALUES (2, sunshine2);;constchar*querySqlSELECT * FROM BELLA;;constchar*dropTableDROP TABLE BELLA;;intmain(){try{Sqlitesqlite(_T(test.db));std::string msg;intretsqlite.Exec(dropTableIfExists,msg);if(ret!SQLITE_OK){std::coutDrop old table failed: msgstd::endl;return-1;}retsqlite.Exec(createTable,msg);if(ret!SQLITE_OK){std::coutCreate table failed: msgstd::endl;return-1;}retsqlite.Exec(insert1,msg);if(ret!SQLITE_OK){std::coutInsert row 1 failed: msgstd::endl;return-1;}retsqlite.Exec(insert2,msg);if(ret!SQLITE_OK){std::coutInsert row 2 failed: msgstd::endl;return-1;}std::vectorstd::vectorstd::stringresults;std::vectorstd::stringcolumns;retsqlite.Query(querySql,results,columns,msg);if(ret!SQLITE_OK){std::coutQuery failed: msgstd::endl;return-1;}for(std::size_t i0;iresults.size();i){for(std::size_t j0;jresults[i].size()jcolumns.size();j){std::coutcolumns[j] results[i][j]std::endl;}std::cout----------------std::endl;}retsqlite.Exec(dropTable,msg);if(ret!SQLITE_OK){std::coutDrop table failed: msgstd::endl;return-1;}}catch(interrorCode){std::coutOpen database failed. SQLite code: errorCodestd::endl;return-1;}return0;}Sqlite.h的代码#pragmaonce#includesqlite3.h#includelist#includestring#includevector#pragmacomment(lib,sqlite3.lib)#ifdef_UNICODEusingtstringstd::wstring;#defineSqliteOpensqlite3_open16#elseusingtstringstd::string;#defineSqliteOpensqlite3_open#endifclassSqlite{public:// 构造函数explicitSqlite(consttstringdbPath);// 析构函数~Sqlite();// 禁止复制Sqlite(constSqlitedb)delete;Sqliteoperator(constSqlitedb)delete;// 查询intQuery(conststd::stringsql,std::vectorstd::vectorstd::stringresult,std::vectorstd::stringcolumns,std::stringstrMsg);intQueryBlob(conststd::stringsql,std::vectorstd::vectorstd::stringresult,std::vectorstd::stringcolumns,std::stringstrMsg);// 增、删、改intExec(conststd::stringsql,std::stringstrMsg);protected:// sqlite3_exec 要求的静态回调入口staticintSelectCallbackEntry(void*thiz,intargc,char*argv[],char*names[]);// 真正处理查询结果的成员函数intSelectCallback(intargc,char*argv[],char*names[]);// 清除内部查询结果intClearResult();private:sqlite3_stmt*m_stmt;sqlite3*m_dbnullptr;// 注意这里不能写成引用类型std::liststd::vectorstd::string*m_result;std::vectorstd::stringm_column;};
郑州网站建设
网页设计
企业官网