Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2296617
  • 博文数量: 393
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 4178
  • 用 户 组: 普通用户
  • 注册时间: 2016-07-04 13:04
文章分类

全部博文(393)

文章存档

2020年(8)

2019年(24)

2018年(135)

2017年(158)

2016年(68)

我的朋友

分类: 嵌入式

2018-07-05 16:17:36

SQLite是一个超轻量级的开源数据库,从官网上下载的source是一个用c写的文件,在C++(VC)中调 用时难免会碰到一些问题,这时就可使用CppSQLite。 CppSQLite(最近版本为CppSQLite3)是对SQLite进行二次封装后的 C++类库。

SQLite官网:

cppsqlite下载地址:

 

一、使用前需要包含sqlite3头文件和库文件。

(1)CppSQLite3.h 和CppSQLite3.cpp

(2)sqlite3.h、sqlite3.lib和sqlite3.dll

在使用这个类的时候,你需要确保几件事情:首先你要下载上面5个文件。其次就是在你的工程中引入,sqlite3.lib,最后要将CppSQLite3.h 和CppSQLite3.cpp添加到你的工程中。

 

二、使用方法

1、打开数据库

	
  1. CppSQLite3DB db;
  2. db.open("data.db");
  3. db.close();

CppSQLite3DB是一个核心类,之后的查询等数据库操作都要借助这个类。打开,关闭就像操作一个文件。

2、查询

	
  1. const char *sRoute = "x://..."; //设置sqlite数据库文件的路径
  2. CppSQLite3DB db;
  3. try
  4. {
  5. db.open(sRoute); //打开数据库
  6. CppSQLite3Query q = db.execQuery("select * from t_table"); //执行查询
  7. for(int i = 0; i <= q.numFields() - 1; i++) //遍历并打印表头
  8. {
  9. printf("%s\t", q.fieldName(i));
  10. }
  11. printf("\n");
  12. while(!q.eof()) //遍历所有行
  13. {
  14. for(int i = 0; i<=q.numFields()-1; i++)
  15. {
  16. printf("%s\t", q.getStringField(i));
  17. }
  18. printf("\n");
  19. q.nextRow();
  20. }
  21. q.finalize();//结束查询,释放内存
  22. }
  23. catch(CppSQLite3Exception& e)
  24. {
  25. printf("%s",e.errorMessage());
  26. }
  27. db.close()

CppSQLite3Query是一个查询返回对象,查询完后可以利用此类。这里就使用了CppSQLite3DB的一个函数execQuery,只要将查询sql传入即可。

eof函数:判断是否还有数据;

nextRow函数:移到下一条记录;

getStringField函数:将获得相应字段的内容,以字符串形式返回;

getIntField函数:将获得相应字段的内容,以整形形式返回。

 注意的是这个类产生之后要finalize

3、数据库更改操作

	
  1. db.execDML("insert into t_table(name,age)values('xiaomi',25)");
  2. db.execDML("update t_table set age = 21 where name = 'xiaomi'");

执行insert、update、delete sql语句,无需取返回结果。

4、statement对象

	
  1. CppSQLite3Statementsmt = db.compileStatement("insert into t_table(name,age) values(?,?)");
  2. for (int i = 0 ; i < 10; ++i)
  3. {
  4. smt.bind(1,"test_");
  5. smt.bind(2,i);
  6. smt.execDML();
  7. }
  8. smt.finalize();

CppSqlite也提供Statement对象,用法也相当简单。注意的是,CppSQLite3Statement和CppSQLite3Query一样,最后也要finalize。

5、SQLite一条SQL语句插入多条记录,批量插入

用SQLite才发现这个语法并非标准SQL,故而SQLite并不支持。网络上推荐的方法:
INSERT INTO TABLE(col1, col2) SELECT val11, val12 UNION ALL SELECT val21, val22 ;
这样的写法是属于复合SQL语句,表示先把两个SELECT的结果集进行无删减的联合,再把联合结果插入到TABLE中。

6、异常处理

	
  1. try
  2. {
  3. code……
  4. }
  5. catch(CppSQLite3Exception & e)
  6. {
  7. }

将操作代码放入try里面,使用CppSQLite3Exception & 来catch。

