FMDB将SQLite API进行了“OC”型封装,使用上方便了很多。
提供了对数据库的增删改查基本功能,以及在多线程并发操作线程安全。
我们简单看一下FMDB:
//FMDatabase:代表一个数据库文件
#import "FMDatabase.h"
//FMResultSet:查询的结果集合
#import "FMResultSet.h"
#import "FMDatabaseAdditions.h"
//用于多线程操作数据库
#import "FMDatabaseQueue.h"
//一种适合只读数据库方式
#import "FMDatabasePool.h"
我们来做一个项目熟悉一下FMDB基本使用。
项目需求:学校-教室-老师-学生 3层数据本地化存储。
使用CocoaPods导入FMDB,我们需要导入libsqlite3.0框架。
首先,我们在沙盒当中创建数据库,习惯用一个单例来创建一个数据库读写对象 NFDbManager :
+ (NFDbManager *)sharedManager
{
static NFDbManager *sharedAccountManagerInstance = nil;
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
sharedAccountManagerInstance = [[self alloc] init];
});
return sharedAccountManagerInstance;
}
/**
* 创建DB对象
*/
- (FMDatabase *)loadDbWishDBName:(NSString *)dbName{
//沙盒路径
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory=[paths objectAtIndex:0];
//dbName:数据库名称
NSString *writableDBPath=[documentsDirectory stringByAppendingPathComponent:dbName];
NSLog(@"数据库位置-------%@",writableDBPath);
//创建数据库
FMDatabase *db = [FMDatabase databaseWithPath:writableDBPath] ;
if (![db open]) {
NSLog(@"数据库未能创建/打开");
return nil;
}
return db;
}
我们接着创建模型类和控制器类:
分别为教室类NFClassModel:
@property (nonatomic, copy) NSString *schoolName; //学校名称
@property (nonatomic, copy) NSString *className; //教室名称
NFTeacherModel:
@property (nonatomic, copy) NSString * className;
@property (nonatomic, copy) NSString * teacherName;
@property (nonatomic, copy) NSString * teacherGender;
@property (nonatomic, copy) NSString * teacherHeader;
@property (nonatomic, copy) NSString * teacherAge;
@property (nonatomic, strong) NSArray * studentArray;
学生类NFStudentModel:
@property (nonatomic, copy) NSString * studentName;
@property (nonatomic, copy) NSString * studentAge;
@property (nonatomic, copy) NSString * studentGender;
@property (nonatomic, copy) NSString * studentHeader;
@property (nonatomic, copy) NSString * teacherName;
接着我们就根据建立好的模型类来去数据库当中建立我们需要对应的表,我是建立了三张表,一一对应教室,老师和学生:
- (void)initDB:(FMDatabase *)db{
/**
* 开启数据库
*/
if ([db open])
{
[db setShouldCacheStatements:YES];
}
if(![db tableExists:CLASS_TABLE])//创建教室表
{
/**
* 字段:
id 为主排序
* classID :教室ID
* className :教室名称
* classImg :教室图片
* classTotal :数组
*/
BOOL result = [db executeUpdate:@"create table class_table(_id integer PRIMARY KEY AUTOINCREMENT,"
"schoolName char(100),className char(100) ,classTotal char(10))"];
if (result) {
NSLog(@"教室表创建成功");
}
}
if(![db tableExists:TEACHER_TABLE])//创建老师表
{
/**
* 字段:
id 为主排序
* teacherID :ID
* teacherName :名字
* teacherImg :图片
* teacherTotal :数组
* teacherAge :年龄
* teacherGender :性别
*/
BOOL result = [db executeUpdate:@"create table teacher_table(_id integer PRIMARY KEY AUTOINCREMENT,"
"className char(100), teacherName char(100), teacherAge char(100),teacherGender char(100))"];
if (result) {
NSLog(@"老师表创建成功");
}
}
if(![db tableExists:STUDENT_TABLE])//创建学生表
{
/**
* 字段:
id 为主排序
* studentID :学生ID
* studentName :学生名称
* studentImg :学生图片
* studentAge :学生年龄
* studentGender :学生性别
*/
BOOL result = [db executeUpdate:@"create table student_table(_id integer PRIMARY KEY AUTOINCREMENT,"
"teacherName char(100), studentName char(100) ,studentAge char (100), studentGender char(10))"];
if (result) {
NSLog(@"学生表创建成功");
}
}
}
我们的表建好了,那么我们就在NFDbManager当中公开几个方法,让我们来操作对应的表:
/**
* 插入教室
*/
- (BOOL)insertClass:(NFClassModel *)classModel;
/**
* 插入老师
*/
- (BOOL)insertTeacher:(NFTeacherModel *)teacher;
/**
* 插入学生
*/
- (BOOL)insertStudent:(NFStudentModel *)student;
/**
* 查询学校下面所有的教室
*/
- (NSArray *)querySubjectWithSchoolName:(NSString *)schoolName;
/**
* 查询教室下面的所有老师
*/
- (NSArray *)querySubjectWithClassName:(NSString *)className;
/**
* 查询老师下面的所有学生
*/
- (NSArray *)querySubjectWithTeacherName:(NSString *)teacherName;
FMDB提供了增删改查语句:
有这么一点:一切不是SELECT命令的命令都视为更新,这包括 CREAT,UPDATE,INSERT,ALTER,BEGIN,COMMIT,DETACH,DELETE,DROP,END,EXPLAIN,VACUUM,REPLACE等。
我们就拿插入一个学生信息为例子吧:
/**
* 插入学生
*/
- (BOOL)insertStudent:(NFStudentModel *)student{
//判断是否打开
if ([nfDB open]) {
if (![self existsWithObjcet:student WishType:3])
{
NSLog(@"插入成功 " );
//?:占位符 执行语句不区分大小写
return [nfDB executeUpdate:[self setTable2:@"insert into %@ (teacherName,studentName ,studentAge,studentGender) values(?,?,?,?)"],
student.teacherName,
student.studentName,
student.studentAge,
student.studentGender
];
}
//插入之后关闭
[nfDB close];
}
return NO;
}
同样的方法,我们插入更多数据。
当我们需要查询的时候,FMResultSet为我们提供了不同的数据格式读取:
intForColumn:
longForColumn:
longLongIntForColumn:
boolForColumn:
doubleForColumn:
stringForColumn:
dateForColumn:
dataForColumn:
dataNoCopyForColumn:
UTF8StringForColumnIndex:
objectForColumn:
我们再一次查询当前老师名称下的所有学生数组:
/**
* 查询老师下面的所有学生
*/
- (NSArray *)querySubjectWithTeacherName:(NSString *)teacherName{
NSMutableArray *array =[[NSMutableArray alloc] init];
FMResultSet *rs;
//查询结果集合
rs = [nfDB executeQuery:[self setTable2:@"select * from %@ where teacherName = ? "],teacherName];
//遍历集合
while ([rs next]) {
NFStudentModel *studentModel = [[NFStudentModel alloc]init];
studentModel.studentName = [rs stringForColumn:@"studentName"];
studentModel.studentAge = [rs stringForColumn:@"studentAge"];
studentModel.studentGender = [rs stringForColumn:@"studentGender"];
[array addObject:studentModel];
}
return array;
}
FMDM还有很多功能可以供我们使用,以后有机会会继续写一些其他功能,供童鞋们学习。
效果: