SQLite一种轻量级关系数据库,在嵌入式系统中使用比较广泛。
在iOS中使用SQLite需要添加库libsqlite3.0.dylib,并引入头文件#import
//打开数据库,资源不足或权限不够会打开失败
if (![db open])
{
NSLog(@"数据库打开失败");
}
//用完后需要关闭
[db close];
数据库操作:
查询操作:SELECT,返回FMResultSet,nil表示查询失败;
[db executeQuery:sql];
FMResultSet *rs = [db executeQuery:@"SELECT * FROM TableName"];
{
while ([rs next])
{
//获取查询结果,即使结果只有一条
}
}
更新操作:非SELECT操作都是更新操作,返回值类型BOOL,YES:成功,NO:失败
[db executeUpdate:sql];
数据库事务:
当需要插入的数据较多时,使用事务操作会比较快。
[db beginTransaction];
//需要执行的操作
[db commit];
FMResultSet *rs;
FMResultSet可以不手动关闭,当数据库关闭时,会跟着关闭。
2.FMDatabaseQueue 线程安全,所有的数据库操作会在队列中顺序执行
[FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:path];
queue inDatabase:^(FMDatabase *db) {
//
}];
queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
//
}
FMDB是ios平台的SQLite数据库框架;
FMDB以OC的方式封装了SQLite的C语言API
优点:
使用起来更加面向对象,省去了很多麻烦、冗余的C语言代码
对比苹果自带的Core Data框架,更加轻量级和灵活
核心类:
FMDataBase
一个FMDatabase对象就代表一个单独的SQLite数据库
用来执行SQL语句
FMResultSet
使用FMDatabase执行查询后的结果集
FMDatabaseQueue
用于在多线程中执行多个查询或更新,它是线程安全的
import "FMDB.h"
@property(nonatomic,strong)FMDatabase *db;
-(void)viewDidLoad{
[super viewDidLoad];
//获取cache文件夹路径
NSString *cachePath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES)[0];
//拼接文件名
NSString *filePath = [cachePath stringByAppendingPathComponent:@"student.sqlite"];
//创建一个数据库的实例
FMDatabase *db = [FMDatabase databaseWithPath:filePath];
_db = db;
//打开数据库
BOOL flag = [db open];
if(flag){
NSLog(@"打开成功");
}else{
NSLog(@"打开失败");
}
//创建数据库表
//数据库操作:插入、更新、删除都属于update
//查询Query
//参数:sqlite语句
BOOL flag1 = [db executeUpdate:@"create table if not exists t_contact(id integer primary key autoincrement,name text,phone text);"];
if(flag1){
NSLog(@"创建成功");
}else{
NSLog(@"创建失败");
}
}
//?:表示数据库里面的占位符;且不用打单引号;ps:只能代表对象,不能是基本数据类型,如果是int类型,就包装成NSNumber
-(IBAction)insert:(id)sender{
BOOL flag = [_db executeUpdate:@"insert into t_contact(name,phone)values (?,?)",@"ooo",@"23232"];
if(flag){
NSLog(@"success");
}else{
NSLog(@"failure");
}
}
-(IBAction)select:(id)sender{
FMResultSet *result = [_db executeQuery:@"select *fram t_contact"];
//从结果集里面往下找
while ([result next])
{
NSString *name = [result stringForColumn:@"name"];
NSString *phone = [result stringForColumn:@"phone"];
NSLog(@"%@--%@",name,phone);
}
}
-(IBAction)update:(id)sender{
BOOL flag = [_db executeUpdate:@"update t_contact set name = ?",@"adc"];
if(flag){
NSLog(@"success");
}else{
NSLog(@"failure");
}
}
-(IBAction)delete:(id)sender{
BOOL flag = [_db executeUpdate:@"delete from t_contact" ];
if(flag){
NSLog(@"success");
}else{
NSLog(@"failure");
}
}
FMDatabase这个类是线程不安全的,如果在多线程中同时使用一个FMDatabase实例,会造成数据混乱等问题
为了包装线程安全FMDB提供方便快捷的FMDatabaseQueue类
FMDatabaseQueue创建
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:path];
-(void)viewDidLoad{
[super viewDidLoad];
//获取cache文件夹路径
NSString *cachePath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES)[0];
//拼接文件名
NSString *filePath = [cachePath stringByAppendingPathComponent:@"user.sqlite"];
//创建一个数据库的实例
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:filePath];
_queue = queue;
//创建数据库表
//提供一个多线程安全的数据库实例
queue inDatabase:^(FMDatabase *db){
BOOL flag =[db executeUpdate:@"create table if not exists t_user (id integer primary key autoincrement,name text,money integer)"];
if(flag){
NSLog(@"success");
}else{
NSLog(@"failure");
}
}
}
-(IBAction)insert:(id)sender{
[_queue inDatabase:^(FMDatabase *db){
BOOL flag = [_db executeUpdate:@"insert into t_user(name,money)values (?,?)",@"a",@1000];
if(flag){
NSLog(@"success");
}else{
NSLog(@"failure");
}
[_db executeUpdate:@"insert into t_user(name,money)values (?,?)",@"b",@500];
}];
}
-(IBAction)select:(id)sender{
[_queue inDatabase:^(FMDatabase *db){
FMResultSet *result = [_db executeQuery:@"select *fram t_user"];
//从结果集里面往下找
while ([result next])
{
NSString *name = [result stringForColumn:@"name"];
int money = [result intForColumn:@"money"];
NSLog(@"%@--%@",name,money);
}
}];
}
-(IBAction)update:(id)sender{
// update t_user set money = 500 where name = 'a';
// update t_user set money = 1000 where name = 'b';
// a ->b 500 a 500
// b + 500 = b 1000
[_queue inDatabase:^(FMDatabase *db){
//开启事务
[db beginTransaction];
BOOL flag = [_db executeUpdate:@"update t_user set money = ? where name = ?;",@500 , @"a"];
if(flag){
NSLog(@"success");
}
else{
NSLog(@"failure");
//回滚
[db rollback];
}
BOOL flag1 = [_db executeUpdate:@"update t_user set money = ? where name = ?;",@1000 , @"b"];
if(flag1){
NSLog(@"success");
}
else
{
NSLog(@"failure");
[db rollbacl];
}
//全部操作完成时候再去
[db commit];
}];
}
-(IBAction)delete:(id)sender{
[_queue inDatabase:^(FMDatabase *db){
BOOL flag = [_db executeUpdate:@"delete from t_us er "];
if(flag){
NSLog(@"success");
}else{
NSLog(@"failure");
}
}];
}