您的位置:首页 > 博客中心 > 数据库 >

数据持久化-CoreData、SQLite、FMDB

时间:2022-03-14 03:02

1.CoreData


1.1 CoreData概述


1)Core data 是数据持久存储的最佳方式

2)Core Data 基于model-view-controller(mvc)模式下,为创建分解的cocoa应用程序提供了一个灵活和强大的数据模型框架。


3)Core Data可以是你以图形界面的方式快速的定义app的数据模型,同时在你的代码中容易获取到它。 Core Data提供了基础结构去处理常用的功能,例如:保存,恢复,撤销和重做,允许你在app中继续创建新的任务。在使用 Core Data的时候,你不用安装额外的数据库系统,因为 Core Data使用内置的SQLite数据库。(里面自动生成三个字段)


4)Core Data提供了一个通用的数据管理解决方案来处理那些所有需要数据模型的app,app使用 Core Data来管理数据对象时很多的益处


5)苹果的图形用户界面编译器-interface builder(IB),提供了对core data controller对象的预构建,从而来减少app的用户界面和它的数据模型之间的粘滞代码。在使用core data的时候你不需要考虑sql的语法问题,也不需要管理相关的逻辑树去追踪用户的行为,更不用建立新的永久机制。当你写你app的用户界面到它的core data模型的时候,它已经为你把所有的东西都做好了。


6)core data将你app的模型层放入到一组定义在内存中的数据对象。core data会追踪这些对象的改变,同时可以根据需要做相反的改变,例如用户执行撤销命令。当core data在对你app数据的改变进行保存的时候,core data会把这些数据归档,并永久性保存。它保存的数据在一些常规的文件,你可以在Finder中可以进行管理,用spotlight进行搜索,备份到cd,和email给朋友或者家人。


7)在使用core data框架的时候,你可以创建一个管理对象的模型,该模型提供了对模型对象的抽象定义,这也就是我们所知道的entities,它可以在我们的程序中使用。


8)core data是一个实体-关系模型,该模型是使用Xcode的数据模型设计工具来定义的,对数据实体以及他们的关系提供了丰富的环境。

1.2 CoreData的构成及特点


1.2.1 数据最终的存储类型


SQLite数据库,XML,二进制,内存里,或自定义数据类型(在Mac OS X 10.5Leopard及以后的版本中,开发者也可以通过继承NSPersistentStore类以创建自定义的存储格式)


1.2.2 好处


能够合理管理内存,避免使用sql的麻烦,高效


1.2.3 构成

1)NSManagedObjectContext(被管理的数据上下文)

操作实际内容(操作持久层)

作用:插入数据,查询数据,删除数据


2)NSManagedObjectModel(被管理的数据模型)

数据库所有表格或数据结构,包含各实体的定义信息

作用:添加实体的属性,建立属性之间的关系

操作方法:视图编辑器,或代码


3)NSPersistentStoreCoordinator(持久化存储助理)

相当于数据库的连接器

作用:设置数据存储的名字,位置,存储方式,和存储时机


4)NSManagedObject(被管理的数据记录)

相当于数据库中的表格记录


5)NSFetchRequest(获取数据的请求)

相当于查询语句


6)NSEntityDescription(实体结构)

相当于表格结构


7)后缀为.xcdatamodeld的包

里面是.xcdatamodel文件,用数据模型编辑器编辑

编译后为.momd或.mom文件


1.2.4 依赖关系


gxlsystem.com,布布扣



FMDB同时兼容ARC和非ARC工程,会自动根据工程配置来调整相关的内存管理代码。

FMDB常用类:

FMDatabase : 一个单一的SQLite数据库,用于执行SQL语句。
FMResultSet :执行查询一个FMDatabase结果集,这个和android的Cursor类似。
FMDatabaseQueue :在多个线程来执行查询和更新时会使用这个类。


3.1 数据基本操作

1) 创建数据库:


