FMDatabase操作sqlite数据库

1.FMDB有三个主要的类

FMDatabase – 表示一个单独的sqlite数据库。 用来执行sqlite的命令。

FMResultSet – 表示FMDatabase执行查询后结果集。

FMDatabaseQueue – 如果你想在多线程中执行多个查询或更新,你应该使用该类。这是线程安全的。

通过指定sqlite数据库文件路径来创建FMDatabase对象

FMDatabase *db = [FMDatabase databaseWithPath:path];

if (![db open]) {

NSLog(@"数据库打开失败!");

}

文件路径有三种情况

(1)具体文件路径

  如果不存在会自动创建

(2)空字符串@""

  会在临时目录创建一个空的数据库

  当FMDatabase连接关闭时,数据库文件也被删除

(3)nil

  会创建一个内存中临时数据库,当FMDatabase连接关闭时,数据库会被销毁

2.FMResultSet提供了很多方法来获得所需的格式的值:


intForColumn:
longForColumn:
longLongIntForColumn:
boolForColumn:
doubleForColumn:
stringForColumn:
dataForColumn:
datanocopyForColumn:
UTF8StringForColumnIndex:
objectForColumn:

3.FMDB语句执行

一切不是SELECT命令的命令都视为更新。这包括CREATE,UPDATE,INSERT,ALTER,COMMIT,BEGIN,DETACH,DELETE,DROP,END,EXPLAIN,VACUUM,and REPLACE(等)。简单来说,只要不是以SELECT开头的命令都是UPDATE命令。执行更新返回一个BOOL值。YES表示执行成功,否则表示有那些错误

在FMDB中,除查询以外的所有操作,都称为“更新”

create、drop、insert、update、delete等

使用executeUpdate:方法执行更新

- (BOOL)executeUpdate:(Nsstring*)sql,...

-(BOOL)executeUpdateWithFormat:(Nsstring*)format,...

- (BOOL)executeUpdate:(Nsstring*)sqlwithArgumentsInArray:(NSArray *)arguments

示例

[db executeUpdate:@"UPDATE t_studentSET age = ? WHERE name = ?;",@20,@"Jack"]


SELECT命令就是查询,执行查询方法是以 -excuteQuery开头的。执行查询时,如果成功返回FMResultSet对象, 错误返回nil. 与执行更新相当,支持使用 NSError**参数。

查询方法

- (FMResultSet*)executeQuery:(Nsstring*)sql,...

- (FMResultSet*)executeQueryWithFormat:(Nsstring*)format,...

- (FMResultSet *)executeQuery:(Nsstring*)sql withArgumentsInArray:(NSArray *)arguments

示例

// 查询数据

FMResultSet *rs = [dbexecuteQuery:@"SELECT * FROM t_student"];

// 遍历结果集

while ([rs next]) {

Nsstring *name = [RSStringForColumn:@"name"];

int age = [rsintForColumn:@"age"];

double score = [rs doubleForColumn:@"score"];

}


4.FMDB中sqlite数据绑定语法

sqlite会识别 “?” 为一个输入的点位符, 这样的执行会接受一个可变参数(或者表示为其他参数,如NSArray,NSDictionary,或va_list等),会正确为您转义。

一定要注意(提供给 -executeUpdate: 方法的参数都必须是对象。就像以下的代码就无法工作,且会产生崩溃。)参数必须是 NSObject 的子类,所以象 int,double,bool 这种基本类型,需要封装成对应的包装类才行

NSNumber * intNumber=[NSNumber numberWithInt:1];
    [self.database executeUpdate:@"insert into storeProduct(installDate,startTimes) values (?,?)",[NSDate date],intNumber];



或者

-execute*WithFormat:的方法的内部实现会帮你封装数据, 以下这些修饰符都可以使用: %@,%c,%s,%d,%D,%i,%u,%U,%hi,%hu,%qi,%qu,%f,%g,%ld,%lu,%lld,and %llu.除此之外的修饰符可能导致无法预知的结果。一些情况下,你需要在sql语句中使用 % 字符,你应该使用 %%。

