SQLite3简介

  SQLite3只是一个轻型的嵌入式数据库引擎,占用资源非常低,处理速度比Mysql还快,专门用于移动设备上进行适量的数据存取,它只是一个文件,不需要服务器进程。

  SQL语句是SQL操作的指令,我们用C/C++访问数据库时,需要用char*即C字符串来保存SQL语句,然后调用相应sqlite3库的函数,传入C字符串,来执行SQL指令。

  常用术语表(table)、字段(column,列,属性)、记录(row,record)。

转载:https://www.cnblogs.com/KillerAery/p/9114124.html

  

SQL(structured query language)语句 

  特点:不区分大小写,每条语句后加";"结尾。

  关键字:select、insert、update、delete、from、creat、where、desc、order、by、group、table、alter、view、index等,数据库中不能使用关键字命名表和字段。

  数据定义语句(DDL:Data Definition Language)

  新建表 ⟹ create:create table 表名 (字段名1 字段类型1,字段名2 字段类型2,。。。); create table if not exists 表名 (字段名1 字段类型1,字段名2 字段类型2,。。。);

CREATE TABLE IF NOT EXISTS t_person (id integer PRIMARY KEY AUTOINCREMENT, name text NOT NULL, age integer NOT NULL); 

  删除表 ⟹ drop:dorp table 表名;drop table if exists 表名;

DROP TABLE IF EXISTS t_person; 

  数据操作语句(DML:Data Manipulation language)

  添加表中的数据 ⟹ insert:insert into 表名 (字段1,字段2,。。。) values (字段1的值,字段2的值);字符串内容用单引号。

INSERT INTO t_person (name, age) VALUES ('大明', 22); 

  修改表中的数据 ⟹ update:update 表名 set 字段1 = 字段1的值,字段2 = 字段2的值,。。。;

UPDATE t_person SET name = '小明', age = 10; // 把表中name字段的值全部改成小明,age字段的值全部改成10。  

UPDATE t_person SET age = 12 WHERE name = '小明'; // 把表中name字段值是小明的age值改为12。  

  删除表中的数据 ⟹ delete:delete from 表名;delete from 表名 where 字段 = 字段值。

DELETE FROM t_person; // 删除表中的所有记录。 

DELETE FROM t_person WHERE age = 25; // 删除表中字段age等于25的这条记录。 

DELETE FROM t_person WHERE age > 12 AND age < 15; // 删除表中年龄大于12且小于15的记录。 

  数据查询语句(DQL:Data Query Language)

  select:select 字段1, 字段2, 。。。 from 表名;select 字段1, 字段2, 。。。 from 表名 where 字段 = 某值;select * from 表名;(查询所有的字段)

  表别名:select 字段1 别名, 字段2 别名,。。。from 表名 别名;select 字段1 别名, 字段2 as 别名,。。。from 表名 as 别名;select 别名.字段1,别名.字段2,。。。from 表名 别名;

SELECT name, age FROM t_person WHERE age < 80; 

SELECT * FROM t_person WHERE age < 80; 

SELECT name, age nianling FROM t_person ren WHERE ren.age > 80 AND nianling < 90; 

  计算记录条数:select count(字段或者*) from 表名;

SELECT count(name) FROM t_person ren WHERE ren.age > 80; 

SELECT count(*) FROM t_person ren WHERE ren.age > 80; 

  where:where 字段 = 某值;where 字段 is 某值;where 字段 != 某值;where 字段 is not 某值;where 字段 > 某值;where 字段1 = 某值1 and 字段2 < 某值2;where 字段1 = 某值1 or 字段2 > 某值2;

  order by:select * from 表名 order by 字段(默认升序);select * from 表名 order by 字段 desc(降序);select * from 表名 order by 字段 asc(升序);select * from 表名 order by 字段1 asc(先按字段1升序),字段2 desc(再按字段2降序);

SELECT * FROM t_person WHERE age < 100 ORDER BY age DESC, name ASC; // 先按年龄降序,再按名字升序。  

  limit:select * from 表名 limit 数值1,数值2;分页查询,数值1表示跳过前面多少条,数值2表示取出之后多少条。select * from 表名 limit 数值2;(跳过前面0条,相当于select * from 表名 limit 0,数值2,表示最前面多少条数据)

SELECT * FROM t_person WHERE age < 100 ORDER BY age DESC, name ASC LIMIT 3, 5; // 先筛选,后排序,再分页。 

  like:模糊查询,select 字段1, 字段2, 。。。 from 表名 where 字段 like %某值%;