7、SQLite 插入大量数据慢(多次insert)的解决方法 
sqlite 插入数据很慢的原因:sqlite在没有显式使用事务的时候会为每条insert都使用事务操作,而sqlite数据库是以文件的形式存在磁盘中,就相当于每次访问时都要打开一次文件,如果对数据进行大量的操作,时间都耗费在I/O操作上,所以很慢。
解决方法是显式使用事务的形式提交:因为我们开始事务后,进行的大量操作的语句都保存在内存中,当提交时才全部写入数据库,此时,数据库文件也就只用打开一次。
https://www.cnblogs.com/likebeta/archive/2012/06/15/2551466.html

完整实例:

	
  1. #include "CppSQLite3.h"
  2. Class TestSqlite{
  3. //定义db指针
  4. private:
  5. CppSQLite3DB* m_pSqlDb;
  6. TestSqlite()
  7. {
  8. m_pSqlDb = NULL;
  9. Init();
  10. }
  11. ~TestSqlite()
  12. {
  13. if ( m_pSqlDb )
  14. {
  15. m_pSqlDb.Close();
  16. delete m_pSqlDb;
  17. m_pSqlDb = NULL;
  18. }
  19. }
  20. //初始化
  21. BOOL Init()
  22. {
  23. //初始化sqlite指针
  24. if ( m_pSqlDb || !(m_pSqlDb = new CppSQLite3DB))
  25. {
  26. return FALSE;
  27. }
  28. try
  29. {
  30. string strDbFile = "D:\\data.s3db";
  31. m_pSqlDb->open( strDbFile.c_str() );//打开指定位置的本地数据库
  32. }
  33. catch (CppSQLite3Exception& e)//处理sqlite异常
  34. {
  35. return FALSE;
  36. }
  37. return TRUE;
  38. }
  39. public:
  40. //读出db中指定名称的表数据
  41. void ReadAllLine(map<int,int>& mpDbInfo,const string &TblName)
  42. {
  43. try
  44. {
  45. char szCmd[256];
  46. sprintf( szCmd, "SELECT id,testnum FROM %s;",TblName);
  47. CppSQLite3Query query = m_pSqlDb->execQuery( szCmd );//执行查询语句
  48. while(!query.eof())
  49. {
  50. int id = query.getIntField( "id"); //列项为id的值
  51. int testnum = query.getIntField( "testnum"); //列项testnum的值
  52. mpDbInfo.insert(make_pair(id,testnum));//插入map
  53. query.nextRow();//继续下一行
  54. }
  55. query.finalize();//结束查询,释放内存
  56. }
  57. catch (CppSQLite3Exception& e)
  58. {
  59. return;
  60. }
  61. }
  62. //更新指定数据
  63. BOOL DeleteLine(const string& TblName,const int& id,const int& num)
  64. {
  65. try
  66. {
  67. char szCmd[256];
  68. sprintf( szCmd, "update %s set num = %d WHERE id=%d;",TblName,num,id);//更新内容
  69. m_pSqlDb->execDML( szCmd );
  70. }
  71. catch (CppSQLite3Exception& e)
  72. {
  73. return FALSE;
  74. }
  75. return TRUE;
  76. }
  77. //删除指定数据
  78. BOOL DeleteLine(const string& TblName,const int& id)
  79. {
  80. try
  81. {
  82. char szCmd[256];
  83. sprintf( szCmd, "DELETE FROM %d WHERE id=%d;", TblName,id);//删除语句
  84. m_pSqlDb->execDML( szCmd );
  85. }
  86. catch (CppSQLite3Exception& e)
  87. {
  88. return FALSE;
  89. }
  90. return TRUE;
  91. }
  92. };

三、注意事项

1、执行selectexecQuery,执行deleteupdateinsertexecDML 

2、数据库文件名传入utf-8格式字符串,否则文件库文件名包含中文时会打开失败。

Gbkutf-8函数可以参考下面这篇文章或开源库libiconv

https://blog.csdn.net/bladeandmaster88/article/details/54800287
3
、如果发现有的数据库能打开,有的打不开,则到官网下载并替换最新版的sqlite.dll即可。

阅读(1219) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~