NSNumber * intNumber=[NSNumber numberWithInt:1];
    [self.database executeUpdateWithFormat:@"insert into storeProduct(installDate,startTimes,request) values (%@,%@,%d)",intNumber,YES];


5.FMDatabaseQueue多线程安全

在多个线程中同时使用一个FMDatabase实例是不明智的。现在你可以为每个线程创建一个FMDatabase对象。
不要让多个线程分享一个实例,它无法在多个线程中同时使用。 若此,坏事会经常发生,程序会时不时崩溃,
或者报告异常,或者陨石会从天空中掉下来砸到你Mac Pro.总之很崩溃。
所以,不要初始化FMDatabase对象,然后在多个线程中使用。
请使用 FMDatabaseQueue,它是你的朋友而且会帮助你。以下是使用方法
首先创建队列。
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath];
这样使用。


[queue inDatabase:^(FMDatabase *db) {
[db executeUpdate:@"INSERT INTO myTable VALUES (?)",[NSNumber numberWithInt:1]];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)",[NSNumber numberWithInt:2]];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)",[NSNumber numberWithInt:3]];
FMResultSet *rs = [db executeQuery:@"select * from foo"];
while([rs next]) {

}
}];

像这样,轻松地把简单任务包装到事务里:


[queue inTransaction:^(FMDatabase *db,BOOL *rollback) {
[db executeUpdate:@"INSERT INTO myTable VALUES (?)",[NSNumber numberWithInt:3]];
if (whoopsSomethingWrongHappened) {
*rollback = YES; return;
}
// etc…
[db executeUpdate:@"INSERT INTO myTable VALUES (?)",[NSNumber numberWithInt:4]];
}];

FMDatabaseQueue后台会建立系列化的G-C-D队列,并执行你传给G-C-D队列的块。这意味着 你从多线程同时调用调用方法
GDC也会按它接收的块的顺序来执行。谁也不会吵到谁的脚 ,每个人都幸福。

6.总结写代码


#import <Foundation/Foundation.h>
#import "FMDB.h"
@interface sqlLiteSKStoreProduct : NSObject
-(BOOL)isTanchu;
-(void)setNotRequest;
-(void)resetStartTimes;
-(void)addRestartTimes;
@end





#import "sqlLiteSKStoreProduct.h"
@interface sqlLiteSKStoreProduct()
@property FMDatabase *database;
@end
@implementation sqlLiteSKStoreProduct
-(id)init{
	self=[super init];
	[self openSKStoreProductDatabase];
	[self createLoginInfoTable];
	return self;
}

-(void)dealloc{
	[_database commit];
	[_database close];
}

-(BOOL) openSKStoreProductDatabase{
	//获取Document文件夹下的数据库文件,没有则创建
	Nsstring *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES) objectAtIndex:0];
	Nsstring *dbPath = [docPath stringByAppendingPathComponent:@"SKStoreProduct.db"];
	//获取数据库并打开
	self.database  = [FMDatabase databaseWithPath:dbPath];
	if (![self.database open]) {
		NSLog(@"Open database Failed");
		return NO;
		self.database=nil;
	}
	else{
		return YES;
	}
}

