#ifndef SQLITEENTRANCE_H
#define SQLITEENTRANCE_H
#include <sqlite3.h>
#include "string.h"
#include "errno.h"
#include "err.h"
#include "stdio.h"
#include <stdio.h>
#include <stdlib.h>
class SQliteEntrance
{
public:
SQliteEntrance();
virtual ~SQliteEntrance();
public:
int OpenTable(); //创建
int InsertElement(); //插入
int InsertElement(int tgtno, int imgno, char *filename, char* buf, int len); //插入特定数据
int InqueryElement(); //查询
int InqueryElement(int tgtno,int imgno); //查询特定数据 目标编号 图像编号
int InqueryElement(int eleno , bool istgt); //只根据一个字段索引模板,第二个参数决定是根据哪一个字段
int UpdateElement(int tgtno, int imgno,char* pbuf,int len);
int DeleteElement(); //删除
int DeleteElement(int tgtno,int imgno); //删除特定数据
int CloseTable(); //关闭数据库
int IsOpen();
private:
sqlite3 *m_db;
int m_len;
int m_nrow=0;
int m_ncolumn = 0;
char *m_zErrMsg ;
char **m_azResult; //二维数组存放结果
sqlite3_stmt *m_stat;
char m_Tplbuffer2[65536];
char m_sqlSentence[256];
bool m_isSqlOpen;
};
#endif // SQLITEENTRANCE_H
#include "SQliteEntrance.h"
SQliteEntrance::SQliteEntrance()
{
m_isSqlOpen=false;
m_db=nullptr;
m_len=0;
m_nrow=0;
m_ncolumn = 0;
m_zErrMsg =nullptr ;
m_azResult=nullptr; //二维数组存放结果
memset(m_Tplbuffer2,0,sizeof(m_Tplbuffer2));
memset(m_sqlSentence,0,sizeof(m_sqlSentence));
}
SQliteEntrance::~SQliteEntrance()
{
if(m_db!=nullptr)
{
sqlite3_close(m_db);
m_isSqlOpen=false;
}
}
int SQliteEntrance::OpenTable()
{
if(m_isSqlOpen)
{
return -1;
}
//system("rm -rf ./user.db");
/* 打开数据库 */
int len = sqlite3_open("./user.db",&m_db);
if( len )
{
/* fprintf函数格式化输出错误信息到指定的stderr文件流中 */
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(m_db));//sqlite3_errmsg(db)用以获得数据库打开错误码的英文描述。
sqlite3_close(m_db);
return -2;
}
else
{
printf("You have opened a sqlite3 database named user successfully!\n");
m_isSqlOpen=true;
}
//创建表
char *sql = " CREATE TABLE TemplateData(\
ID INTEDER PRIMARY KEY,\
TargetID INTEGER,\
ImgID INTEGER,\
FileName VARCHAR(128),\
SensorParameter REAL,\
ImgInfo BLOB \
);" ;
sqlite3_exec(m_db,sql,NULL,NULL,&m_zErrMsg);
}
int SQliteEntrance::InsertElement()
{
if(!m_isSqlOpen|| m_db==nullptr)
{
return -1;
}
/*插入数据 */
char*sql1 ="INSERT INTO 'TemplateData'VALUES(NULL,1,2,201430506201,13.5,NULL);";
sqlite3_exec(m_db,sql1,NULL,NULL,&m_zErrMsg);
char*sql2 ="INSERT INTO 'TemplateData'VALUES(NULL,3,4,201530506302,14.5,NULL);";
sqlite3_exec(m_db,sql2,NULL,NULL,&m_zErrMsg);
char*sql3 ="INSERT INTO 'TemplateData'VALUES(NULL,5,6,201630506413,18.6,NULL);";
sqlite3_exec(m_db,sql3,NULL,NULL,&m_zErrMsg);
char*sql4 ="INSERT INTO 'TemplateData'VALUES(NULL,7,8,201630506413,18.6,?);";
#if 1
//插入带有blob的数据
sqlite3_prepare(m_db,sql4, -1, &m_stat, nullptr);
FILE *fp;
long filesize = 0;
char * ffile;
fp = fopen("./5.bmp", "rb");
if(fp != NULL)
{
fseek(fp, 0, SEEK_END); //将fp指针退回到距离文件结尾0个字节处。
filesize = ftell(fp); //函数 ftell() 用于得到文件位置指针当前位置相对于文件首的偏移字节数。
fseek(fp, 0, SEEK_SET); //将fp指针指到距离文件头0个字节处。
ffile = new char[filesize+1]; //创建一个空间为dilesize大小的字符型数组。
size_t sz = fread(ffile, sizeof(char), filesize+1, fp); //将fp指针指向的文件读取filesize+1个大小的以char为元素单位大小,到ffile中。
fclose(fp); //关闭文件读取
}
//sqlite3_bind_blob()函数中。?号的索引。前面prepare的sql语句里有一个?号,假如有多个?号怎么插入?方法就是改变 bind_blob 函数第2个参数。
//这个参数我写1,表示这里插入的值要替换 stat 的第一个?号(这里的索引从1开始计数,而非从0开始)。
//如果你有多个?号,就写多个 bind_blob 语句,并改变它们的第2个参数就替换到不同的?号。如果有?号没有替换,sqlite为它取值null。
//本函数是将图片保存到stat的表中。
sqlite3_bind_blob(m_stat, 1, ffile, filesize, NULL);
sqlite3_step(m_stat); //通过这个语句,stat 表示的sql语句就被写到了数据库里。
sqlite3_prepare(m_db, "select *from TemplateData where TargetID = 7", -1, &m_stat, 0);
sqlite3_step(m_stat);
const void * test = sqlite3_column_blob(m_stat, 5);
int size = sqlite3_column_bytes(m_stat, 5);
sprintf(m_Tplbuffer2, "%s", test);
FILE *fp2;
fp2 = fopen("4.bmp", "wb");
if(fp2 != NULL)
{
size_t ret = fwrite(test, sizeof(char), size, fp2); //将fp2的图片写进test中
fclose(fp2);
}
if(ffile!=nullptr)
{
delete(ffile);
}
sqlite3_finalize(m_stat);
#endif
}
//重载函数
int SQliteEntrance::InsertElement(int tgtno, int imgno, char* filename,char *buf, int len)
{
if(!m_isSqlOpen|| m_db==nullptr)
{
return -1;
}
char* pbuf=buf;
if(pbuf==nullptr)
{
return -1;
}
//插入数据段 含有blob信息
/*插入数据 */
memset(m_sqlSentence,0,sizeof(m_sqlSentence));
sprintf(m_sqlSentence,"INSERT INTO 'TemplateData'VALUES(NULL,%d,%d,'%s',0.0,?);",
tgtno,imgno,filename);
char*sql4 ="INSERT INTO 'TemplateData'VALUES(NULL,7,8,'Template-33-22.dta',18.6,?);";
#if 1
//插入带有blob的数据
sqlite3_prepare(m_db,m_sqlSentence, -1, &m_stat, nullptr);
//sqlite3_bind_blob()函数中。?号的索引。前面prepare的sql语句里有一个?号,假如有多个?号怎么插入?方法就是改变 bind_blob 函数第2个参数。
//这个参数我写1,表示这里插入的值要替换 stat 的第一个?号(这里的索引从1开始计数,而非从0开始)。
//如果你有多个?号,就写多个 bind_blob 语句,并改变它们的第2个参数就替换到不同的?号。如果有?号没有替换,sqlite为它取值null。
//本函数是将图片保存到stat的表中。
sqlite3_bind_blob(m_stat, 1, pbuf, len, NULL);
sqlite3_step(m_stat); //通过这个语句,stat 表示的sql语句就被写到了数据库里。
//写入之后查询测试写入是否正确
memset(m_sqlSentence,0,sizeof(m_sqlSentence));
sprintf(m_sqlSentence,"select *from TemplateData where TargetID = %d",tgtno);
sqlite3_prepare(m_db, m_sqlSentence, -1, &m_stat, 0);
sqlite3_step(m_stat);
const void * test = sqlite3_column_blob(m_stat, 5);//这里面的数字表示数据库表的第五列
int size = sqlite3_column_bytes(m_stat, 5);
sprintf(m_Tplbuffer2, "%s", test);
FILE *fp2;
fp2 = fopen("./testBlob.dat", "wb");
if(fp2 != NULL)
{
size_t ret = fwrite(test, sizeof(char), size, fp2); //将fp2的图片写进test中
fclose(fp2);
}
sqlite3_finalize(m_stat);
#endif
}
int SQliteEntrance::InqueryElement()
{
if(!m_isSqlOpen|| m_db==nullptr)
{
return -1;
}
/* 查询数据 */
char* sql="select *from TemplateData";
sqlite3_get_table( m_db , sql , &m_azResult , &m_nrow , &m_ncolumn , &m_zErrMsg );
printf("nrow=%d ncolumn=%d\n",m_nrow,m_ncolumn);
// printf("the result is:\n");
// for(int i=0;i<(m_nrow+1)*m_ncolumn;i++)
// {
// printf("azResult[%d]=%s\n",i,m_azResult[i]);
// }
sqlite3_free_table(m_azResult);
return m_nrow;
}
int SQliteEntrance::InqueryElement(int tgtno, int imgno)
{
if(!m_isSqlOpen|| m_db==nullptr)
{
return -1;
}
/* 查询数据 */
memset(m_sqlSentence,0,sizeof(m_sqlSentence));
sprintf(m_sqlSentence,"select *from TemplateData where TargetID = %d AND ImgID = %d;",tgtno,imgno);
//char* sql="select *from TemplateData";
sqlite3_get_table( m_db , m_sqlSentence , &m_azResult , &m_nrow , &m_ncolumn , &m_zErrMsg );
printf("nrow=%d ncolumn=%d\n",m_nrow,m_ncolumn);
printf("the result is:\n");
for(int i=0;i<(m_nrow+1)*m_ncolumn;i++)
{
printf("azResult[%d]=%s\n",i,m_azResult[i]);
}
sqlite3_free_table(m_azResult);
return m_nrow;//返回所引导的模板数量
}
int SQliteEntrance::InqueryElement(int eleno, bool istgt)
{
if(!m_isSqlOpen|| m_db==nullptr)
{
return -1;
}
/* 查询数据 */
memset(m_sqlSentence,0,sizeof(m_sqlSentence));
if(istgt)
{
sprintf(m_sqlSentence,"select *from TemplateData where TargetID = %d;",eleno);
}
else
{
sprintf(m_sqlSentence,"select *from TemplateData where ImgID = %d;",eleno);
}
//char* sql="select *from TemplateData";
sqlite3_get_table( m_db , m_sqlSentence , &m_azResult , &m_nrow , &m_ncolumn , &m_zErrMsg );
printf("nrow=%d ncolumn=%d\n",m_nrow,m_ncolumn);
printf("the result is:\n");
for(int i=0;i<(m_nrow+1)*m_ncolumn;i++)
{
printf("azResult[%d]=%s\n",i,m_azResult[i]);
}
sqlite3_free_table(m_azResult);
return m_nrow;//返回所引导的模板数量
}
int SQliteEntrance::UpdateElement(int tgtno, int imgno,char* pbuf,int len)
{
if(!m_isSqlOpen || m_db==nullptr)
{
return -1;
}
/* 删除某个特定的数据 */
memset(m_sqlSentence,0,sizeof(m_sqlSentence));
sprintf(m_sqlSentence,"update TemplateData set ImgInfo=? where TargetID = %d AND ImgID = %d ;",tgtno,imgno);
//sqlite3_exec( m_db , m_sqlSentence , NULL , NULL , &m_zErrMsg );
#if 1
//插入带有blob的数据
sqlite3_prepare(m_db,m_sqlSentence, -1, &m_stat, nullptr);
//sqlite3_bind_blob()函数中。?号的索引。前面prepare的sql语句里有一个?号,假如有多个?号怎么插入?方法就是改变 bind_blob 函数第2个参数。
//这个参数我写1,表示这里插入的值要替换 stat 的第一个?号(这里的索引从1开始计数,而非从0开始)。
//如果你有多个?号,就写多个 bind_blob 语句,并改变它们的第2个参数就替换到不同的?号。如果有?号没有替换,sqlite为它取值null。
//本函数是将图片保存到stat的表中。
sqlite3_bind_blob(m_stat, 1, pbuf, len, NULL);
sqlite3_step(m_stat); //通过这个语句,stat 表示的sql语句就被写到了数据库里。
//写入之后查询测试写入是否正确
memset(m_sqlSentence,0,sizeof(m_sqlSentence));
sprintf(m_sqlSentence,"select *from TemplateData where TargetID = %d",tgtno);
sqlite3_prepare(m_db, m_sqlSentence, -1, &m_stat, 0);
sqlite3_step(m_stat);
const void * test = sqlite3_column_blob(m_stat, 5);//这里面的数字表示数据库表的第五列
int size = sqlite3_column_bytes(m_stat, 5);
sprintf(m_Tplbuffer2, "%s", test);
FILE *fp2;
fp2 = fopen("./testBlob.dat", "wb");
if(fp2 != NULL)
{
size_t ret = fwrite(test, sizeof(char), size, fp2); //将fp2的图片写进test中
fclose(fp2);
}
sqlite3_finalize(m_stat);
#endif
}
int SQliteEntrance::DeleteElement()
{
if(!m_isSqlOpen|| m_db==nullptr)
{
return -1;
}
/* 删除all 的数据 */
char* sql="delete from TemplateData ;";
sqlite3_exec( m_db , sql , NULL , NULL , &m_zErrMsg );
}
//函数重载
int SQliteEntrance::DeleteElement(int tgtno, int imgno)
{
if(!m_isSqlOpen || m_db==nullptr)
{
return -1;
}
/* 删除某个特定的数据 */
memset(m_sqlSentence,0,sizeof(m_sqlSentence));
sprintf(m_sqlSentence,"delete from TemplateData where TargetID = %d AND ImgID = %d ;",tgtno,imgno);
//char* sql="delete from TemplateData where TargetID = 1 ;";
sqlite3_exec( m_db , m_sqlSentence , NULL , NULL , &m_zErrMsg );
}
int SQliteEntrance::CloseTable()
{
if(!m_isSqlOpen)
{
return -1;
}
if(m_db!=nullptr)
{
sqlite3_close(m_db);
m_isSqlOpen=false;
}
}
int SQliteEntrance::IsOpen()
{
return m_isSqlOpen;
}
这是自己在项目开发中使用的sqlite3数据库C++类,也可以在嵌入式平台上面使用