今天尝试将使用sqlite3数据库,直接使用sqlite3的源码,得到sqlite3.c和sqlite3.h。
我想将他们加入到我的cpp工程里面
所以我新建了一个mysqlite3.cpp文件,在里面调用了sqlite3的函数。
下面来说明我遇到的问题及解决方法
一共有两种编译方法,一种使用gcc/g++编译,一种使用cmake编译,下面就来说明这两种方法
工程源码在最后面。
第一种:使用gcc/g++编译
1.g++ mysqlite.cpp sqlite3.c -o a.out
直接报了一大堆invalid use of incomplete type "XXX"的错误。
解决方法就是.cpp文件和.c文件要分开编译,分别用gcc和g++编译成.o,再用g++将多个.o连接起来
2.gcc -c sqlite3.c -o sqlite3.o
也是报了一堆,对‘pthread_create’未定义的引用,表示找不到pthread_create等函数,应该是没有连接线程库文件
解决办法,加上 -lpthread
3.gcc -c sqlite3.c -o sqlite3.o -lpthread
又报了一堆对‘dlopen’未定义的引用,表示找不到dl库
解决办法,加上-ldl
4.gcc -c sqlite3.c -o sqlite3.o -lpthread -ldl
成功生成sqlite3.o
5.g++ -c mysqlite.cpp -o mysqlite.o
一次成功,生成mysqlite3.o
6.g++ mysqlite.o sqlite3.o -o a.out
报了pthread和dl的未定义的引用,加上
7.g++ mysqlite.o sqlite3.o -o a.out -lpthread -ldl
成功生成a.out
8.执行a.out
OKOKOK
第二种:使用cmake编译
cmake的安装可看别的博客
!!!cmake很好用,真的很好用,没学过的一定要学
1.同样是找不到pthread和dl
CMakeLists.txt源码如下
cmake_minimum_required(VERSION 2.8)
aux_source_directory(. SRC_LIST)
add_executable(apple ${SRC_LIST})
添加pthread库和dl库
2.成功
CMakeLists.txt源码如下
cmake_minimum_required(VERSION 2.8)
link_libraries(pthread)
link_libraries(dl)
aux_source_directory(. SRC_LIST)
add_executable(apple ${SRC_LIST})
成功生成apple可执行文件
下面附上工程源码
sqlite3.c和sqlite3.h就不贴了,就贴我自己写的mysqlite3.cpp
单个函数
1.打开数据库文件
int DbOpen(const char * addr) //打开数据库,不存在,就创建一个同名的
{
int ret = 0;
ret = sqlite3_open(addr,&database);
printf("open : %d\n", ret);
if(ret != SQLITE_OK){
return -1;
}
return 0;
}
2.创建数据表
int DbCreateTbl()
{
int rc = sqlite3_exec(database, "create table tblTest(id int, name varchar(128));", 0, 0, &errMsg);
//加上容错
printf("errMSG = %s\n",errMsg);
return 0;
}
3.插入数据
int DbInsert() //插入数据
{
int rc = sqlite3_exec(database, "insert into tblTest values(1,'随便');", 0, 0, &errMsg);
//加上容错
return 0;
}
4.利用回调函数查询数据
//每查到一条记录,就执行该回调函数
//para是sqlite3里面传入的值,现在我们传入了0
//nCount是这一条记录有几个字段
//pValue查询到的数据都在这里
//pName表示这个字段的字段名称
//没找到一个记录,会调用一次该函数,别忘记最后的return。
int callback(void*para , int nCount, char** pValue, char** pName)
{
for(int i=0;i<nCount;i++){
printf("nCount = %d,pValue = %s,pName = %s\n", nCount,pValue[i], pName[i]);
}
return 0;
}
int DbSearch_1() //使用回调函数查找
{
int rc = sqlite3_exec(database, "select * from tblTest where id = 3;", callback, 0, &errMsg);
//加容错
return 0;
}
5.利用sqlite3_get_table查询数据
int DbSearch_2() //利用sqlite3_get_table查询数据
{
char** pResult;
int nRow;
int nCol;
int rc = sqlite3_get_table(database,"select * from tblTest where id = 3;",&pResult,&nRow,&nCol,&errMsg);
if (rc != SQLITE_OK)
{
sqlite3_free(errMsg);
sqlite3_close(database);
return -1;
}
printf("nRow = %d,nCol = %d\n",nRow, nCol);
//for(int i=0;i<(nRow+1) * nCol;i++) 得到表中查询结果的所有数据
//for(int i=col;i<(nRow+1) * nCol;i++) 得到查询结果去除表头所有数据
//for(int i=nCol;i<(nRow+1) * nCol;i=i+nCol) 去除表头得到结果集的第一列结果
//for(int i=nCol+1;i<(nRow+1) * nCol;i=i+nCol) 去除表头得到结果集的第二列结果
for(int i=nCol;i<(nRow+1) * nCol;i=i+nCol)
{
printf("id = %s,",pResult[i]);
printf("name = %s\n",pResult[i+1]);
}
return 0;
}
6.利用sqlite3_prepare、sqlite3_step查询数据
int DbSearch_3() //利用sqlite3_prepare、sqlite3_step查询数据
{
sqlite3_stmt *stmt = NULL;
const char *zTail;
if(sqlite3_prepare_v2(database, "select * from tblTest where id = 3;", -1, &stmt, &zTail) == SQLITE_OK)
{
while(sqlite3_step(stmt) == SQLITE_ROW) //不包括列标题
{
int id = sqlite3_column_int(stmt, 0); //表示第一列
const unsigned char *name = sqlite3_column_text(stmt, 1); //表示第二列
printf("id = %d, name = %s\n", id, name);
}
}
sqlite3_finalize(stmt);
return 0;
}
7.关闭数据库
int DbClose() //关闭数据库
{
sqlite3_free(errMsg);
sqlite3_close(database);
return 0;
}
总的文件
#include "sqlite3.h"
#include <stdio.h>
#include <iostream>
#include <string>
#include <vector>
#include <string.h>
#include <cstring>
using namespace std;
int DbOpen(const char * addr); //打开数据库文件,如果没有同名的,则新创建一个
int DbClose(); //关闭数据库
int DbCreateTbl(); //在数据库文件中创建数据表,如果存在同名的,则不会创建
int DbInsert(); //插入数据
int callback(void*para , int nCount, char** pValue, char** pName); //回调函数
int DbSearch_1(); //利用回调函数查询数据
int DbSearch_2(); //利用sqlite3_get_table查询数据
int DbSearch_3(); //利用sqlite3_prepare、sqlite3_step查询数据
sqlite3 *database = NULL;
char * errMsg = NULL;
int main()
{
DbOpen("aaa");
DbCreateTbl();
DbInsert();
DbSearch_1();
printf("--------------------------\n");
DbSearch_2();
printf("--------------------------\n");
DbSearch_3();
printf("--------------------------\n");
DbClose();
return 0;
}
//每查到一条记录,就执行该回调函数
//para是sqlite3里面传入的值,现在我们传入了0
//nCount是这一条记录有几个字段
//pValue查询到的数据都在这里
//pName表示这个字段的字段名称
//没找到一个记录,会调用一次该函数,别忘记最后的return。
int callback(void*para , int nCount, char** pValue, char** pName)
{
for(int i=0;i<nCount;i++){
printf("nCount = %d,pValue = %s,pName = %s\n", nCount,pValue[i], pName[i]);
}
return 0;
}
int DbSearch_1() //使用回调函数查找
{
int rc = sqlite3_exec(database, "select * from tblTest where id = 3;", callback, 0, &errMsg);
//加容错
return 0;
}
int DbSearch_2() //利用sqlite3_get_table查询数据
{
char** pResult;
int nRow;
int nCol;
int rc = sqlite3_get_table(database,"select * from tblTest where id = 3;",&pResult,&nRow,&nCol,&errMsg);
if (rc != SQLITE_OK)
{
sqlite3_free(errMsg);
sqlite3_close(database);
return -1;
}
printf("nRow = %d,nCol = %d\n",nRow, nCol);
for(int i=nCol;i<(nRow+1) * nCol;i=i+nCol)
{
printf("id = %s,",pResult[i]);
printf("name = %s\n",pResult[i+1]);
}
return 0;
}
int DbSearch_3() //利用sqlite3_prepare、sqlite3_step查询数据
{
sqlite3_stmt *stmt = NULL;
const char *zTail;
if(sqlite3_prepare_v2(database, "select * from tblTest where id = 3;", -1, &stmt, &zTail) == SQLITE_OK)
{
while(sqlite3_step(stmt) == SQLITE_ROW) //不包括列标题
{
int id = sqlite3_column_int(stmt, 0); //表示第一列
const unsigned char *name = sqlite3_column_text(stmt, 1); //表示第二列
printf("id = %d, name = %s\n", id, name);
}
}
sqlite3_finalize(stmt);
return 0;
}
int DbInsert() //插入数据
{
int rc = sqlite3_exec(database, "insert into tblTest values(1,'随便');", 0, 0, &errMsg);
return 0;
}
//创建一张数据表,如果存在同名数据表,则errMSG = table tblTest already exists。继续运行
int DbCreateTbl()
{
int rc = sqlite3_exec(database, "create table tblTest(id int, name varchar(128));", 0, 0, &errMsg);
printf("errMSG = %s\n",errMsg);
return 0;
}
int DbOpen(const char * addr) //打开数据库,不存在,就创建一个同名的
{
int ret = 0;
ret = sqlite3_open(addr,&database);
printf("open : %d\n", ret);
if(ret != SQLITE_OK){
return -1;
}
return 0;
}
int DbClose() //关闭数据库
{
sqlite3_free(errMsg);
sqlite3_close(database);
return 0;
}