ios FMDB 简单使用

//数据库操作软件可以用Navicat premium

//  WTTEstContController.m

//  GraspCourse

//

//  Created by admin10 on 2019/3/19.

//  Copyright © 2019年 sun. All rights reserved.

//

#import "WTTEstContController.h"

#import <CoreImage/CoreImage.h>

#define screenW [UIScreen mainScreen].bounds.size.width

#define screenH [UIScreen mainScreen].bounds.size.height

#import "UILabel+Vertical.h"

#import "FMDB.h"

#import "AddressItem.h"

static NSString * const TestName = @"test.db";

@interface WTTEstContController ()

@property(nonatomic,strong) UIImageView *imageView;

@property (nonatomic, strong) FMDatabase *fmdb;

@end

@implementation WTTEstContController

- (void)creatDB{

    NSString *dbPath = [self pathForName:TestName];

    self.fmdb = [FMDatabase databaseWithPath:dbPath];

}

//获得指定名字的文件的全路径

- (NSString *)pathForName:(NSString *)name

{

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    NSString *documentDirectory = [paths lastObject];

    NSString *dbPath = [documentDirectory stringByAppendingPathComponent:name];

    return dbPath;

}

- (void)viewDidLoad {

    [super viewDidLoad];

    self.view.backgroundColor = [UIColor whiteColor];

    for (int i = 0; i < 3; i ++) {

        UIButton *contentBtn  = [UIButton buttonWithType:UIButtonTypeCustom];

        [contentBtn setBackgroundColor:[UIColor greenColor]];

        [contentBtn addTarget:self action:@selector(buttonClicks:) forControlEvents:UIControlEventTouchUpInside];

        contentBtn.titleLabel.font= FontSize(15);

        contentBtn.tag = i;

        [contentBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];

        [self.view addSubview:contentBtn];

        [contentBtn mas_makeConstraints:^(MASConstraintMaker *make){

            make.left.equalTo(self.view).offset(90 * i);

            //make.bottom.equalTo(self.view);

            make.top.equalTo(self.view).offset(70);

            make.height.and.width.equalTo(@80);

        }];

    }

    

     [self creatDB];

}

- (void)buttonClicks:(UIButton *)btn{

    

    if (btn.tag == 0) {

        

        [self creatDB];

        

    }else if (btn.tag == 1){

        BOOL iskai = [self createTable];

        if (!iskai) {

            NSLog(@"表创建失败");

        }else{

            NSLog(@"表创建成功");

            [self insertRecords];

        }

    }else{

        HY_Weak;

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

            NSMutableArray *array = [weakSelf queryAllProvince];

            NSLog(@"%ld",array.count);

            

        });

    }

}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

    BOOL iskai = [self createTable];

    if (!iskai) {

        NSLog(@"表创建失败");

    }else{

         NSLog(@"表创建成功");

        [self insertRecords];

        HY_Weak;

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

      NSMutableArray *array = [weakSelf queryAllProvince];

            

            

            NSLog(@"%ld",array.count);

            

        });

    }

}

//往表插入数据

- (void)insertRecords{

    

    //NSDate *startTime = [NSDate date];

    // 开启事务

    if ([self.fmdb open] && [self.fmdb beginTransaction]) {

        

        BOOL isRollBack = NO;

        @try

        {

//                NSString *insertSql= [NSString stringWithFormat:

//                                      @"INSERT INTO %@ ('sheng','di','xian','name', 'level') VALUES ('%@','%@','%@','%@','%@')",

//                                      @"testname", @"12",@"13",@"14" ,@"15", @"16"];

//                BOOL a = [self.fmdb executeUpdate:insertSql];

            

             BOOL a = [self.fmdb executeUpdate:@"insert into testname ('sheng','di','xian','name','level') values (?,?,?,?,?)",@"12",@"13",@"14",@"15",@"16"];

            

                if (!a)

                {

                    NSLog(@"插入地址信息数据失败");

                }

                else

                {

                    NSLog(@"批量插入地址信息数据成功!");

                    

                }

//            NSDate *endTime = [NSDate date];

//            NSTimeInterval a = [endTime timeIntervalSince1970] - [startTime timeIntervalSince1970];

//            NSLog(@"使用事务地址信息用时%.3f秒",a);

            

        }

        @catch (NSException *exception)

        {

            isRollBack = YES;

            [self.fmdb rollback];

        }

        @finally

        {

            if (!isRollBack)

            {

                [self.fmdb commit];

            }

        }

        [self.fmdb close];

        

    } else {

        [self insertRecords];

    }

}