db [FMDatabase databaseWithPath:database_path];  



         1、当数据库文件不存在时,FMDB会自己创建一个。

         2、 如果你传入的参数是空串:@"" ,则FMDB会在临时文件目录下创建这个数据库,数据库断开连接时,数据库文件被删除。

         3、如果你传入的参数是 NULL,则它会建立一个在内存中的数据库,数据库断开连接时,数据库文件被删除。


2) 打开数据库:



[db open]  


返回BOOL型。


3) 关闭数据库:



[db close]  




3.2 数据库增删改等操作:


除了查询操作,FMDB数据库操作都执行executeUpdate方法,这个方法返回BOOL型。


看一下例子:


1)创建表:



if ([db open])  

        NSString *sqlCreateTable  [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS ‘%@‘ (‘%@‘ INTEGER PRIMARY KEY AUTOINCREMENT, ‘%@‘ TEXT, ‘%@‘ INTEGER, ‘%@‘ TEXT)",TABLENAME,ID,NAME,AGE,ADDRESS];

  

        BOOL res [db executeUpdate:sqlCreateTable];  


        if (!res)  


            NSLog(@"error when creating db table");

  

        else  


            NSLog(@"success to creating db table");  

         


        [db close];  

 





2)添加数据:



if ([db open])  

       NSString *insertSql1= [NSString stringWithFormat:  

                              @"INSERT INTO ‘%@‘ (‘%@‘, ‘%@‘, ‘%@‘) VALUES (‘%@‘, ‘%@‘, ‘%@‘)",  TABLENAME, NAME, AGE, ADDRESS, @"张三", @"13", @"济南"];  


       BOOL res [db executeUpdate:insertSql1];  

       NSString *insertSql2 [NSString stringWithFormat:  

                               @"INSERT INTO ‘%@‘ (‘%@‘, ‘%@‘, ‘%@‘) VALUES (‘%@‘, ‘%@‘, ‘%@‘)",TABLENAME, NAME, AGE, ADDRESS, @"李四", @"12", @"济南"];  


       BOOL res2 [db executeUpdate:insertSql2];  

         

       if (!res)  


           NSLog(@"error when insert db table"); 

 

       else  


           NSLog(@"success to insert db table");  

        


       [db close];  

  

 


3)修改数据:




if ([db open])  

        NSString *updateSql [NSString stringWithFormat:  

                               @"UPDATE ‘%@‘ SET ‘%@‘ ‘%@‘ WHERE ‘%@‘ ‘%@‘",TABLENAME,   AGE,  @"15" ,AGE,  @"13"]; 


        BOOL res [db executeUpdate:updateSql]; 

 

        if (!res)  

            NSLog(@"error when update db table");  

        else  

            NSLog(@"success to update db table");  

         

        [db close];  

  

   

4)删除数据:



if ([db open])  

          

        NSString *deleteSql [NSString stringWithFormat:  

                               @"delete from %@ where %@ ‘%@‘",  

                               TABLENAME, NAME, @"张三"];  

        BOOL res [db executeUpdate:deleteSql];  

          

        if (!res)  

            NSLog(@"error when delete db table");  

        else  

            NSLog(@"success to delete db table");  

         

        [db close];  

  

   




5)数据库查询操作:

查询操作使用了executeQuery,并涉及到FMResultSet。



if ([db open])  

        NSString sql [NSString stringWithFormat:  

                          @"SELECT FROM %@",TABLENAME];  

        FMResultSet rs [db executeQuery:sql];  

        while ([rs next])  

            int Id [rs intForColumn:ID];  

            NSString name [rs stringForColumn:NAME];  

            NSString age [rs stringForColumn:AGE];  

            NSString address [rs stringForColumn:ADDRESS];  

            NSLog(@"id %d, name %@, age %@  address %@", Id, name, age, address);  

         

        [db close];  

  



FMDB的FMResultSet提供了多个方法来获取不同类型的数据:







