SQLite简介:
sqlite是轻量化,易用的嵌入式数据库,用于设备端的数据管理,可以理解成单点的数据库,比如人脸识别打卡器,他会保存员工的打卡数据,时间,人脸的数据,员工的ID。传统服务器型数据库用于管理多端设备,更加复杂比如共享单车的数据库,全国有很多的共享单车。
SQLite是一个无服务器的数据库,是自包含的。这也称为嵌入式数据库,这意味着数据库引擎作为应用程序的一部分运行。
MySQL需要运行服务器,MySQL将需要客户端和服务器架构通过网络进行交互。
SQLITE的优点 | SQLITE的缺点 | MYSQL的优点 | MYSQL的缺点 |
基于文件,易于设置和使用 适合基础开发和测试 轻松携带 使用标准SQL语法进行微小更改 使用方便 | 缺乏用户管理和安全功能 不容易扩展 不适合大数据库 无法定制 | 使用方便 提供了许多与数据库相关的功能 良好的安全功能 易于扩展,适用于大型数据库 提供良好的速度和性能 提供良好的用户管理和多种访问控制 | 需要一些技术专业知识来设置 与传统SQL相比,语法略有不同 |
基于嵌入式的数据库主要有:SQLite,Firebird,Berkeley DB,eXtremeDB
Firebird 是关系型数据库,功能强大,支持存储过程,SQL兼容等
SQLite 关系型数据库,体积小,支持ACID事务
Berkeley DB 并没有数据库服务器的概念,他的程序直接链接到应用程序中
eXtremeDB 是内存数据库,运行效率高
安装sqlite3:去sqlite官网下载sqlite3的包
-
把下载的文件sqlite-autoconf-3390000.tar.gz上传到开发板
-
tar -xvf sqlite-autoconf-3390000.tar.gz 解压
-
cd sqlite-autoconf-3390000 进入文件夹
-
./configure --prefix=/usr/local 配置安装路径在/usr/local
-
make 编译
-
sudo make install 安装
SQLite的命令使用:
- 创建一个数据库
方式一:
-
sqlite3 进入数据库
-
.open test.db
-
.quit//如果输入不正确导致输入出错,按ctrl+z强制退出 数据库退出后在命令当前路径创建数据库test.db
方式二:
sqlite3 test.db //在命令运行当前窗口创建数据库test.db
在数据库命令下
.databases 列出当前打开的数据库
.table 列出当前的所有数据库
.quit 退出
-
创建一张表格
create table stu2(id Integer,name char,score Integer);
-
插入一条记录
insert into stu2 values(18130106,'huang',99);
insert into stu2 values(18130101,"gang",100); ''和""都行
insert into stu2(name,score) values("huanggang",98); 插入部分字段内容
-
查看数据库的记录
select * from stu2; //查询所有字段的结果
select name,score from stu2; //查询数据库中部分字段的内
-
删除一条记录
delete from stu2 where id = 18130101;
-
更改一条记录
update stu2 set name = 'huang' where id = 18130106;
-
删除一张表
drop table stu;
-
增加一列
alter table stu add column sex char;
SQLite的编程操作:
sqlite3_open(const char *filename, sqlite3 **ppDb)
int sqlite3_open(
const char *filename, // 数据库文件的名称
sqlite3 **ppDb // 返回一个指向新创建数据库结构体指针的指针
);
filename:要打开或创建的数据库文件的名称。如果文件存在,它将打开它;如果文件不存在,它将创建一个新文件。
ppDb:一个指向指针的指针,用于接收新创建的sqlite3数据库结构体的地址。
该例程打开一个指向 SQLite 数据库文件的连接,返回一个用于其他 SQLite程序的数据库连接对象。
sqlite3_close(sqlite3*)
该例程关闭之前调用 sqlite3_open() 打开的数据库连接。所有与连接相关的语句都应在连接关闭之前完成。
如果还有查询没有完成,sqlite3_close() 将返回 SQLITE_BUSY 禁止关闭的错误消息。
const char *sqlite3_errmsg(sqlite3*);
sqlite3_errmsg() 通常用来获取最近调用的API接口返回的错误代码.
#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>
int main(int argc,char **argv)
{
sqlite3 *db;
int ret;
if(argc < 2){
printf("Usage:%s input error\n",argv[1]);
exit(-1);
}
ret = sqlite3_open(argv[1],&db);
if(ret == SQLITE_OK){
printf("open %s success\n",argv[1]);
}else{
printf("error:%s,%d\n",sqlite3_errmsg(db),ret);
if(ret == 14){
printf("permission denied\n");
exit(-1);
}
}
sqlite3_close(db);
printf("done\n");
return 0;
}
创建表的C接口:
int sqlite3_exec(sqlite3*, const char *sql, sqlite_callback, void *data, char **errmsg)
sqlite3* : open 打开的数据库
const char* sql : 执行的sql功能语句
*callback, : sql语句对应的回调函数
void* data, : 传递给回调函数的指针参数
char **errmsq : 错误信息
回调函数指针callback则是 sql功能命令对应的回调函数,所谓回调函数的意思是,会先执行sql对应的功能命令,然后将结果传递给回调函数,回调函数根据结果再进一步执行。这代表着,这个 “回调函数”才是最有意义的,我们要讲我们需要的功能,通过回调函数来实现,不管是获取数据库表中有效信息,还是其他动作。
int callback(void *para, int column_size, char *column_value[], char *column_name[])
para: 由sqlite3_exec传入的参数指针,或者说是指针参数
column_size: 查询到的这一条记录有多少个字段(多少列)
column_value[]: 该参数是双指针,查询出来的数据都保存在这里,它是一个1维数组,每一个元素都是一个char*,是一个字段内容,所以这个参数就可以不是单字节,而是可以为字符串等不定长度的数值,用字符串表示,以'\0'结尾。 列的值
column_name[]:该参数是双指针,与columnValue是对应的,表示这个字段的字段名称
返回值:执行成果则返回SQLITE_OK,否则返回其他值
这里面有几个地方容易理解错:
-
回调函数的参数一定是 sql功能命令执行结果的进一步处理,其中para好理解,就是sqlite3_exec传递的参数
-
column_size:表示sql功能结果的“字段”,也就是“列”的个数,没错,就是“列”的个数。
-
另外需要特别注意的是:回调函数多数时候不是执行1次,而是会循环执行n次,当我们使用select进行sql功能时,往往输出的结果会是多行,那么有n行,就会执行n次的回调函数。回调函数中必须return 0,返回其它的值回调函数只会执行一次,无法执行多次
#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>
int callback(void *para,int column_size,char *column_value[],char *column_name[])
{
printf("para = %s\n",(char *)para);
int i;
for(i=0;i<column_size;i++){
printf("%s = %s\n",column_name[i],column_value[i]);
}
printf("======================================\n");
return 0;
}
int main(int argc,char **argv)
{
sqlite3 *db;
int ret;
char *errorMsg;
if(argc < 2){
printf("Usage:%s input error\n",argv[1]);
exit(-1);
}
ret = sqlite3_open(argv[1],&db);
if(ret == SQLITE_OK){
printf("open %s success\n",argv[1]);
}else{
printf("error:%s,%d\n",sqlite3_errmsg(db),ret);
if(ret == 14){
printf("permission denied\n");
exit(-1);
}
}
sqlite3_exec(db,"select * from stu",callback,"content from sql:",&errorMsg);
sqlite3_close(db);
printf("done\n");
return 0;
}
插入数据的C接口:
#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>
int callback(void *para,int column_size,char *column_value[],char *column_name[])
{
printf("para = %s\n",(char *)para);
int i;
for(i=0;i<column_size;i++){
printf("%s = %s\n",column_name[i],column_value[i]);
}
printf("======================================\n");
return 0;
}
int main(int argc,char **argv)
{
sqlite3 *db;
int ret;
char *errorMsg;
if(argc < 2){
printf("Usage:%s input error\n",argv[1]);
exit(-1);
}
ret = sqlite3_open(argv[1],&db);
if(ret == SQLITE_OK){
printf("open %s success\n",argv[1]);
}else{
printf("error:%s,%d\n",sqlite3_errmsg(db),ret);
if(ret == 14){
printf("permission denied\n");
exit(-1);
}
}
ret = sqlite3_exec(db,"create table class(id Integer,name char,score Integer)", \
callback,"content from sql:",&errorMsg);
printf("creat:ret = %d error msg = %s\n",ret,errorMsg);
sqlite3_exec(db,"insert into class values(001,'ksw',89)", \
callback,"content from sql:",&errorMsg);
printf("insert:ret = %d error msg = %s\n",ret,errorMsg);
sqlite3_exec(db,"select * from class",callback,"content from sql:",&errorMsg);
printf("select:ret = %d error msg = %s\n",ret,errorMsg);
sqlite3_exec(db,"alter table class add column sex char", \这里使用\进行连接连接换行
callback,"content from sql:",&errorMsg);
printf("alter:ret = %d error msg = %s\n",ret,errorMsg);
sqlite3_exec(db,"insert into class values(002,'lm',90,'g')", \
callback,"content from sql:",&errorMsg);
printf("insert:ret = %d error msg = %s\n",ret,errorMsg);
sqlite3_exec(db,"select * from class",callback,"content from sql:",&errorMsg);
printf("select:ret = %d error msg = %s\n",ret,errorMsg);
sqlite3_close(db);
printf("done\n");
return 0;
}