SQLite简介
- 什么是SQLite
1.SQLite是一款 轻型的嵌入式数据库
2.它占用资源非常低,在嵌入式设备中可能只需要几百K内存 - 常用关系型数据库
1.PC端:Oracle、MySQL、SQL server
2.嵌入式、移动端:SQLite
SQL语句的种类
- 数据定义语句(DDL:Data Definition Language)
1.包括Create和Drop等操作
2.在数据库中创建新表或删除表(create table或 drop table) - 数据操作语句(DML:Data Manipulation Language)
1.包括Insert、Update、Delete等操作
2.面的3种操作分别用于添加、修改、删除表中的数据 - 数据查询语句(DQL:Data Query Language)
1.可以用于查询获得表中的数据
2.关键字Select是DQL(也是所有SQL)用得最多的操作
3.其他DQL常用的关键字有Where,Order by,Group by和Having
字段类型
SQLite将数据划分为以下几种存储类型:
- integer : 整型值
- real : 浮点值
- text : 文本字符串
- blob : 二进制数据(比如文件)
创表
- Create table 表名 (字段名1 字段类型1, 字段名2 字段类型2, …) ;
- Create table if not exists 表名 (字段名1 字段类型1, 字段名2 字段类型2, …) ;
删表
- Drop table 表名 ;
- Drop table if exists 表名 ;
插入数据(insert)
- Insert into 表名 (字段1, 字段2, …) values (字段1的值, 字段2的值, …) ;
更新数据(update)
- Update 表名 set 字段1 = 字段1的值, 字段2 = 字段2的值, … ;
删除数据(delete)
- Delete from 表名 ;
Limit
- select * from 表名 limit 数值1, 数值2 ;
示例
select * from t_student limit 4, 8 ;
即跳过最前面4条语句,然后取8条记录
简单约束
建表时可以给特定的字段设置一些约束条件,常见的约束有
- not null :规定字段的值不能为null
- unique :规定字段的值必须唯一
- default :指定字段的默认值
Create table t_student (id integer, name text not null unique, age integer not null default 1) ;
name字段不能为null,并且唯一
age字段不能为null,并且默认为1
主键约束
什么是主键
1.主键(Primary Key)用来唯一地标识某一条记录 ,例如t_student可以增加一个id字段作为主键,相当于人的身份证
2.主键可以是一个字段或多个字段
主键的声明
在创表的时候用primary key声明一个主键
Create table t_student (id integer primary key, name text, age integer) ;
- integer类型的id作为t_student表的主键
- 只要声明为primary key,就说明是一个主键字段
- 主键字段默认就包含了not null 和 unique 两个约束
如果想要让主键自动增长(必须是integer类型),应该增加autoincrement
Create table t_student (id integer primary key autoincrement, name text, age integer) ;
外键约束
利用外键约束可以用来建立表与表之间的联系
外键的一般情况是:一张表的某个字段,引用着另一张表的主键字段
SQLite编码
在iOS中使用SQLite3,首先要添加库文件libsqlite3.dylib和导入主头文件
- 创建或打开数据库 :
//sqlite3 *db:一个打开的数据库实例
sqlite3 *db = NULL;
int result = sqlite3_open([path UTF8String], &db);
sqlite3_open()将根据文件路径打开数据库,如果不存在,则会创建一个新的数据库。如果result等于常量SQLITE_OK,则表示成功打开数据库
数据库文件的路径必须以C字符串(而非NSString)传入
- 关闭数据库:
sqlite3_close(db); - 执行不返回数据的SQL语句:
执行创表语句
// 用来存储错误信息
char *errorMsg = NULL;
char *sql = "create table if not exists t_person(id integer primary key autoincrement, name text, age integer);";
int result = sqlite3_exec(db, sql, NULL, NULL, &errorMsg);
sqlite3_exec()可以执行任何SQL语句,比如创表、更新、插入和删除操作。但是一般不用它执行查询语句,因为它不会返回查询到的数据
FMDB
- FMDB是iOS平台的SQLite数据库框架 ,以OC的方式封装了SQLite的C语言API
FMDB的优点 - 使用起来更加面向对象,省去了很多麻烦、冗余的C语言代码
- 提供了多线程安全的数据库操作方法,有效地防止数据混乱
1.打开数据库
通过指定SQLite数据库文件路径来创建FMDatabase对象
FMDatabase *db = [FMDatabase databaseWithPath:path];
if (![db open]) {
NSLog(@"数据库打开失败!");
}
文件路径有三种情况
- 具体文件路径 ,如果不存在会自动创建
- 空字符串@"" ,会在临时目录创建一个空的数据库 ,当FMDatabase连接关闭时,数据库文件也被删除
- nil ,会创建一个内存中临时数据库,当FMDatabase连接关闭时,数据库会被销毁
2.执行更新
使用executeUpdate:方法执行更新
- (BOOL)executeUpdate:(NSString*)sql, ...
- (BOOL)executeUpdateWithFormat:(NSString*)format, ...
- (BOOL)executeUpdate:(NSString*)sql withArgumentsInArray:(NSArray *)arguments
[db executeUpdate:@"UPDATE t_student SET age = ? WHERE name = ?;", @20, @"Jack"]
3.执行查询
- (FMResultSet )executeQuery:(NSString)sql, ...
- (FMResultSet )executeQueryWithFormat:(NSString)format, ...
- (FMResultSet *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray *)arguments
// 查询数据
FMResultSet *results = [db executeQuery:@"SELECT * FROM t_student"];
// 遍历结果集
while ([results next]) {
NSString *name = [results stringForColumn:@"name"];
int age = [results intForColumn:@"age"];
double score = [results doubleForColumn:@"score"];
}
4.FMDatabaseQueue
为了保证线程安全,FMDB提供方便快捷的FMDatabaseQueue类
//FMDatabaseQueue的创建
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:path];
- 简单使用
[queue inDatabase:^(FMDatabase *db) {
[db executeUpdate:@"INSERT INTO t_student(name) VALUES (?)", @"Jack"];
[db executeUpdate:@"INSERT INTO t_student(name) VALUES (?)", @"Rose"];
[db executeUpdate:@"INSERT INTO t_student(name) VALUES (?)", @"Jim"];
FMResultSet *results = [db executeQuery:@"select * from t_student"];
while ([results next]) {
// …
}
}];
- 使用事务
[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
[db executeUpdate:@"INSERT INTO t_student(name) VALUES (?)", @"Jack"];
[db executeUpdate:@"INSERT INTO t_student(name) VALUES (?)", @"Rose"];
[db executeUpdate:@"INSERT INTO t_student(name) VALUES (?)", @"Jim"];
FMResultSet *results = [db executeQuery:@"select * from t_student"];
while ([results next]) {
// …
}
}];
//事务回滚
*rollback = YES;