SELECT * FROM t_person WHERE name like '%明%'; 

  存储类型:integer(整型)、real(浮点型)、text(文本字符串)、blob(二进制数据)。

  实际上SQLite是无类型的,建表时声明的类型是为了方便程序员之间的交流,是一种良好的编程规范。

  字段约束:

  not null:字段的值不能为空。

  unique:字段的值必需唯一。

  default:指定字段的默认值。

  primary key:主键,用来唯一的标识某条记录,相当于记录的身份证。主键可以是一个或多个字段,应由计算机自动生成和管理。主键字段默认包含了not null和unique两个约束。

  autoincrement:当主键是integer类型时,应该增加autoincrement约束,能实现主键值的自动增长。

CREATE TABLE IF NOT EXISTS t_person (id integer PRIMARY KEY AUTOINCREMENT, name text NOT NULL UNIQUE, age integer NOT NULL DEFAULT 30); 

  外键:利用外键约束可以用来建立表与表之间的联系,一般是一张表的某个字段,引用着另一张表的主键的字段。

  创建一个表:

CREATE TABLE IF NOT EXISTS t_class (id integer PRIMARY KEY AUTOINCREMENT, name text NOT NULL UNIQUE);

  创建一个带外键的表:t_student表中有一个叫做fk_student_class的外键,这个外键的作用是让t_student表中的class_id字段引用t_class表中的id字段。

CREATE TABLE IF NOT EXISTS t_student (id integer PRIMARY KEY AUTOINCREMENT, name text NOT NULL, age integer NOT NULL, class_id integer NOT NULL, CONSTRAINT fk_student_class FOREIGN KEY (class_id) REFERENCES t_class(id)); 

  利用外键来查询多张表中的数据:

SELECT t.name t_name, t.age t_age, tc.name c_name FROM t_student t, t_class tc WHERE t.class_id = tc.id; // 查询所有学生对应的班级 

SELECT * FROM t_student WHERE class_id = (SELECT id FROM t_class WHERE name = '四班'); // 查询四班的所有学生

C/C++上使用SQLite3

  配置好C/C++项目环境:导入sqlite3.lib和sqlite3.dll,包含头文件#include <sqlite3.h>。

 1、下载sqlite3源码:http://www.sqlite.org/download.html

  主要是sqlite-amalgamation-XXXXXXX.zip、sqlite-dll-win32-x86-XXXXXXX.zip、sqlite-dll-win32-x64-XXXXXXX.zip

动态库编译:

  ps:如果没有特殊要求,可直接使用下载的sqlite-dll-*********.zip内的dll,那如果不放心就自己编译。

  1、使用vs2010创建win32工程,然后选择DLL和空项目,正常情况下vc6-vs2015都支持

  2、把sqlite3.c、sqlite3.h、sqlite3ext.h、sqlite3.def拷贝到工程源文件目录,前3个文件位于第一个zip,后一个文件位于后2个zip,用哪个就看你的目标环境。

  3、然后通过工程的资源管理器把上述4个文件添加到工程中

  4、修改工程配置,在配置属性-->c/c++-->预处理器-->预处理器定义,加入

  SQLITE_ENABLE_RTREE
  SQLITE_ENABLE_COLUMN_METADATA

  5、修改工程配置,在配置属性-->链接器-->输入-->模块定义文件 加入sqlite3.def,然后编译即可。

静态库编译: 

  1、使用vs2010创建win32工程,然后选择静态库,去掉预编译头,正常情况下vc6-vs2015都支持

  2、把sqlite3.c、sqlite3.h、sqlite3ext.h、sqlite3.def拷贝到工程源文件目录,前3个文件位于第一个zip,后一个文件位于后2个zip,用哪个就看你的目标环境。

  3、然后通过工程的资源管理器把上述4个文件添加到工程中

  4、修改工程配置,在配置属性-->c/c++-->预处理器-->预处理器定义,加入

  SQLITE_ENABLE_RTREE
  SQLITE_ENABLE_COLUMN_METADATA

  5、修改工程配置,在配置属性-->链接器-->输入-->模块定义文件 加入sqlite3.def,然后编译即可。

 2、打开或者创建数据库。

     sqlite3 *sql = NULL; // 一个打开的数据库实例
const char * path = "..../test.db";//某个sql文件的路径 // 根据文件路径打开数据库连接。如果数据库不存在,则创建。
// 数据库文件的路径必须以C字符串传入。
int result = sqlite3_open_v2(path, &sql, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_SHAREDCACHE, NULL); if (result == SQLITE_OK) {
std::clog << "打开数据库连接成功";
}
else {
std::clog << "打开数据库连接失败";
}

 3、执行不返回数据的SQL语句(增、删、改)。

     const char *sqlSentence = "INSERT INTO t_person(name, age)     VALUES('夏明', 22); ";        //SQL语句
