使用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];