//创建表

- (BOOL)createTable{

    BOOL result = NO;

    BOOL openSuccess = [self.fmdb open];

    if (!openSuccess) {

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

    } else {

        NSLog(@"地址数据库打开成功");

        //'code','sheng','di','xian','name', 'level'

        NSString *sql = [NSString stringWithFormat:@"create table if not exists %@ (code integer primary key autoincrement,sheng text,di text,xian text,name text,level text);",@"testname"];

        result = [self.fmdb executeUpdate:sql];

        if (!result) {

            NSLog(@"创建地址表失败");

            

        } else {

            NSLog(@"创建地址表成功");

        }

    }

    [self.fmdb close];

    return result;

}

//根据areaLevel 查询

- (NSMutableArray *)queryAllProvince

{

    if ([self.fmdb  open]) {

        NSString *sql = [NSString stringWithFormat:@"SELECT * FROM %@", @"testname"];

        FMResultSet *result = [self.fmdb  executeQuery:sql];

        NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:0];

        //'code','sheng','di','xian','name', 'level'

        while ([result next]) {

            AddressItem *model = [[AddressItem alloc] init];

            model.code = [result stringForColumn:@"code"];

            model.sheng = [result stringForColumn:@"sheng"];

            model.di = [result stringForColumn:@"di"];

            model.xian = [result stringForColumn:@"xian"];

            model.name = [result stringForColumn:@"name"];

            model.level = [result stringForColumn:@"level"];

            [array addObject:model];

        }

        [self.fmdb close];

        return array;

    }

    return nil;

}

//// 判断是否存在表

//- (BOOL) isTableOK

//{

//    BOOL openSuccess = [self.fmdb open];

//    if (!openSuccess) {

//        NSLog(@"地址数据库打开失败");

//    } else {

//        NSLog(@"地址数据库打开成功");

//        FMResultSet *rs = [self.fmdb executeQuery:@"SELECT count(*) as 'count' FROM sqlite_master WHERE type ='table' and name = ?", @"testwozi"];

//        while ([rs next])

//        {

//            // just print out what we've got in a number of formats.

//            NSInteger count = [rs intForColumn:@"count"];

//            if (0 == count)

//            {

//                [self.fmdb close];

//                return NO;

//            }

//            else

//            {

//                [self.fmdb close];

//                return YES;

//            }

//        }

//    }

//    [self.fmdb close];

//    return NO;

//}

@end

FMDB

前言.

去年整理的文章了,好久不做ios,再不发,估计ios就废了,拿来记录一下,大牛勿喷

一、FMDB简介

1.什么是 FMDB

FMDB 是 iOS 平台的 SQLite 数据库框架

FMDB 以 OC 的方式封装了 SQLite 的 C 语言 API

2.FMDB的优点

使用起来更加面向对象,省去了很多麻烦、冗余的C语言代码

对比苹果自带的Core Data框架,更加轻量级和灵活

提供了多线程安全的数据库操作方法,有效地防止数据混乱

3.FMDB 的 github 地址

https://github.com/ccgus/fmdb

二、使用说明

cocopads 引入 FMDB 库

pod 'FMDB'

三、核心类

FMDB有三个主要的类

(1)FMDatabase

一个FMDatabase对象就代表一个单独的SQLite数据库

用来执行SQL语句

(2)FMResultSet

使用FMDatabase执行查询后的结果集

(3)FMDatabaseQueue

用于在多线程中执行多个查询或更新,它是线程安全的

四、打开数据库

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

// 1..创建数据库对象
FMDatabase *db = [FMDatabase databaseWithPath:path];
// 2.打开数据库
if ([db open]) {
    // do something
} else {
    DLog(@"fail to open database");
}

文件路径有三种情况

(1)具体文件路径

如果不存在会自动创建
  
  [备注]使用绝对路径

(2)空字符串@""

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

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

(3)nil

会创建一个内存中临时数据库,当FMDatabase连接关闭时,数据库会被销毁
  
【备注】path 可以是相对路径,也可以是绝对路径。

四、数据库操作

1.执行更新操作

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

create、drop、insert、update、delete等

使用executeUpdate:方法执行更新

1)(BOOL)executeUpdate:(NSString*)sql, ...

