FMDB使用

使用FMDB创建一个表。首先要知道表中的元素有哪些,表的主键是哪个,数据在存储后,用于查询的条件是一个还是多个,考虑清楚表的结构,对后面完成功能更方便。

首先使用cocoa pods导入FMDB

1:因为我要存储的数据来自后台返回的json串,我使用MVC模式来显示数据。所以表中的元素都是Model(模型)的属性。然后再考虑主键,如果只是用一个tableview来显示数据,那这个主键可以用一个字符串代替,以后查询的时候,通过这个字符串,就能将表里的数据拿到,从而显示出来。下面是我用到的数据模型的model(模型)。


#import <Foundation/Foundation.h>

@interface LMTopicsModel : NSObject
/* 名称 */
@property(nonatomic,copy)NSString *name;
/* 头像   */
@property(nonatomic,copy)NSString *profile_image;
/* 文本内容 */
@property(nonatomic,copy)NSString *text;
/* 发帖子时间 */
@property(nonatomic,copy)NSString *create_time;
/* 点赞数 */
@property(nonatomic,assign)NSInteger ding;
/* 踩数 */
@property(nonatomic,assign)NSInteger cai;
/* 转发数 */
@property(nonatomic,assign)NSInteger repost;
/* 评论数 */
@property(nonatomic,assign)NSInteger comment;
/* 新浪加v */
@property(nonatomic,assign,getter=isSina_v)BOOL sina_v;
/* 小图 */
@property(nonatomic,copy)NSString *small_image;
/* 大图 */
@property(nonatomic,copy)NSString *large_image;
/* 中图 */
@property(nonatomic,copy)NSString *middle_image;
/* 宽度 */
@property(nonatomic,copy)NSString *width;
/* 高度 */
@property(nonatomic,copy)NSString *height;
/* ID */
@property(nonatomic,copy)NSString *ID;
/* 加载更多的参数 */
@property(nonatomic,copy)NSString *maxtime;
@end


#import "LMTopicsModel.h"
#import <MJExtension.h>
@implementation LMTopicsModel
+(NSDictionary *)mj_replacedKeyFromPropertyName
{
    return @{
             @"small_image":@"image0",
             @"middle_image":@"image2",
             @"large_image":@"image1",
             @"ID":@"id"
             };
}
@end

2:因为我的数据在首页就要显示出来,我在AppDelegate.m里面创建了这个数据库。

#import "AppDelegate.h"
#import "MainViewController.h"

#import "ProjectTool.h"
#import <FMDB.h>

@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //创建主窗口
    self.window = [[UIWindow alloc] init];
    self.window.frame = [UIScreen mainScreen].bounds;
    self.window.backgroundColor = [UIColor whiteColor];
    //设置根控制器
    UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:[[MainViewController alloc]init]];
    self.window.rootViewController = nav;
    //显示窗口
    [self.window makeKeyAndVisible];
    //创建数据库
    [self createFMDB];
    return YES;
}
#pragma mark - 创建数据库
-(void)createFMDB
{
    NSString *dbFilePath = [ProjectTool getFMDBPath];
    /*
     为什么要往应用程序里添加数据库文件这个过程:
     因为下面要进行判断,会根据这个路径去查找应用程序的路径中到底有没有这个文件,
     如果有,则不用在此拷贝了,
     如果没有,则重新拷贝一次,
     数据库文件必须添加进取,否则无法进行数据库的操作,而且必须添加一次,
     
     那么为什么必须要添加一次呢?
     因为我们在程序中实现对数据库的修改,然而却又把数据库添加了一次,
     那么新添加的数据库就会把旧的数据库覆盖掉,那么程序中对数据库的修改也不能实现,
     所以数据库只能添加一次且是在程序运行初添加
     */
    
    //根据上面拼接好的路径 dbFilePath ,利用NSFileManager 类的对象的fileExistsAtPath方法来检测是否存在,返回一个BOOL值
    //1. 创建NSFileManager对象  NSFileManager包含了文件属性的方法
    NSFileManager *fm = [NSFileManager defaultManager];
    
    //2. 通过 NSFileManager 对象 fm 来判断文件是否存在,存在 返回YES  不存在返回NO
    BOOL isExist = [fm fileExistsAtPath:dbFilePath];
    //- (BOOL)fileExistsAtPath:(NSString *)path;
    
    //如果不存在 isExist = NO,拷贝工程里的数据库到Documents下
    if (!isExist)
    {
        //创建FMDB数据库
        FMDatabase *db = [FMDatabase databaseWithPath:dbFilePath];
        if ([db open]) {
            NSString *sql = [NSString stringWithFormat:@"CREATE TABLE %@(prikey TEXT,name TEXT,profile_image TEXT,text TEXT,create_time TEXT,ding TEXT,cai TEXT,repost TEXT,comment TEXT,sina_v TEXT,small_image TEXT,width TEXT,height TEXT,ID TEXT,maxtime TEXT)",dbTableName];
            BOOL res = [db executeUpdate:sql];
            if (!res) {
                NSLog(@"创建数据库失败");
            }else
            {
                NSLog(@"创建数据库成功!");
            }
            [db close];
        }else
        {
            NSLog(@"数据库打开失败");
        }
    }
}