-(BOOL) createLoginInfoTable{
	if (self.database!=nil) {
		return [self.database executeUpdate:@"create table if not exists storeProduct(id INTEGER PRIMARY KEY,installDate date,startTimes int,request bool)"];
	}
	else{
		return NO;
	}
}
-(BOOL)isTanchu{
	if (self.database!=nil) {
		FMResultSet *resultSet1 = [self.database executeQuery:@"select * from storeProduct"];
		if (resultSet1!=nil && ![resultSet1 next]) {
			NSNumber * intNumber=[NSNumber numberWithInt:1];
		   [self.database executeUpdateWithFormat:@"insert into storeProduct(installDate,YES];
		   return NO;
		}
		NSDate* installDate=nil;
		int restartTimes=0;
		int ID=-1;
		FMResultSet *resultSet = [self.database executeQuery:@"select * from storeProduct"];
		while ([resultSet next]) {
			BOOL requestBool =[resultSet boolForColumn:@"request"];
			if (!requestBool) {
				return NO;
			}
			installDate = [resultSet dateForColumn:@"installDate"];
			restartTimes= [resultSet intForColumn:@"startTimes"];
			ID=[resultSet intForColumn:@"id"];
			break;
		}
		NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
		NSDate * curDate=[NSDate date];
		NSUInteger unitFlags = NSMonthCalendarUnit | NSDayCalendarUnit | NSYearCalendarUnit;
		NSDateComponents *components = [gregorian components:unitFlags fromDate:installDate toDate:curDate options:0];
		long days=[components day];
		if (days > 7 && restartTimes >15) {
			return YES;
		} else {
			return NO;
		}
	}
	else{
		return NO;
	}

}
-(void)setNotRequest{
	if (self.database!=nil) {
		FMResultSet *resultSet1 = [self.database executeQuery:@"select * from storeProduct"];
		if (resultSet1!=nil && ![resultSet1 next]) {
			NSNumber * intNumber=[NSNumber numberWithInt:1];
			[self.database executeUpdateWithFormat:@"insert into storeProduct(installDate,NO];
			return ;
		}
		int ID=0;
		FMResultSet *resultSet = [self.database executeQuery:@"select * from storeProduct"];
		while ([resultSet next]) {
			ID= [resultSet intForColumn:@"id"];
			break;
		}
		[self.database executeUpdateWithFormat:@"update storeProduct set request = %d where id = %d",NO,ID];
    }
}
-(void)resetStartTimes{
	if (self.database!=nil) {
		FMResultSet *resultSet1 = [self.database executeQuery:@"select * from storeProduct"];
		if (resultSet1!=nil && ![resultSet1 next]) {
			NSNumber * intNumber=[NSNumber numberWithInt:1];
			[self.database executeUpdateWithFormat:@"insert into storeProduct(installDate,YES];
			return ;
		}
		int ID=0;
		FMResultSet *resultSet = [self.database executeQuery:@"select * from storeProduct"];
		while ([resultSet next]) {
			ID= [resultSet intForColumn:@"id"];
			break;
		}
		NSNumber * intNumber=[NSNumber numberWithInt:1];
		[self.database executeUpdateWithFormat:@"update storeProduct set startTimes = %@ where id = %d",ID];
	}
}
-(void)addRestartTimes{
	if (self.database!=nil) {
		FMResultSet *resultSet1 = [self.database executeQuery:@"select * from storeProduct"];
		if (resultSet1!=nil && ![resultSet1 next]) {
			NSNumber * intNumber=[NSNumber numberWithInt:1];
			[self.database executeUpdateWithFormat:@"insert into storeProduct(installDate,YES];
			return ;
		}
		int ID=0;
		FMResultSet *resultSet = [self.database executeQuery:@"select * from storeProduct"];
		int restartTimes=0;
		while ([resultSet next]) {
			restartTimes= [resultSet intForColumn:@"startTimes"];
			ID= [resultSet intForColumn:@"id"];
			restartTimes++;
			break;
		}
		NSNumber * intNumber=[NSNumber numberWithInt:restartTimes];
		[self.database executeUpdateWithFormat:@"update storeProduct set startTimes = %@ where id = %d",ID];
	}
}
@end


参考:http://www.jb51.cc/article/p-kvuisyqi-nn.html

相关文章

SQLite架构简单,又有Json计算能力,有时会承担Json文件/RES...
使用Python操作内置数据库SQLite以及MySQL数据库。
破解微信数据库密码,用python导出微信聊天记录
(Unity)SQLite 是一个软件库,实现了自给自足的、无服务器...
安卓开发,利用SQLite实现登陆注册功能