创建FMDatabas对象时参数为SQLite数据库文件路径,该路径可以是一下三种方法之一
1.文件路径。该文件路径无需真实存在,如果不存在会自动创建
2.空字符串@”“,表示会在临时目录创建一个空的数据库,当FMDatabase连接关闭时,文件也会被删除。
3.NULL。将创建一个内在数据库,同样,当FMDatabase连接关闭时,数据将被销毁
//得到沙盒地址方法
-(NSString*)sandBox
{
NSArray *docArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = docArray[0];
NSString *filePath = [path stringByAppendingPathComponent:@"fmdb.sqlite"];
return filePath;
}
//fmdb打开数据库和建表
-(void)openAndCreat
{
//得到数据库对象
FMDatabase *db = [FMDatabase databaseWithPath:[self sandBox]];
BOOL isOpen = [db open];
if (isOpen) {
NSLog(@"db ok");
//建表,所有无返回集的操作都可以用update来执行sql语句,返回值为bool,判断操作成功
BOOL isCreat = [db executeUpdate:@"CREATE TABLE IF NOT EXISTS myFMDB (id integer PRIMARY KEY AUTOINCREMENT,name text NOT NULL,age integer NOT NULL DEFAULT 0)"];
if (isCreat) {
NSLog(@"table ok");
}
else
{//建表失败
[db lastError];
NSLog(@"table fs");
}
}
else
{
NSLog(@"db fs");
}
}
//增加数据
-(void)insertData
{
//得到实例对象
FMDatabase *db = [FMDatabase databaseWithPath:[self sandBox]];
//先关闭
[db close];
if ([db open]) {
//打开成功,插入数据
NSInteger age = [_ageTextField.text integerValue];
//两种方式
//使用update传参,占位符为?,参数值必须为对象
BOOL isExe = [db executeUpdate:@"INSERT INTO myFMDB (name,age)values(?,?)",_nameTextField.text,@(age)];
//使用updateWithFormat,占位符%@等
BOOL isExe2 = [db executeUpdateWithFormat:@"INSERT INTO myFMDB (name,age)values(%@,%d)",@"王",11];
if (isExe && isExe2) {
NSLog(@"insert ok");
}
}
}
//搜索方法
-(void)queryData
{
FMDatabase *db = [FMDatabase databaseWithPath:[self sandBox]];
[db open];
//执行查询
FMResultSet *result = [db executeQuery:@"SELECT * FROM myFMDB"];
//存储查询结果
_resultMArray = [[NSMutableArray alloc]init];
//循环获得结果集
//next 为ture时继续取下一条
while ([result next]) {
NSString *name = [result stringForColumn:@"name"];
NSInteger age = [result intForColumn:@"age"];
NSInteger id = [result intForColumn:@"id"];
NSLog(@"id = %ld,name = %@,age = %ld",id,name,age);
NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:name,@"name",@(age),@"age",@(id),@"id",nil];
[_resultMArray addObject:dic];
}
//释放结果集
[result close];
//搜索表里的记录数
[db executeQuery:@"select count(*) from myFMDB"];
//关数据库
[db close];
}
//单个字段值的查询
-(void)querySumRow
{
FMDatabase *db = [FMDatabase databaseWithPath:[self sandBox]];
if ([db open]) {
int sumRow = [db intForQuery:@"select age from myFMDB where id = 5"];
int sumRow2 = [db intForQuery:@"select count(*) from myFMDB"];
NSLog(@"%d,%d",sumRow,sumRow2);
}
}
FMDB多线程方法
//调用多线程方法
-(void)beginThread
{
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
[formatter setDateFormat:@"yy-MM-dd,hh:mm:ss.SSS"];
//开始时间
NSLog(@"%@",[formatter stringFromDate:[NSDate date]]);
//建表
[self createSecondTable];
//两种方法
[self threads];
// [self threadsSecond];不使用事务
//插入操作
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self threadsSecond];
NSLog(@"%@",[NSThread currentThread]);
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"这里是主线程--%@",[NSThread currentThread]);
});
});
//结束时间
NSLog(@"%@",[formatter stringFromDate:[NSDate date]]);
}
#pragma mark -- 多线程
-(void)threads
{
//创建队列
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:[self sandBox]];
__block BOOL isError = NO;
//使用事务的方式处理多个操作,不需要手动打开或关闭数据库
[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
//回滚,从错误操作开始回滚到正确的操作
for (int i = 0 ; i < 100000; i++) {
NSString *sql = @"insert into stu (name,age,gender)values(?,?,?);";
//插入操作
isError = [db executeUpdate:sql,@"飞燕",@(i),@"女"];
}
if (!isError) {
NSLog(@"insert fs");
*rollback = YES;//插入出错,回滚到上次正确的地方;
}
}];
}
//不使用事物处理多线程
-(void)threadsSecond
{
//得到队列
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:[self sandBox]];
__block BOOL isError = NO;
//不使用事务的多线程操作
[queue inDatabase:^(FMDatabase *db) {
// [db beginTransaction];//开始事务
for (int i = 0 ; i < 1000; i++) {
NSString *sql = @"insert into stu (name,age,gender)values(?,?,?);";
//插入操作
isError = [db executeUpdate:sql,@"飞燕",@(i),@"女"];
}
if (!isError) {
NSLog(@"insert fs");
}
// [db commit];//事务提交
NSLog(@"%@",[NSThread currentThread]);
}];
//上面是gcd同步队列
//关闭动画
dispatch_async(dispatch_get_main_queue(), ^{
//刷新UI要写在主线程
[self.loadV stopAnimation];
});
}