C++ Sqlite3的基本使用

|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,。。。);

?

1

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 表名;

?

1

DROP TABLE IF EXISTS t_person;

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

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

?

1

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

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

?

1

2

3

4

5

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 字段 = 字段值。

?

1

2

3

4

5

6

7

8

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 表名 别名;

?

1

2

3

4

5

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 表名;

?

1

2

3

SELECT count(nameFROM 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降序);

?

1

2

SELECT FROM t_person WHERE age < 100 ORDER BY age DESCname ASC;

// 先按年龄降序,再按名字升序。

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

?

1

2

SELECT FROM t_person WHERE age < 100 ORDER BY age DESCname ASC LIMIT 3, 5;

// 先筛选,后排序,再分页。

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

?

1

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

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

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

字段约束

  •  not null:字段的值不能为空。
  •  unique:字段的值必需唯一。
  •  default:指定字段的默认值。
  •  primary key:主键,用来唯一的标识某条记录,相当于记录的身份证。主键可以是一个或多个字段,应由计算机自动生成和管理。主键字段默认包含了not null和unique两个约束。
  •  autoincrement:当主键是integer类型时,应该增加autoincrement约束,能实现主键值的自动增长。

?

1

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

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

  •  创建一个表:

?

1

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字段。

?

1

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

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

?

1

2

3

4

5

   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

1、配置好C/C++项目环境:导入sqlite3.lib和sqlite3.dll,包含头文件#include <sqlite3.h>。(具体步骤此处不讲,可参考该网页)

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

?

1

2

3

4

5

6

7

8

9

10

11

12

13

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语句(增、删、改)。

  (执行更新、删除语句和执行创表、添加语句基本类似,只需更改sql语句即可。)

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

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, -1, &stmt, NULL);

 if (result == SQLITE_OK) {

 std::clog<< "添加数据语句OK";

 //执行该语句

 sqlite3_step(stmt);

 }

 else {

 std::clog << "添加数据语句有问题";

 }

 //清理语句句柄,准备执行下一个语句

 sqlite3_finalize(stmt);

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

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

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, -1, &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, 0);

 // 取出第1列字段的值

 int age = sqlite3_column_int(stmt, 1);

 //输出相关查询的数据

 std::clog << "name = " << name <<", age = "<< age;

 }

 }

 else {

 std::clog << "查询语句有问题";

 }

 //清理语句句柄,准备执行下一个语句

 sqlite3_finalize(stmt);

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

?

1

2

3

4

if (sql) {

sqlite3_close_v2(sql);

sql = nullptr;

}

|SQLite3 库函数 总结

1.打开数据库

?

1

2

3

4

5

6

int sqlite3_open_v2(

const char *filename,   // 数据库的文件路径

sqlite3 **ppDb,       // 数据库实例

int flags,          // 标志

const char *zVfs      // 使用该数据库的虚拟机的名字,这里我们不需要用,直接NULL

);

其中

flags参数有如下标志:

?

1

2

3

4

5

6

SQLITE_OPEN_NOMUTEX: 设置数据库连接运行在多线程模式(没有指定单线程模式的情况下)

SQLITE_OPEN_FULLMUTEX:设置数据库连接运行在串行模式。

SQLITE_OPEN_SHAREDCACHE:设置运行在共享缓存模式。

SQLITE_OPEN_PRIVATECACHE:设置运行在非共享缓存模式。

SQLITE_OPEN_READWRITE:指定数据库连接可以读写。

SQLITE_OPEN_CREATE:如果数据库不存在,则创建。

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

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

?

1

2

3

4

5

6

7

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

?

1

2

3

int sqlite3_step(

  sqlite3_stmt* stmt   //stmt句柄

 );

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

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

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

?

1

2

3

4

5

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句柄)

?

1

2

3

int sqlite3_finalize(

  sqlite_stmt* stmt      //stmt句柄

);

关闭数据库连接

?

1

2

3

int sqlite3_close_v2(

  sqlite3 * sql, // 数据库实例

);

直接编译并执行 SQL语句

(不推荐使用:1、没有SQL语法检查 2、每一句SQL语句即使完全一样,也会重新编译执行,对批量指令来说效率不高。)

?

1

2

3

4

5

6

7

int sqlite3_exec(

 sqlite3* sql, // 一个打开的数据库实例

 const char * sqlSentence, // 需要执行的SQL语句

 int (*callback)(void*,int,char**,char**), // SQL语句执行完毕后的回调

 void *,  // 回调函数的第1个参数

 char **errmsg // 错误信息

);

利用事务(BEGIN;COMMIT;)批量操作

如果要进行大量的操作,比如要插入10000条数据,如果逐条执行SQL语句,则消耗的时间非常长。采用事务的方式批量处理,可以极大程度提升操作速度(我用1000条记录实验了一下,速度提高了500倍以上)。sqlite3_exec可以执行任何sql语句,包括事务(“BEGIN TRANSACTION”)、回滚(“ROLLBACK”)和提交(“COMMIT”)等等

Eg1:

//插入条数据(在Begin和Commit之间批量操作,可以大幅度提高效率)
result =sqlite3_exec(db, "BEGIN;",0, 0, 0);
for (int i=0; i<10000; i++)
{
    //插入一条数据
    result = sqlite3_exec(db,
        "INSERT INTOMyTable (MyText, MyDate, MyTime, MyFloat) VALUES ('---上班好远!', '2012-03-23', '9:00:00', 1000);",
        0, 0, 0);
}
result =sqlite3_exec(db, "COMMIT;",0, 0, 0); .

Eg.2

string strSql;  
strSql+="begin;\n";  
for (int i=0;i<100;i++)  
{  
    strSql+="insert into MyTable values(null,'heh');\n";  
}  
strSql+="commit;";  
//cout<<strSql<<endl;  
 
nResult = sqlite3_exec(db,strSql.c_str(),NULL,NULL,&errmsg);  

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值