3.3 数据库多线程操作:


        如果应用中使用了多线程操作数据库,那么就需要使用FMDatabaseQueue来保证线程安全了。 应用中不可在多个线程中共同使用一个FMDatabase对象操作数据库,这样会引起数据库数据混乱。 为了多线程操作数据库安全,FMDB使用了FMDatabaseQueue,使用FMDatabaseQueue很简单,首先用一个数据库文件地址来初使化FMDatabaseQueue,然后就可以将一个闭包(block)传入inDatabase方法中。 在闭包中操作数据库,而不直接参与FMDatabase的管理。



FMDatabaseQueue queue [FMDatabaseQueue databaseQueueWithPath:database_path];  

   dispatch_queue_t q1 dispatch_queue_create("queue1", NULL);  

   dispatch_queue_t q2 dispatch_queue_create("queue2", NULL);  

     

   dispatch_async(q1, ^{  

       for (int 0; 50; ++i)  

           [queue inDatabase:^(FMDatabase *db2)  

                 

               NSString *insertSql1= [NSString stringWithFormat:  

                                      @"INSERT INTO ‘%@‘ (‘%@‘, ‘%@‘, ‘%@‘) VALUES (?, ?, ?)",  

                                      TABLENAME, NAME, AGE, ADDRESS];  

                 

               NSString name [NSString stringWithFormat:@"jack %d", i];  

               NSString age [NSString stringWithFormat:@"%d", 10+i];  

                 

                 

               BOOL res [db2 executeUpdate:insertSql1, name, age,@"济南"];  

               if (!res)  

                   NSLog(@"error to inster data: %@", name);  

               else  

                   NSLog(@"succ to inster data: %@", name);  

                

           }];  

        

   });  

     

   dispatch_async(q2, ^{  

       for (int 0; 50; ++i)  

           [queue inDatabase:^(FMDatabase *db2)  

               NSString *insertSql2= [NSString stringWithFormat:  

                                      @"INSERT INTO ‘%@‘ (‘%@‘, ‘%@‘, ‘%@‘) VALUES (?, ?, ?)",  

                                      TABLENAME, NAME, AGE, ADDRESS];  

                 

               NSString name [NSString stringWithFormat:@"lilei %d", i];  

               NSString age [NSString stringWithFormat:@"%d", 10+i];  

                 

               BOOL res [db2 executeUpdate:insertSql2, name, age,@"北京"];  

               if (!res)  

                   NSLog(@"error to inster data: %@", name);  

               else  

                   NSLog(@"succ to inster data: %@", name);  

                

           }];  

        

   });  



4.总结


  • CoreData允许用户使用代表实体和实体间关系的高层对象来操作数据。它也可以管理串行化的数据,提供对象生存期管理与object_graph 管理,包括存储。Core Data直接与交互,避免开发者使用原本的语句.


  • 上面的三种,都是在什么情况下使用呢?大多数人肯定是根据自己使用某项技术的时间也就是掌握的熟练程度来决定,例如以前没用过CoreData,在编写ios程序的时候还是使用自己比较拿手的SQLite,或者可能会考虑到在使用coredata自己还要花费额外的时候去学习。


  • 但是仔细想一想,CoreData是苹果自己弄的框架,它其实还是和SQLite进行交互的,只是在交互的时候或者处理数据的时候进行了很多的优化,CoreData可以缩小你的代码量,而且CoreData已经优化过很多个版本,还提供了出色的安全性和错误处理之外,还提供了对任何竞争性方案的最好的内存可扩展性。换句话说就是,你可能花费了很长时间为某个问题进行优化精心制作了一个方案,但是在性能上的优势和CoreData相比,还是相差深远的。


  • 另外就是CoreData与Mac OS X的集成非常的好,CoreData也和IB进行了结合,允许你创建用户界面,这样可以帮助你缩短应用程序的设计,实施以及调试周期。


  • 所以在编写程序的时候尽量使用CoreData,这样才是最优的选择。只有在Core Data is available on iOS 3.0 and later才能使用CoreData。


  • 至于SQLite和FMDB的使用情况,这个看个人喜好了,个人觉得没什么标准。FMDB就是对SQLite的封装,使用起来有方便的接口,没那么麻烦而已。

热门排行

今日推荐

热门手游