@end

补: ProjectTool获取数据库路径

#import <Foundation/Foundation.h>

@interface ProjectTool : NSObject
/*获取FMDB数据库的路径*/
+(NSString *)getFMDBPath;
@end

#import "ProjectTool.h"
#define DATABASE_FILE_NAME @"project.sqlite"
@implementation ProjectTool
+(NSString *)getFMDBPath
{
    /*===---===
     在这个部分中我么进行一下操作:(要把数据库文件存放到储存的位置中)
     1.获取应用程序的路径,在手机中就是 应用程序存储数据的地方
     2.把数据库文件的名称拼接到上面得到的路径上
     3.根据拼接好的路径去寻找,并判断这个文件是否存在
     ===---===*/
    //获取应用程序的路径
    NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(
                                                               NSDocumentDirectory,
                                                               NSUserDomainMask,
                                                               YES);
    NSString *documentFolderPath = [searchPaths objectAtIndex:0];
    //往应用程序路径中添加数据库文件名称,把它们拼接起来, 这里用到了宏定义(目的是不易出错)
    NSString *dbFilePath = [documentFolderPath stringByAppendingPathComponent:DATABASE_FILE_NAME];
    
    return dbFilePath;
}
@end

3:为了方便对数据库进行增删改查,我创建一个工具类,在这后面我再进行操作的时候,只需要通过工具类来操作。

DataBaseTool.h

#import <Foundation/Foundation.h>

@interface DataBaseTool : NSObject
//创建单利对象,防止创建多个数据库
+(DataBaseTool *)shareDataBaseTool;
//插入数据
-(void)insertModelArray:(NSMutableArray *)modelArray  byPrKey:(NSString *)PrKey;
//查询数据
-(NSMutableArray *)queryModelArrayByPrKey:(NSString *)PrKey;
//删除数据
-(void)deleteModelArrayByPrKey:(NSString *)PrKey;
//查询所有数据
-(void)queryAll;
//删除所有数据
-(void)clearAll;
@end

DataBaseTool.m