sqlite3_stmt *stmt = NULL; //stmt语句句柄 //进行插入前的准备工作——检查语句合法性
//-1代表系统会自动计算SQL语句的长度
int result = sqlite3_prepare_v2(sql, sqlSentence, -, &stmt, NULL); if (result == SQLITE_OK) {
std::clog<< "添加数据语句OK";
//执行该语句
sqlite3_step(stmt);
}
else {
std::clog << "添加数据语句有问题";
}
//清理语句句柄,准备执行下一个语句
sqlite3_finalize(stmt);

 4、执行返回数据的SQL语句(查)

     const char *sqlSentence = "SELECT name, age FROM t_person WHERE age < 30;";    //SQL语句
sqlite3_stmt *stmt = NULL; // stmt语句句柄 //进行查询前的准备工作——检查语句合法性
//-1代表系统会自动计算SQL语句的长度
int result = sqlite3_prepare_v2(sql, sqlSentence, -, &stmt, NULL); if (result == SQLITE_OK) {
std::clog << "查询语句OK";
// 每调一次sqlite3_step()函数,stmt语句句柄就会指向下一条记录
while (sqlite3_step(stmt) == SQLITE_ROW) {
// 取出第0列字段的值
const unsigned char *name = sqlite3_column_text(stmt, );
// 取出第1列字段的值
int age = sqlite3_column_int(stmt, );
//输出相关查询的数据
std::clog << "name = " << name <<", age = "<< age;
}
}
else {
std::clog << "查询语句有问题";
}
//清理语句句柄,准备执行下一个语句
sqlite3_finalize(stmt);

 5、关闭数据库:sqlite3_close_v2(sqlite3* sql)

      if (sql) {
sqlite3_close_v2(sql);
sql = nullptr;
}

SQLite3 库函数 总结

  1.打开数据库

int sqlite3_open_v2(
const char *filename,   // 数据库的文件路径
sqlite3 **ppDb,       // 数据库实例
int flags,          // 标志
const char *zVfs      // 使用该数据库的虚拟机的名字,这里我们不需要用,直接NULL
);

  flags参数有如下标志:
  SQLITE_OPEN_NOMUTEX: 设置数据库连接运行在多线程模式(没有指定单线程模式的情况下)
  SQLITE_OPEN_FULLMUTEX:设置数据库连接运行在串行模式。
  SQLITE_OPEN_SHAREDCACHE:设置运行在共享缓存模式。
  SQLITE_OPEN_PRIVATECACHE:设置运行在非共享缓存模式。
  SQLITE_OPEN_READWRITE:指定数据库连接可以读写。
  SQLITE_OPEN_CREATE:如果数据库不存在,则创建。

 2.检查SQL语句的合法性(查询前的准备)

 若语句合法即编译通过,则将语句产生的指令塞进stmt句柄(此时并未执行指令)

int sqlite3_prepare_v2(
sqlite3 *db, // 数据库实例
const char *zSql, // 需要检查的SQL语句
int nByte, // SQL语句的最大字节长度
sqlite3_stmt **ppStmt, // stmt句柄,用来存储SQL stmt指令
const char **pzTail
);

 3.执行stmt句柄(执行存储在stmt句柄的指令

 如果指令能查询到下一行数据,就会返回SQLITE_ROW

 如果指令(例如写入数据)不需要返还数据,就会返还SQLITE_DONE

int sqlite3_step(
  sqlite3_stmt* stmt   //stmt句柄
);

 4.利用stmt句柄获得第iCol字段的值(字段的下标从0开始)

 //执行完查询句柄后,stmt就会指向查到的数据

 //然后可以通过stmt获取相应数据

double sqlite3_column_double(sqlite3_stmt*, int iCol);                  // 浮点数据
int sqlite3_column_int(sqlite3_stmt*, int iCol); // 整型数据
sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); // 长整型数据
const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); // 二进制文本数据
const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); // 字符串数据

清理语句句柄(以便重复使用同一个stmt句柄)

int sqlite3_finalize(
  sqlite_stmt* stmt      //stmt句柄
);

关闭数据库连接

int sqlite3_close_v2(
  sqlite3 * sql, // 数据库实例
);

