iOS FMDB 数据库

作者: 莦婼姑娘 | 来源:发表于2017-07-06 14:04 被阅读1890次

    FMDB

    1、简述:

    * FMDB是iOS平台的SQLite数据库框架,是对libsqlite3框架的封装

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

    2、FMDB的优点:

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

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

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

    3、FMDB的github地址 传送门

    4、FMDB的三个核心类

    FMDatabase —— 一个FMDatabase对象就代表一个单独的SQLite数据库 用来执行SQL语句

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

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

    5、基本使用

    1、下载FMDB文件的GitHub,并将FMDB文件夹添加到项目中(也可使用CocoaPods导入)—— pod'FMDB'

    2、导入libsqlite3.0框架,导入头文件FMDatabase.h

    3、代码实现,与SQLite使用步骤相似,创建数据库路径,获得数据库路径,打开数据库,然后对数据库进行增、删、改、查操作,最后关闭数据库。

    导入libsqlite3.0库

    实例Demo

    本例是一个学生的数据库表格student,每个学生都自己所选的课程class,具体信息如下图Model:

    Model

    1、具体操作界面

    具体操作界面

    2、上代码

    2.1、创建 DataForFMDB.h 类,导入头文件

    #import"DataForFMDB.h"

    #import <FMDB.h>

    2.2、创建FMDB单例,以便全局共享

    @interface DataForFMDB (){

    FMDatabase *fmdb;

    }

    @end

    @implementation DataForFMDB

    static DataForFMDB *theData = nil;

    +(instancetype)sharedDataBase{

    @synchronized(self) {

    if(!theData) {

    theData = [[DataForFMDB alloc] init];

    [theData initDataBase];

    }

    }

    return theData;

    }

    -(void)initDataBase{

    //获得Documents目录路径

    NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];

    //文件路径

    NSString *filePath = [documentPath stringByAppendingPathComponent:@"student.db"];

    //实例化FMDataBase对象

    NSLog(@"---path:%@",filePath);

    fmdb = [FMDatabase databaseWithPath:filePath];

    if([fmdb open]) {

    //初始化数据表

    [self addStudentTable];

    [self addClassTable];

    [fmdb close];

    }else{

    NSLog(@"数据库打开失败---%@", fmdb.lastErrorMessage);

    }

    }

    -(void)addStudentTable{

    NSString*studentSQL =@"create table if not exists student (id integerPrimary Key Autoincrement, sId integer, sName text, sAge integer)";

    BOOL studentSuccess = [fmdb executeUpdate:studentSQL];

    if(!studentSuccess) {

    NSLog(@"studentTable创建失败---%@",fmdb.lastErrorMessage);

    }

    }

    -(void)addClassTable{

    NSString*classSQL =@"create table if not exists class (id integerPrimary Key Autoincrement,scId integer, cName text)";

    BOOL classSuccess = [fmdbexecuteUpdate:classSQL];

    if(!classSuccess) {

    NSLog(@"classTable创建失败---%@",fmdb.lastErrorMessage);

    }

    }

    2.3、获取student表全部内容

    -(NSMutableArray*)getAllStudent{

    [fmdb open];

    NSMutableArray *array = [NSMutableArray new];

    FMResultSet *result = [fmdb executeQuery:@"select * from student"];

    while([result next]) {

    StudentFMDBModel *student = [[StudentFMDBModel alloc] init];

    student.sId = [[result stringForColumn:@"sId"] integerValue];

    student.sName= [result stringForColumn:@"sName"];

    student.sAge= [[result stringForColumn:@"sAge"] integerValue];

    [array addObject:student];

    }

    [fmdb close];

    return array;

    }

    //调用

    self.dataArray= [[DataForFMDB sharedDataBase] getAllStudent];

    2.4、student表添加内容

    -(void)addStudent:(StudentFMDBModel*)student{

    [fmdb open];

    NSString *SQL =@"insert into student(sId,sName,sAge) values(?,?,?)";

    BOOL isAddSuccess = [fmdb executeUpdate:SQL,@(student.sId),student.sName,@(student.sAge)];

    if(!isAddSuccess) {

    NSLog(@"studentTable插入信息失败--%@",fmdb.lastErrorMessage);

    }

    [fmdb close];

    }

    //调用

    [[DataForFMDB sharedDataBase] addStudent:student];

    2.5、student表删除内容

    -(void)deleteStudent:(StudentFMDBModel*)student{

    [fmdb open];

    NSString *SQL =@"delete from student where sId = ?";

    BOOL isDeleteSuccess = [fmdb executeUpdate:SQL,@(student.sId)];

    if(!isDeleteSuccess) {

    NSLog(@"studentTable删除某一信息失败--%@",fmdb.lastErrorMessage);

    }

    [fmdb close];

    }

    //调用

    [[DataForFMDB sharedDataBase] deleteStudent:self.dataArray[indexPath.row]];

    2.6、student表修改内容

    -(void)updateStudent:(StudentFMDBModel*)student{

    [fmdb open];

    NSString *SQL1 =@"update student set sName = ? where sId = ?";

    NSString *SQL2 =@"update student set sAge = ? where sId = ?";

    BOOL isSuccess1 = [fmdbexecuteUpdate: SQL1, student.sName,@(student.sId)];

    BOOL isSuccess2 = [fmdbexecuteUpdate: SQL2,@(student.sAge),@(student.sId)];

    if(!isSuccess1) {

    NSLog(@"student.sName修改失败--%@",fmdb.lastErrorMessage);

    }

    if(!isSuccess2) {

    NSLog(@"student.sAge修改失败--%@",fmdb.lastErrorMessage);

    }

    [fmdb close];

    }

    //调用

    [[DataForFMDB sharedDataBase] updateStudent:student];

    2.7、删除student表

    -(void)deleteAllStudent{

    [fmdb open];

    NSString *SQL =@"delete from student";

    BOOL isSuccess = [fmdb executeUpdate:SQL];

    if(!isSuccess) {

    NSLog(@"studentTable全部删除失败--%@",fmdb.lastErrorMessage);

    }

    //student表删除以后,对应的class也要删除

    [self deleteAllClass];

    [fmdb close];

    }

    //调用

    [[DataForFMDB sharedDataBase] deleteAllStudent];

    2.8、获取某一student class表的全部课程

    -(NSMutableArray*)getAllClassFromStudent:(StudentFMDBModel*)student{

    [fmdb open];

    NSMutableArray *array = [NSMutableArray new];

    FMResultSet *result = [fmdb executeQuery:[NSString stringWithFormat:@"select * from class where scId = %ld", student.sId]];

    while([result next]) {

    StudentClassModel*class = [[StudentClassModel alloc] init];

    class.cName= [result stringForColumn:@"cName"];

    [array addObject:class];

    }

    [fmdb close];

    return array;

    }

    //调用

    self.dataArray= [[DataForFMDB sharedDataBase] getAllClassFromStudent: student];

    2.9、给class表添加课程

    -(void)addClass:(StudentClassModel*)clas toStudent:(StudentFMDBModel*)student{

    [fmdb open];

    //scId integer, cName text

    NSString*SQL = [NSStringstringWithFormat:@"insert into class (scId, cName) values (%ld,?)", student.sId];

    BOOL isSuccess = [fmdb executeUpdate:SQL, clas.cName];

    if(!isSuccess) {

    NSLog(@"classTable插入信息失败--%@",fmdb.lastErrorMessage);

    }

    [fmdb close];

    }

    //调用

    [[DataForFMDB sharedDataBase] addClass: class toStudent: student];

    2.10、给class表删除课程

    -(void)deleteClass:(StudentClassModel*)clas toStudent:(StudentFMDBModel*)student{

    [fmdb open];

    NSString *SQL = [NSString stringWithFormat:@"delete from class where scId = %ld and cName = ?", student.sId];

    BOOL isSuccess = [fmdb executeUpdate:SQL,clas.cName];

    if(!isSuccess) {

    NSLog(@"classTable删除某一信息失败--%@",fmdb.lastErrorMessage);

    }

    [fmdb close];

    }

    //调用

    [[DataForFMDB sharedDataBase] deleteClass: self.dataArray[indexPath.row] toStudent: student];

    2.11、删除student下某一的全部class

    -(void)deleteAllCarsFromStudent:(StudentFMDBModel*)student{

    [fmdb open];

    NSString *SQL = [NSString stringWithFormat:@"delete from class where scId = %ld", student.sId];

    BOOL isSuccess = [fmdb executeUpdate:SQL];

    if(!isSuccess) {

    NSLog(@"student下某一的全部class删除失败--%@",fmdb.lastErrorMessage);

    }

    [fmdb close];

    }

    //调用

    [[DataForFMDB sharedDataBase] deleteAllClassFromStudent: student];

    2.12、//删除class表

    -(void)deleteAllClass{

    NSString *SQL =@"delete from class";

    BOOL isSuccess = [fmdb executeUpdate:SQL];

    if(!isSuccess) {

    NSLog(@"classt全部删除失败--%@",fmdb.lastErrorMessage);

    }

    }

    2.13、由名字查找学生student信息

    查找操作界面

    -(NSMutableArray*)seachAllInfoWith:(NSString*)str{

    [fmdb open];

    NSMutableArray*array = [NSMutableArray new];

    //通过名字查询学生信息

    NSString *SQL = [NSString stringWithFormat:@"select * from student where sName = '%@' ", str]; // '%@' 可以查询中文

    FMResultSet *result = [fmdb executeQuery:SQL];

    while([result next]) {

    StudentFMDBModel *student = [[StudentFMDBModel alloc] init];

    student.sId= [result intForColumn:@"sId"];

    student.sName= [result stringForColumn:@"sName"];

    [array addObject:student];

    }

    [fmdb close];

    return array;

    }

    //调用

    self.dataArray= [[DataForFMDB sharedDataBase] seachAllInfoWith: textField.text];

    2.14、全部信息

    全部信息界面

    数据代码:

    @property(nonatomic,strong)NSMutableArray*studentArray;//student数据源数组

    @property(nonatomic,strong)NSMutableArray*allInfoArray;//student对应class数据源数组

    self.studentArray = [[DataForFMDB sharedDataBase] getAllStudent];

    for(inti =0; i<self.studentArray.count; i++){

    StudentFMDBModel *student =  self.studentArray[i];

    NSMutableArray *array = [[DataForFMDB sharedDataBase] getAllClassFromStudent:student];

    [self.allInfoArray addObject:array];

    }

    知识点总结

    1、数据库插入命令SQL  insert into

    //1.executeUpdate:不确定的参数用?来占位(后面参数必须是oc对象,“;”代表语句结束)

    [fmdb executeUpdate:@“insert into student(sId,sName,sAge) values(?,?,?);” ,@(student.sId), student.sName, @(student.sAge)];  //int / integer 类型的要加 “@(xxx)”转成NSNumber类型的

    //2.executeUpdateWithForamat:不确定的参数用%@,%d等来占位 (参数为原始数据类型,执行语句不区分大小写

     [fmdb executeUpdateWithForamat:@“insert intot student (sId,sName,sAge)values(%ld,%@,%ld);”,student.sId, student.sName, student.sAge];    

    //3.参数是数组的使用方式 

    [fmdb executeUpdate:@“insert into student (sId,sName,sAge) values(?,?,?);” withArgumentsInArray:@[@(student.sId), student.sName, @(student.sAge)]];

    2、数据库删除命令SQL  delete

    //1.不确定的参数用?来占位 (后面参数必须是oc对象,需要将int包装成OC对象)

    [fmdb executeUpdate:@“delete from student where sId = ?;”,@(student.sId)];

    //2.不确定的参数用%@,%d等来占位

    [fmdb executeUpdateWithFormat:@“delete from student where name = %@;”,student.sName];

    3、数据库修改命令SQL  update

    //修改学生的名字 

    [fmdb executeUpdate:@“update student set sName = ? where sId = ?”,student.sName,@(student.sId)];

    4、数据库查询命令SQL  select ... from

    select命令就是查询,执行查询的方法是以-excuteQuery开头的。执行查询时,如果成功返回FMResultSet对象,错误返回nil。与执行更新相当,支持使用NSError参数。同时,你也可以使用-lastErrorCode和-lastErrorMessage获知错误信息。

    FMResultSet获取不同数据格式的方法:

    intForColumn:

    longForColumn:

    longLongIntForColumn:

    boolForColumn:

    doubleForColumn:

    stringForColumn:

    dataForColumn:

    dataNoCopyForColumn:

    UTF8StringForColumnIndex:

    objectForColumn:

    5、数据库销毁命令SQL drop ...

    //如果表格存在 则销毁

     [fmdb executeUpadate:@“drop table if existst student;”];

    6、使用FMDatabaseQueue类实现多线程操作

    在多个线程中同时使用一个FMDatabase实例是不明智的。现在你可以为每 个线程创建一个FMDatabase对象,不要让多个线程分享同一个实例,他无法在多个线程中同事使用。否则程序会时不时崩溃或者报告异常。所以,不要初始化FMDatabase对象,然后在多个线程中使用。这时候,我们就需要使 用FMDatabaseQueue来创建队列执行事务。

    //1.创建队列

    FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath]; 

    __block BOOL whoopsSomethingWrongHappened =true;

    //2.把任务包装到事务里

    [queue inTransaction:^(FMDatabase *db, BOOL *rollback)    {  whoopsSomethingWrongHappened &=  [db executeUpdate:@“insert into myTable values (?)”,    [NSNumber numberWith:1]];

    whoopsSomethingWrongHappened &= [db executeUpdata:@“insert into myTable values (?)”, [NSNumber numberWithInt:2]];

    whoopsSomethingWrongHappened &= [db executeUpdata:@“insert into myTable values(?)”[NSNumber  numberWithInt:3]];

    //如果有错误 返回

    if(!whoopsSomethingWrongHappened)  {   

     *rollback = YES;

    return;

     }

    }];

    ——————————————————

    有什么问题欢迎大家提问哟,O(∩_∩)O~~

    相关文章

      网友评论

      本文标题:iOS FMDB 数据库

      本文链接:https://www.haomeiwen.com/subject/psochxtx.html