#import "DataBaseTool.h"
#import "ProjectTool.h"
#import "LMTopicsModel.h"
#import <FMDB.h>
static DataBaseTool *shareDataBase = nil;
@implementation DataBaseTool
//创建单利对象,防止创建多个数据库
+(DataBaseTool *)shareDataBaseTool
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        shareDataBase = [[DataBaseTool alloc]init];
    });
    return shareDataBase;
}
//插入数据
-(void)insertModelArray:(NSMutableArray *)modelArray byPrKey:(NSString *)PrKey
{
    //存储信息
    FMDatabase *db = [FMDatabase databaseWithPath:[ProjectTool getFMDBPath]];
    if ([db open]) {
        for (LMTopicsModel *model in modelArray) {
            //创建一个社区table
            NSString *sql = [NSString stringWithFormat:
                             @"insert into %@ (prikey,name ,profile_image ,text ,create_time  ,ding ,cai  ,repost ,comment ,sina_v ,small_image ,width ,height ,ID,maxtime) values ('%@','%@','%@','%@','%@','%@','%@',%@,'%@','%@','%@','%@','%@','%@','%@')",dbTableName,PrKey,model.name,model.profile_image,model.text,model.create_time,@(model.ding),@(model.cai),@(model.repost),@(model.comment),@(model.sina_v),model.small_image,model.width,model.height,model.ID,model.maxtime];
            BOOL res = [db executeUpdate:sql];
            if (!res) {
                NSLog(@"更新失败!");
            }else{
                NSLog(@"成功!");
            }
        }
        [db close];
        
    }
}
//查询数据query
-(NSMutableArray *)queryModelArrayByPrKey:(NSString *)PrKey
{
    FMDatabase *db = [FMDatabase databaseWithPath:[ProjectTool getFMDBPath]];
    NSMutableArray *dbArray = [NSMutableArray array];
    if ([db open]) {
        NSString *sql = [NSString stringWithFormat:@"select * from %@ where prikey = '%@'",dbTableName,PrKey];
        //执行sql查询语句
        FMResultSet *rs = [db executeQuery:sql];
        while ([rs next]) {
            LMTopicsModel *model = [[LMTopicsModel alloc]init];
            model.name = [rs stringForColumn:@"name"];
            model.profile_image = [rs stringForColumn:@"profile_image"];
            model.text = [rs stringForColumn:@"text"];
            model.create_time = [rs stringForColumn:@"create_time"];
            model.ding = [[rs stringForColumn:@"ding"] integerValue];
            model.cai = [[rs stringForColumn:@"cai"] integerValue];
            model.repost = [[rs stringForColumn:@"repost"] integerValue];
            model.comment = [[rs stringForColumn:@"comment"] integerValue];
            model.sina_v = [[rs stringForColumn:@"sina_v"] integerValue];
            model.small_image = [rs stringForColumn:@"small_image"];
            model.width = [rs stringForColumn:@"width"];
            model.height = [rs stringForColumn:@"height"];
            model.ID = [rs stringForColumn:@"ID"];
            model.maxtime = [rs stringForColumn:@"maxtime"];
            [dbArray addObject:model];
        }
        [db close];
    }
    return dbArray;
}
//删除数据
-(void)deleteModelArrayByPrKey:(NSString *)PrKey
{
    FMDatabase *db = [FMDatabase databaseWithPath:[ProjectTool getFMDBPath]];
    if ([db open]) {
        NSString *sql = [NSString stringWithFormat:@"delete from %@ where prikey = '%@'",dbTableName,PrKey];
        BOOL res = [db executeUpdate:sql];
        if (!res) {
            NSLog(@"删除失败");
        }else
        {
            NSLog(@"删除成功!");
        }
        [db close];
    }
}
//查询所有数据
-(void)queryAll
{
    FMDatabase *db = [FMDatabase databaseWithPath:[ProjectTool getFMDBPath]];
    if ([db open]) {
        int i = 0;
        NSString * sql = [NSString stringWithFormat:@"select * from %@",dbTableName];
        FMResultSet * rs = [db executeQuery:sql];
        while ([rs next]) {
            NSString *ID = [rs stringForColumn:@"ID"];
            NSString *text = [rs stringForColumn:@"text"];
            NSLog(@"查询的数据 %d,%@,%@",i++,ID,text);
        }
        [db close];
    }
}
//删除所有数据
-(void)clearAll
{
    FMDatabase *db = [FMDatabase databaseWithPath:[ProjectTool getFMDBPath]];
    if ([db open]) {
        NSString * sql =[NSString stringWithFormat:@"delete from %@",dbTableName];
        BOOL res = [db executeUpdate:sql];
        if (!res) {
            NSLog(@"清除失败!");
        }else
        {
            NSLog(@"清除完成!");
        }
    }
}
@end

4.使用情境:

无网状态下:(从数据库取出,然后赋值给数据,刷新tableview

//主键
    NSString *private_key = @"homeInfo";

//从数据库取出
        NSMutableArray *dbModelArray = [[DataBaseTool shareDataBaseTool]queryModelArrayByPrKey:private_key];
        [self.lmTableView reloadData];

请求到最新的数据:(先清除原来数据库所有的数据,再将新的数据存储)

//存储数据
            [[DataBaseTool shareDataBaseTool]deleteModelArrayByPrKey:private_key];
            [[DataBaseTool shareDataBaseTool]insertModelArray:[NSMutableArray arrayWithArray:tempArray] byPrKey:private_key];

请求到更多的数据:(在原来数据的基础上插入更多数据,不用删除原来的数据)

//存储数据
                [[DataBaseTool shareDataBaseTool]insertModelArray:[NSMutableArray arrayWithArray:tempArray] byPrKey:private_key];



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值