C++SQLite的使⽤总结
SQLite3简介
SQLite3只是⼀个轻型的嵌⼊式数据库引擎,占⽤资源⾮常低,处理速度⽐Mysql还快,专门⽤于移动设备上进⾏适量的数据存取,它只是⼀个⽂件,不需要服务器进程。
SQL语句是SQL操作的指令,我们⽤C/C++访问数据库时,需要⽤char*即C字符串来保存SQL语句,然后调⽤相应sqlite3库的函数,传⼊C字符串,来执⾏SQL指令。
常⽤术语:表(table)、字段(column,列,属性)、记录(row,record)。
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 =12WHERE 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 >12AND 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 >80AND 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;
mysql下载的vs库放在那个文件里 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 <100ORDER 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 <100ORDER 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 DEFAULT30);
外键:利⽤外键约束可以⽤来建⽴表与表之间的联系,⼀般是⼀张表的某个字段,引⽤着另⼀张表的主键的字段。
创建⼀个表:
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 利⽤外键来查询多张表中的数据:
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>。
主要是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、打开或者创建数据库。
1 sqlite3 *sql = NULL; // ⼀个打开的数据库实例
2const char * path = "..../test.db";//某个sql⽂件的路径
3
4// 根据⽂件路径打开数据库连接。如果数据库不存在,则创建。
5// 数据库⽂件的路径必须以C字符串传⼊。
6int result = sqlite3_open_v2(path, &sql, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_SHAREDCACHE, NULL);
7
8if (result == SQLITE_OK) {
9 std::clog << "打开数据库连接成功";
10 }
11else {
12 std::clog << "打开数据库连接失败";
13 }
3、执⾏不返回数据的SQL语句(增、删、改)。
1const char *sqlSentence = "INSERT INTO t_person(name, age) VALUES('夏明', 22); "; //SQL语句
2 sqlite3_stmt *stmt = NULL; //stmt语句句柄
3
4//进⾏插⼊前的准备⼯作——检查语句合法性
5//-1代表系统会⾃动计算SQL语句的长度
6int result = sqlite3_prepare_v2(sql, sqlSentence, -1, &stmt, NULL);
7
8if (result == SQLITE_OK) {
9 std::clog<< "添加数据语句OK";
10//执⾏该语句
11 sqlite3_step(stmt);
12 }
13else {
14 std::clog << "添加数据语句有问题";
15 }
16//清理语句句柄,准备执⾏下⼀个语句
17 sqlite3_finalize(stmt);
4、执⾏返回数据的SQL语句(查)
1const char *sqlSentence = "SELECT name, age FROM t_person WHERE age < 30;"; //SQL语句
2 sqlite3_stmt *stmt = NULL; // stmt语句句柄
3
4//进⾏查询前的准备⼯作——检查语句合法性
5//-1代表系统会⾃动计算SQL语句的长度
6int result = sqlite3_prepare_v2(sql, sqlSentence, -1, &stmt, NULL);
7
8if (result == SQLITE_OK) {
9 std::clog << "查询语句OK";
10// 每调⼀次sqlite3_step()函数,stmt语句句柄就会指向下⼀条记录
11while (sqlite3_step(stmt) == SQLITE_ROW) {
12// 取出第0列字段的值
13const unsigned char *name = sqlite3_column_text(stmt, 0);
14// 取出第1列字段的值
15int age = sqlite3_column_int(stmt, 1);
16//输出相关查询的数据
17 std::clog << "name = " << name <<", age = "<< age;
18 }
19 }
20else {
21 std::clog << "查询语句有问题";
22 }
23//清理语句句柄,准备执⾏下⼀个语句
24 sqlite3_finalize(stmt);
5、关闭数据库:sqlite3_close_v2(sqlite3* sql)
1if (sql) {
2 sqlite3_close_v2(sql);
3 sql = nullptr;
4 }
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, // 数据库实例
);
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论