C++ SQLite的使用总结的更多相关文章

  1. 【开源】分享2011-2015年全国城市历史天气数据库【Sqlite+C#访问程序】

    由于个人研究需要,需要采集天气历史数据,前一篇文章:C#+HtmlAgilityPack+XPath带你采集数据(以采集天气数据为例子),介绍了基本的采集思路和核心代码,经过1个星期的采集,历史数据库 ...

  2. UWP开发之ORM实践:如何使用Entity Framework Core做SQLite数据持久层?

    选择SQLite的理由 在做UWP开发的时候我们首选的本地数据库一般都是Sqlite,我以前也不知道为啥?后来仔细研究了一下也是有原因的: 1,微软做的UWP应用大部分也是用Sqlite.或者说是微软 ...

  3. 深入解析Sqlite的完美替代者,android数据库新王者——Realm

    写在前面: 又到一年一度七夕虐狗节,看着大家忍受着各种朋友圈和QQ空间还有现实生活中的轮番轰炸,我实在不忍心再在这里给大家补刀,所以我觉得今天不虐狗,继续给大家分享有用的. 如果你比较关心androi ...

  4. VS15 preview 5打开文件夹自动生成slnx.VC.db SQLite库疑惑?求解答

    用VS15 preview 5打开文件夹(详情查看博客http://www.cnblogs.com/zsy/p/5962242.html中配置),文件夹下多一个slnx.VC.db文件,如下图: 本文 ...

  5. Android之SQLite数据存储

    一.SQLite保存数据介绍 将数据库保存在数据库对于重复或者结构化数据(比如契约信息)而言是理想之选.SQL数据库的主要原则之一是架构:数据库如何组织正式声明.架构体现于用于创建数据库的SQL语句. ...

  6. 【教程】SQLite数据库修复

    SQLite 大家都知道,就不多说了. 有时候数据量大了,或者存储过程中出现异常,数据库就可能会出问题. 这是以前公司产品出现过的问题,导致软件都打不开了,我花了不少时间才解决的,趁现在有空贡献出来. ...

  7. SQLite学习笔记(十)&&加密

    随着移动互联网的发展,手机使用越来越广泛,sqlite作为手机端存储的一种解决方案,使用也非常普遍.但是sqlite本身安全特性却比较弱,比如不支持用户权限,只要能获取到数据库文件就能进行访问:另外也 ...

  8. mono for android中使用dapper或petapoco对sqlite进行数据操作

    在mono for android中使用dapper或petapoco,很简单,新建android 类库项目,直接把原来的文件复制过来,对Connection连接报错部分进行注释和修改就可以运行了.( ...

  9. 【腾讯Bugly干货分享】微信iOS SQLite源码优化实践

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57b58022433221be01499480 作者:张三华 前言 随着微信iO ...

  10. 【腾讯Bugly干货分享】移动客户端中高效使用SQLite

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57b57f2a0703f7d31b9a3932 作者:赵丰 导语 iOS 程序能 ...

随机推荐

  1. 【VS开发】这就是COM组件

    [实例]这就是COM组件 时间 2012-02-21 10:49:15  CSDN博客 原文  http://blog.csdn.net/btwsmile/article/details/727849 ...

  2. kubenetes 的svc从ClusterPort 改为NodePort

    1.yaml文件如下 spec: clusterIP: 10.233.43.125 ports: - name: http-metrics port: protocol: TCP targetPort ...

  3. POJ1041 John's trip 【字典序输出欧拉回路】

    题目链接:http://poj.org/problem?id=1041 题目大意:给出一个连通图,判断是否存在欧拉回路,若存在输出一条字典序最小的路径. 我的想法: 1.一开始我是用结构体记录边的起点 ...

  4. Update语句的Output从句结构

    原文:Update语句的Output从句结构 一,先看1个列子 ) dbo.Table_1 set status = 'C' --2,选择前3条数据output deleted.id,deleted. ...

  5. MySql 多表关系

    多表关系 一对一关系 一对一关系是最好理解的一种关系,在数据库建表的时候可以将人表的主键放置与身份证表里面,也可以将身份证表的主键放置于人表里面 一对多关系 班级是1端,学生是多端,结合面向对象的思想 ...

  6. Gson格式转换Integer变为Double类型问题解决

    问题描述 在前后端分离的开发模式下,前后端交互通常采用JSON格式数据.自然会涉及到json字符串与JAVA对象之间的转换.实现json字符串与Java对象相互转换的工具很多,常用的有Json.Gso ...

  7. Nginx、OpenResty和Kong的基本概念与使用方法

    Nginx.OpenResty和Kong的基本概念与使用方法 2018年10月10日 22:46:08 李佶澳 阅读数 322更多 分类专栏: kubernetes   版权声明:本文为博主原创文章, ...

  8. lua加载DLL

    .cpp //若没有在项目属性--库文件.依赖文件.包含添加.则添加一下路径 #pragma  comment (lib,"lua5.1.lib") #include " ...

  9. 简单的todolist的demo

    放上代码: <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF ...

  10. 如何源码编译安装并控制nginx

    安装nginx 注意 Linux操作系统需要2.6及其以上的内核(支持epoll) 使用nginx的必备软件 gcc编辑器 yum -y install gcc gcc-c++ pcre库(支持正则表 ...