** 示例 CREATE (建表操作)

NSString *createTableSqlString = @"CREATE TABLE IF NOT EXISTS t_student (id integer PRIMARY KEY AUTOINCREMENT, name text NOT NULL, age integer NOT NULL)";
[db executeUpdate:createTableSqlString];

** 示例INSERT(写入数据)

//不确定的参数用?来占位
NSString *sql = @"insert into t_student (name, age) values (?, ?)";
[db executeUpdate:sql, @"zhangsan", [NSNumber numberWithInt:18]];
 

** 示例DELETE(删除数据)

NSString *sql = @"delete from t_student where id = ?";
[db executeUpdate:sql, [NSNumber numberWithInt:1]];
 

** 示例UPDATE(更改数据)

NSString *sql = @"update t_student set name = "heiheihei"  where id = ?";
[db executeUpdate:sql, [NSNumber numberWithInt:1]];
 

2)(BOOL)executeUpdateWithFormat:(NSString*)format, ...

示例:

//不确定的参数用%@,%d等来占位
NSString *sql = @"insert into t_student (name,age) values (%@,%i)";
[db executeUpdateWithFormat:sql, @"zhangsan", 18];

3)(BOOL)executeUpdate:(NSString*)sql withParameterDictionary:(NSDictionary *)

示例:

NSDictionary *studentDict = [NSDictionary dictionaryWithObjectsAndKeys:@"lisi", @"name", @"18", @"age", nil];
[db executeUpdate:@"insert into t_student (name, age) values (:name, :age)" withParameterDictionary:studentDict];  

...

2、执行查询操作

查询方法

1)(FMResultSet )executeQuery:(NSString)sql, ...

2)(FMResultSet )executeQueryWithFormat:(NSString)format, ...

...

示例:

// 4.查询
NSString *sql = @"select id, name, age FROM t_student";
FMResultSet *rs = [db executeQuery:sql];
while ([rs next]) {
    int id = [rs intForColumnIndex:0];
    NSString *name = [rs stringForColumnIndex:1];
    int age = [rs intForColumnIndex:2];
    NSDictionary *studentDict = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:id], @"id", name, @"name", [NSNumber numberWithInt:age], @"age", nil];
    [studentArray addObject:studentDict];
}

3、多语句和批处理

FMDatabase 可以通过 -executeStatements:withResultBlock: 方法在一个字符串中执行多语句。

NSString *sql = @"CREATE TABLE IF NOT EXISTS bulktest1 (id integer PRIMARY KEY AUTOINCREMENT, x text);"
                "CREATE TABLE IF NOT EXISTS bulktest2 (id integer PRIMARY KEY AUTOINCREMENT, y text);"
                "CREATE table IF NOT EXISTS bulktest3 (id integer primary key autoincrement, z text);"
                "insert into bulktest1 (x) values ('XXX');"
                "insert into bulktest2 (y) values ('YYY');"
                "insert into bulktest3 (z) values ('ZZZ');"
        ;
        result = [db executeStatements:sql];
        
sql = @"select count(*) as count from bulktest1;"
        "select count(*) as count from bulktest2;"
        "select count(*) as count from bulktest3;";
        
        result = [db executeStatements:sql withResultBlock:^int(NSDictionary *resultsDictionary) {
            NSLog(@"dictionary=%@", resultsDictionary);
            return 0;
        }];

五、队列和线程安全

在多线程中同时使用 FMDatabase 单例是极其错误的想法,会导致每个线程创建一个 FMDatabase 对象。不要跨线程使用单例,也不要同时跨多线程,不然会奔溃或者异常。

因此不要实例化一个 FMDatabase 单例来跨线程使用。

相反,使用 FMDatabaseQueue,下面就是它的使用方法:

1、创建队列

FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath];

2.示例:

[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]) {
        ...
    }
}];

3.把操作放在事务中也很简单,示例:

[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
    [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]];

    if (whoopsSomethingWrongHappened) {
        *rollback = YES;
        return;
    }
    // ...
    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:4]];
}];

fmdb使用遇到的问题及解决

fmdb使用中问题调试

[参考文档]

http://blog.devtang.com/2012/04/22/use-fmdb/
http://www.hcios.com/archives/921



作者:DaZenD
链接:https://www.jianshu.com/p/766a694399c0
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

猜你喜欢

转载自blog.csdn.net/a18339063397/article/details/88862674