增加持久化swift 数据持久化函数

iOS中几种数据持久化方案:我要永远地记住你!
招聘信息:
作者: 授权本站转载概论所谓的持久化,就是将数据保存到硬盘中,使得在应用程序或机器重启后可以继续访问之前保存的数据。在iOS开发中,有很多数据持久化的方案,接下来我将尝试着介绍一下5种方案:plist文件(属性列表)preference(偏好设置)NSKeyedArchiver(归档)SQLite 3CoreData沙盒在介绍各种存储方法之前,有必要说明以下沙盒机制。iOS程序默认情况下只能访问程序自己的目录,这个目录被称为“沙盒”。1.结构既然沙盒就是一个文件夹,那就看看里面有什么吧。沙盒的目录结构如下:"应用程序包"
&&&&Caches
&&&&Preferences
tmp2.目录特性虽然沙盒中有这么多文件夹,但是没有文件夹都不尽相同,都有各自的特性。所以在选择存放目录时,一定要认真选择适合的目录。"应用程序包": 这里面存放的是应用程序的源文件,包括资源文件和可执行文件。&&NSString&*path&=&[[NSBundle&mainBundle]&bundlePath];
&&NSLog(@"%@",&path);Documents: 最常用的目录,iTunes同步该应用时会同步此文件夹中的内容,适合存储重要数据。&&NSString&*path&=&NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,&NSUserDomainMask,&YES).firstO
&&NSLog(@"%@",&path);Library/Caches: iTunes不会同步此文件夹,适合存储体积大,不需要备份的非重要数据。&&NSString&*path&=&NSSearchPathForDirectoriesInDomains(NSCachesDirectory,&NSUserDomainMask,&YES).firstO
&&NSLog(@"%@",&path);Library/Preferences: iTunes同步该应用时会同步此文件夹中的内容,通常保存应用的设置信息。tmp: iTunes不会同步此文件夹,系统可能在应用没运行时就删除该目录下的文件,所以此目录适合保存应用中的一些临时文件,用完就删除。&&NSString&*path&=&NSTemporaryDirectory();
&&NSLog(@"%@",&path);plist文件plist文件是将某些特定的类,通过XML文件的方式保存在目录中。可以被序列化的类型只有如下几种:NSA
NSMutableA
NSMutableD
NSMutableD
NSMutableS
NSD1.获得文件路径&&&&NSString&*path&=&NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,&NSUserDomainMask,&YES).firstO
&&&&NSString&*fileName&=&[path&stringByAppendingPathComponent:@"123.plist"];2.存储NSArray&*array&=&@[@"123",&@"456",&@"789"];
[array&writeToFile:fileName&atomically:YES];3.读取NSArray&*result&=&[NSArray&arrayWithContentsOfFile:fileName];
NSLog(@"%@",&result);4.注意只有以上列出的类型才能使用plist文件存储。存储时使用writeToFile: atomically:方法。 其中atomically表示是否需要先写入一个辅助文件,再把辅助文件拷贝到目标文件地址。这是更安全的写入文件方法,一般都写YES。读取时使用arrayWithContentsOfFile:方法。Preference1.使用方法//1.获得NSUserDefaults文件
NSUserDefaults&*userDefaults&=&[NSUserDefaults&standardUserDefaults];
//2.向文件中写入内容
[userDefaults&setObject:@"AAA"&forKey:@"a"];
[userDefaults&setBool:YES&forKey:@"sex"];
[userDefaults&setInteger:21&forKey:@"age"];
//2.1立即同步
[userDefaults&synchronize];
//3.读取文件
NSString&*name&=&[userDefaults&objectForKey:@"a"];
BOOL&sex&=&[userDefaults&boolForKey:@"sex"];
NSInteger&age&=&[userDefaults&integerForKey:@"age"];
NSLog(@"%@,&%d,&%ld",&name,&sex,&age);2.注意偏好设置是专门用来保存应用程序的配置信息的,一般不要在偏好设置中保存其他数据。如果没有调用synchronize方法,系统会根据I/O情况不定时刻地保存到文件中。所以如果需要立即写入文件的就必须调用synchronize方法。偏好设置会将所有数据保存到同一个文件中。即preference目录下的一个以此应用包名来命名的plist文件。NSKeyedArchiver归档在iOS中是另一种形式的序列化,只要遵循了NSCoding协议的对象都可以通过它实现序列化。由于决大多数支持存储数据的Foundation和Cocoa Touch类都遵循了NSCoding协议,因此,对于大多数类来说,归档相对而言还是比较容易实现的。1.遵循NSCoding协议NSCoding协议声明了两个方法,这两个方法都是必须实现的。一个用来说明如何将对象编码到归档中,另一个说明如何进行解档来获取一个新对象。遵循协议和设置属性&&//1.遵循NSCoding协议&
&&@interface&Person&:&NSObject&&&//2.设置属性
&&@property&(strong,&nonatomic)&UIImage&*
&&@property&(copy,&nonatomic)&NSString&*
&&@property&(assign,&nonatomic)&NSInteger&
&&@end实现协议方法&&//解档
&&-&(id)initWithCoder:(NSCoder&*)aDecoder&{
&&&&&&if&([super&init])&{
&&&&&&&&&&self.avatar&=&[aDecoder&decodeObjectForKey:@"avatar"];
&&&&&&&&&&self.name&=&[aDecoder&decodeObjectForKey:@"name"];
&&&&&&&&&&self.age&=&[aDecoder&decodeIntegerForKey:@"age"];
&&&&&&return&
&&-&(void)encodeWithCoder:(NSCoder&*)aCoder&{
&&&&&&[aCoder&encodeObject:self.avatar&forKey:@"avatar"];
&&&&&&[aCoder&encodeObject:self.name&forKey:@"name"];
&&&&&&[aCoder&encodeInteger:self.age&forKey:@"age"];
&&}特别注意如果需要归档的类是某个自定义类的子类时,就需要在归档和解档之前先实现父类的归档和解档方法。即 [super encodeWithCoder:aCoder] 和 [super initWithCoder:aDecoder] 方法;2.使用需要把对象归档是调用NSKeyedArchiver的工厂方法 archiveRootObject: toFile: 方法。&&NSString&*file&=&[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,&NSUserDomainMask,&YES).firstObject&stringByAppendingPathComponent:@"person.data"];
&&Person&*person&=&[[Person&alloc]&init];
&&person.avatar&=&self.avatarView.
&&person.name&=&self.nameField.
&&person.age&=&[self.ageField.text&integerValue];
&&[NSKeyedArchiver&archiveRootObject:person&toFile:file];需要从文件中解档对象就调用NSKeyedUnarchiver的一个工厂方法 unarchiveObjectWithFile: 即可。&&NSString&*file&=&[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,&NSUserDomainMask,&YES).firstObject&stringByAppendingPathComponent:@"person.data"];
&&Person&*person&=&[NSKeyedUnarchiver&unarchiveObjectWithFile:file];
&&if&(person)&{
&&&&&self.avatarView.image&=&person.
&&&&&self.nameField.text&=&person.
&&&&&self.ageField.text&=&[NSString&stringWithFormat:@"%ld",&person.age];
&&}3.注意必须遵循并实现NSCoding协议保存文件的扩展名可以任意指定继承时必须先调用父类的归档解档方法SQLite3之前的所有存储方法,都是覆盖存储。如果想要增加一条数据就必须把整个文件读出来,然后修改数据后再把整个内容覆盖写入文件。所以它们都不适合存储大量的内容。1.字段类型表面上SQLite将数据分为以下几种类型:integer : 整数real : 实数(浮点数)text : 文本字符串blob : 二进制数据,比如文件,图片之类的实际上SQLite是无类型的。即不管你在创表时指定的字段类型是什么,存储是依然可以存储任意类型的数据。而且在创表时也可以不指定字段类型。SQLite之所以什么类型就是为了良好的编程规范和方便开发人员交流,所以平时在使用时最好设置正确的字段类型!主键必须设置成integer2. 准备工作准备工作就是导入依赖库啦,在iOS中要使用SQLite3,需要添加库文件:libsqlite3.dylib并导入主头文件,这是一个C语言的库,所以直接使用SQLite3还是比较麻烦的。3.使用创建数据库并打开操作数据库之前必须先指定数据库文件和要操作的表,所以使用SQLite3,首先要打开数据库文件,然后指定或创建一张表。/**
*&&打开数据库并创建一个表
-&(void)openDatabase&{
&&&//1.设置文件名
&&&NSString&*filename&=&[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,&NSUserDomainMask,&YES).firstObject&stringByAppendingPathComponent:@"person.db"];
&&&//2.打开数据库文件,如果没有会自动创建一个文件
&&&NSInteger&result&=&sqlite3_open(filename.UTF8String,&&_sqlite3);
&&&if&(result&==&SQLITE_OK)&{
&&&&&&&NSLog(@"打开数据库成功!");
&&&&&&&//3.创建一个数据库表
&&&&&&&char&*errmsg&=&NULL;
&&&&&&&sqlite3_exec(_sqlite3,&"CREATE&TABLE&IF&NOT&EXISTS&t_person(id&integer&primary&key&autoincrement,&name&text,&age&integer)",&NULL,&NULL,&&errmsg);
&&&&&&&if&(errmsg)&{
&&&&&&&&&&&NSLog(@"错误:%s",&errmsg);
&&&&&&&}&else&{
&&&&&&&&&&&NSLog(@"创表成功!");
&&&}&else&{
&&&&&&&NSLog(@"打开数据库失败!");
}执行指令使用 sqlite3_exec() 方法可以执行任何SQL语句,比如创表、更新、插入和删除操作。但是一般不用它执行查询语句,因为它不会返回查询到的数据。/**
*&&往表中插入1000条数据
-&(void)insertData&{
NSString&*nameS
NSInteger&
for&(NSInteger&i&=&0;&i&<&1000;&i++)&{
&&nameStr&=&[NSString&stringWithFormat:@"Bourne-%d",&arc4random_uniform(10000)];
&&age&=&arc4random_uniform(80)&+&20;
&&NSString&*sql&=&[NSString&stringWithFormat:@"INSERT&INTO&t_person&(name,&age)&VALUES(&#39;%@&#39;,&&#39;%ld&#39;)",&nameStr,&age];
&&char&*errmsg&=&NULL;
&&sqlite3_exec(_sqlite3,&sql.UTF8String,&NULL,&NULL,&&errmsg);
&&if&(errmsg)&{
&&&&&&NSLog(@"错误:%s",&errmsg);
NSLog(@"插入完毕!");
}查询指令前面说过一般不使用 sqlite3_exec() 方法查询数据。因为查询数据必须要获得查询结果,所以查询相对比较麻烦。示例代码如下:sqlite3_prepare_v2() : 检查sql的合法性sqlite3_step() : 逐行获取查询结果,不断重复,直到最后一条记录sqlite3_coloum_xxx() : 获取对应类型的内容,iCol对应的就是SQL语句中字段的顺序,从0开始。根据实际查询字段的属性,使用sqlite3_column_xxx取得对应的内容即可。sqlite3_finalize() : 释放stmt/**
*&&从表中读取数据到数组中
-&(void)readData&{
&&&NSMutableArray&*mArray&=&[NSMutableArray&arrayWithCapacity:1000];
&&&char&*sql&=&"select&name,&age&from&t_";
&&&sqlite3_stmt&*
&&&NSInteger&result&=&sqlite3_prepare_v2(_sqlite3,&sql,&-1,&&stmt,&NULL);
&&&if&(result&==&SQLITE_OK)&{
&&&&&&&while&(sqlite3_step(stmt)&==&SQLITE_ROW)&{
&&&&&&&&&&&char&*name&=&(char&*)sqlite3_column_text(stmt,&0);
&&&&&&&&&&&NSInteger&age&=&sqlite3_column_int(stmt,&1);
&&&&&&&&&&&//创建对象
&&&&&&&&&&&Person&*person&=&[Person&personWithName:[NSString&stringWithUTF8String:name]&Age:age];
&&&&&&&&&&&[mArray&addObject:person];
&&&&&&&self.dataList&=&mA
&&&sqlite3_finalize(stmt);
}4.总结总得来说,SQLite3的使用还是比较麻烦的,因为都是些c语言的函数,理解起来有些困难。不过在一般开发过程中,使用的都是第三方开源库 FMDB,封装了这些基本的c语言方法,使得我们在使用时更加容易理解,提高开发效率。FMDB1.简介FMDB是iOS平台的SQLite数据库框架,它是以OC的方式封装了SQLite的C语言API,它相对于cocoa自带的C语言框架有如下的优点:使用起来更加面向对象,省去了很多麻烦、冗余的C语言代码对比苹果自带的Core Data框架,更加轻量级和灵活提供了多线程安全的数据库操作方法,有效地防止数据混乱注:2.核心类FMDB有三个主要的类:FMDatabase一个FMDatabase对象就代表一个单独的SQLite数据库,用来执行SQL语句FMResultSet使用FMDatabase执行查询后的结果集FMDatabaseQueue用于在多线程中执行多个查询或更新,它是线程安全的3.打开数据库和c语言框架一样,FMDB通过指定SQLite数据库文件路径来创建FMDatabase对象,但FMDB更加容易理解,使用起来更容易,使用之前一样需要导入sqlite3.dylib。打开数据库方法如下:NSString&*path&=&[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,&NSUserDomainMask,&YES).firstObject&stringByAppendingPathComponent:@"person.db"];
FMDatabase&*database&=&[FMDatabase&databaseWithPath:path];&&&&
if&(![database&open])&{
&&&&NSLog(@"数据库打开失败!");
}值得注意的是,Path的值可以传入以下三种情况:具体文件路径,如果不存在会自动创建空字符串@"",会在临时目录创建一个空的数据库,当FMDatabase连接关闭时,数据库文件也被删除nil,会创建一个内存中临时数据库,当FMDatabase连接关闭时,数据库会被销毁4.更新在FMDB中,除查询以外的所有操作,都称为“更新”, 如:create、drop、insert、update、delete等操作,使用executeUpdate:方法执行更新://常用方法有以下3种:&&&
-&(BOOL)executeUpdate:(NSString*)sql,&...
-&(BOOL)executeUpdateWithFormat:(NSString*)format,&...
-&(BOOL)executeUpdate:(NSString*)sql&withArgumentsInArray:(NSArray&*)arguments
[database&executeUpdate:@"CREATE&TABLE&IF&NOT&EXISTS&t_person(id&integer&primary&key&autoincrement,&name&text,&age&integer)"];&&&
[database&executeUpdate:@"INSERT&INTO&t_person(name,&age)&VALUES(?,&?)",&@"Bourne",&[NSNumber&numberWithInt:42]];5.查询查询方法也有3种,使用起来相当简单:-&(FMResultSet&*)executeQuery:(NSString*)sql,&...
-&(FMResultSet&*)executeQueryWithFormat:(NSString*)format,&...
-&(FMResultSet&*)executeQuery:(NSString&*)sql&withArgumentsInArray:(NSArray&*)arguments查询示例://1.执行查询
FMResultSet&*result&=&[database&executeQuery:@"SELECT&*&FROM&t_person"];
//2.遍历结果集
while&([result&next])&{
&&&&NSString&*name&=&[result&stringForColumn:@"name"];
&&&&int&age&=&[result&intForColumn:@"age"];
}6.线程安全在多个线程中同时使用一个FMDatabase实例是不明智的。不要让多个线程分享同一个FMDatabase实例,它无法在多个线程中同时使用。 如果在多个线程中同时使用一个FMDatabase实例,会造成数据混乱等问题。所以,请使用 FMDatabaseQueue,它是线程安全的。以下是使用方法:创建队列。FMDatabaseQueue&*queue&=&[FMDatabaseQueue&databaseQueueWithPath:aPath];使用队列[queue&inDatabase:^(FMDatabase&*database)&{&&&&
&&&&&&&&&&[database&executeUpdate:@"INSERT&INTO&t_person(name,&age)&VALUES&(?,&?)",&@"Bourne_1",&[NSNumber&numberWithInt:1]];&&&&
&&&&&&&&&&[database&executeUpdate:@"INSERT&INTO&t_person(name,&age)&VALUES&(?,&?)",&@"Bourne_2",&[NSNumber&numberWithInt:2]];&&&&
&&&&&&&&&&[database&executeUpdate:@"INSERT&INTO&t_person(name,&age)&VALUES&(?,&?)",&@"Bourne_3",&[NSNumber&numberWithInt:3]];&&&&&&
&&&&&&&&&&FMResultSet&*result&=&[database&executeQuery:@"select&*&from&t_person"];&&&&
&&&&&&&&&while([result&next])&{&&&
&&&&&&&&&}&&&&
}];而且可以轻松地把简单任务包装到事务里:[queue&inTransaction:^(FMDatabase&*database,&BOOL&*rollback)&{&&&&
&&&&&&&&&&[database&executeUpdate:@"INSERT&INTO&t_person(name,&age)&VALUES&(?,&?)",&@"Bourne_1",&[NSNumber&numberWithInt:1]];&&&&
&&&&&&&&&&[database&executeUpdate:@"INSERT&INTO&t_person(name,&age)&VALUES&(?,&?)",&@"Bourne_2",&[NSNumber&numberWithInt:2]];&&&&
&&&&&&&&&&[database&executeUpdate:@"INSERT&INTO&t_person(name,&age)&VALUES&(?,&?)",&@"Bourne_3",&[NSNumber&numberWithInt:3]];&&&&&&
&&&&&&&&&&FMResultSet&*result&=&[database&executeQuery:@"select&*&from&t_person"];&&&&
&&&&&&&&&&&&&while([result&next])&{&&&
&&&&&&&&&&&&&}&&&
&&&&&&&&&&&//回滚
&&&&&&&&&&&*rollback&=&YES;&&
&&&&}];FMDatabaseQueue 后台会建立系列化的G-C-D队列,并执行你传给G-C-D队列的块。这意味着 你从多线程同时调用调用方法,GDC也会按它接收的块的顺序来执行。CoreData详见我的另一篇笔记:声明:以上内容属于本人整理的笔记,如有错误的地方希望能告诉我,大家共同进步。以上内容有些段落或语句可能是本人从其他地方Copy而来,如有侵权,请及时告诉我。
微信扫一扫
订阅每日移动开发及APP推广热点资讯公众号:CocoaChina
您还没有登录!请或
点击量16272点击量10875点击量8664点击量8017点击量7488点击量7063点击量6588点击量6497点击量5716
&2016 Chukong Technologies,Inc.
京公网安备89君,已阅读到文档的结尾了呢~~
可持久化数据结构研究帮助,可持久化,数据结构,持久化,函数式编程,陈立杰,反馈意见
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
可持久化数据结构研究
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口hibernate中持久化对象的更新_百度知道
hibernate中持久化对象的更新
这个是什么原因,所以当session执行flush方法的时候在控制台打印出了update语句因为持久化对象存在于本次事务的session缓存中.所以在session清空缓存(flush)的时候hibernate应该自己会检测与数据库中记录不一致的情况来自动执行update方法啊,内容反而没改变.由于在配置文件中设置show_sql为true.之后查询数据库中..?求解释啊
只写 了session的flush()函数后来试了一下在本次更新中加入了Transaction 的提交?但是书上说的session只要flush就可以了.就可以完成持久化对象的更新了.难道是每一个CURD都需要有事务的提交才行么.但是没有session的更新...,迷惑
提问者采纳
执行flush仅仅是执行SQL语句,别人就查不到,仍然会回滚。回滚事务。所以说执行数据更新语句。不提交直接中断连接,插入一条数据,如果不提交事物。就算是不使用hibernate,数据库最后仍然会回滚掉此次更新。但是如果不提交事物,马上查询能查到,自己也查不到了,如果开启一个事务。hibernatehibernate执行sql语句不代表数据更新。但是不提交事物,下次连接自己也查不到了
提问者评价
其他类似问题
为您推荐:
其他1条回答
flush()知识清理缓存,将缓存中的数据强制清空,但是涉及到数据库中数据的更新session
但是flush后hibernate就会默认执行update方法啊..这个没什么争议啊..
持久化的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁中国领先的IT技术网站
51CTO旗下网站
iOS中几种数据持久化方案:我要永远地记住你!(2)
所谓的持久化,就是将数据保存到硬盘中,使得在应用程序或机器重启后可以继续访问之前保存的数据
作者:伯恩的遗产来源:| 13:14
NSKeyedArchiver
归档在iOS中是另一种形式的序列化,只要遵循了NSCoding协议的对象都可以通过它实现序列化。由于决大多数支持存储数据的Foundation和Cocoa Touch类都遵循了NSCoding协议,因此,对于大多数类来说,归档相对而言还是比较容易实现的。
1.遵循NSCoding协议
NSCoding协议声明了两个方法,这两个方法都是必须实现的。一个用来说明如何将对象编码到归档中,另一个说明如何进行解档来获取一个新对象。
遵循协议和设置属性
&&&@interface&Person&:&NSObject&&&&&&@property&(strong,&nonatomic)&UIImage&*&&&@property&(copy,&nonatomic)&NSString&*&&&@property&(assign,&nonatomic)&NSInteger&&&&@end&
实现协议方法
&&&-&(id)initWithCoder:(NSCoder&*)aDecoder&{&&&&&&&if&([super&init])&{&&&&&&&&&&&self.avatar&=&[aDecoder&decodeObjectForKey:@&avatar&];&&&&&&&&&&&self.name&=&[aDecoder&decodeObjectForKey:@&name&];&&&&&&&&&&&self.age&=&[aDecoder&decodeIntegerForKey:@&age&];&&&&&&&}&&&&&&&return&&&&}&&&&&&-&(void)encodeWithCoder:(NSCoder&*)aCoder&{&&&&&&&[aCoder&encodeObject:self.avatar&forKey:@&avatar&];&&&&&&&[aCoder&encodeObject:self.name&forKey:@&name&];&&&&&&&[aCoder&encodeInteger:self.age&forKey:@&age&];&&&}&
如果需要归档的类是某个自定义类的子类时,就需要在归档和解档之前先实现父类的归档和解档方法。即 [super encodeWithCoder:aCoder] 和 [super initWithCoder:aDecoder] 方法;
需要把对象归档是调用NSKeyedArchiver的工厂方法 archiveRootObject: toFile: 方法。
NSString&*file&=&[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,&NSUserDomainMask,&YES).firstObject&stringByAppendingPathComponent:@&person.data&];&&&Person&*person&=&[[Person&alloc]&init];&&&person.avatar&=&self.avatarView.&&&person.name&=&self.nameField.&&&person.age&=&[self.ageField.text&integerValue];&&&[NSKeyedArchiver&archiveRootObject:person&toFile:file];&
需要从文件中解档对象就调用NSKeyedUnarchiver的一个工厂方法 unarchiveObjectWithFile: 即可。
NSString&*file&=&[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,&NSUserDomainMask,&YES).firstObject&stringByAppendingPathComponent:@&person.data&];&&&Person&*person&=&[NSKeyedUnarchiver&unarchiveObjectWithFile:file];&&&if&(person)&{&&&&&&self.avatarView.image&=&person.&&&&&&self.nameField.text&=&person.&&&&&&self.ageField.text&=&[NSString&stringWithFormat:@&%ld&,&person.age];&&&}&
必须遵循并实现NSCoding协议
保存文件的扩展名可以任意指定
继承时必须先调用父类的归档解档方法
之前的所有存储方法,都是覆盖存储。如果想要增加一条数据就必须把整个文件读出来,然后修改数据后再把整个内容覆盖写入文件。所以它们都不适合存储大量的内容。
1.字段类型
表面上SQLite将数据分为以下几种类型:
integer : 整数
real : 实数(浮点数)
text : 文本字符串
blob : 二进制数据,比如文件,图片之类的
实际上SQLite是无类型的。即不管你在创表时指定的字段类型是什么,存储是依然可以存储任意类型的数据。而且在创表时也可以不指定字段类型。SQLite之所以什么类型就是为了良好的编程规范和方便开发人员交流,所以平时在使用时最好设置正确的字段类型!主键必须设置成integer
2. 准备工作
准备工作就是导入依赖库啦,在iOS中要使用SQLite3,需要添加库文件:libsqlite3.dylib并导入主头文件,这是一个C语言的库,所以直接使用SQLite3还是比较麻烦的。
创建数据库并打开
操作数据库之前必须先指定数据库文件和要操作的表,所以使用SQLite3,首先要打开数据库文件,然后指定或创建一张表。
&&&-&(void)openDatabase&{&&&&&&&&NSString&*filename&=&[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,&NSUserDomainMask,&YES).firstObject&stringByAppendingPathComponent:@&person.db&];&&&&&&&&NSInteger&result&=&sqlite3_open(filename.UTF8String,&&_sqlite3);&&&&if&(result&==&SQLITE_OK)&{&&&&&&&&NSLog(@&打开数据库成功!&);&&&&&&&&&&&&&&&&char&*errmsg&=&NULL;&&&&&&&&sqlite3_exec(_sqlite3,&&CREATE&TABLE&IF&NOT&EXISTS&t_person(id&integer&primary&key&autoincrement,&name&text,&age&integer)&,&NULL,&NULL,&&errmsg);&&&&&&&&if&(errmsg)&{&&&&&&&&&&&&NSLog(@&错误:%s&,&errmsg);&&&&&&&&}&else&{&&&&&&&&&&&&NSLog(@&创表成功!&);&&&&&&&&}&&&&}&else&{&&&&&&&&NSLog(@&打开数据库失败!&);&&&&}&}&
使用 sqlite3_exec() 方法可以执行任何SQL语句,比如创表、更新、插入和删除操作。但是一般不用它执行查询语句,因为它不会返回查询到的数据。
&&&-&(void)insertData&{&NSString&*nameS&NSInteger&&for&(NSInteger&i&=&0;&i&&&1000;&i++)&{&&&nameStr&=&[NSString&stringWithFormat:@&Bourne-%d&,&arc4random_uniform(10000)];&&&age&=&arc4random_uniform(80)&+&20;&&&NSString&*sql&=&[NSString&stringWithFormat:@&INSERT&INTO&t_person&(name,&age)&VALUES('%@',&'%ld')&,&nameStr,&age];&&&char&*errmsg&=&NULL;&&&sqlite3_exec(_sqlite3,&sql.UTF8String,&NULL,&NULL,&&errmsg);&&&if&(errmsg)&{&&&&&&&NSLog(@&错误:%s&,&errmsg);&&&}&}&NSLog(@&插入完毕!&);&}&
前面说过一般不使用 sqlite3_exec() 方法查询数据。因为查询数据必须要获得查询结果,所以查询相对比较麻烦。示例代码如下:
sqlite3_prepare_v2() : 检查sql的合法性
sqlite3_step() : 逐行获取查询结果,不断重复,直到最后一条记录
sqlite3_coloum_xxx() : 获取对应类型的内容,iCol对应的就是SQL语句中字段的顺序,从0开始。根据实际查询字段的属性,使用sqlite3_column_xxx取得对应的内容即可。
sqlite3_finalize() : 释放stmt
&&&-&(void)readData&{&&&&NSMutableArray&*mArray&=&[NSMutableArray&arrayWithCapacity:1000];&&&&char&*sql&=&&select&name,&age&from&t_&;&&&&sqlite3_stmt&*&&&&NSInteger&result&=&sqlite3_prepare_v2(_sqlite3,&sql,&-1,&&stmt,&NULL);&&&&if&(result&==&SQLITE_OK)&{&&&&&&&&while&(sqlite3_step(stmt)&==&SQLITE_ROW)&{&&&&&&&&&&&&char&*name&=&(char&*)sqlite3_column_text(stmt,&0);&&&&&&&&&&&&NSInteger&age&=&sqlite3_column_int(stmt,&1);&&&&&&&&&&&&&&&&&&&&&&&&Person&*person&=&[Person&personWithName:[NSString&stringWithUTF8String:name]&Age:age];&&&&&&&&&&&&[mArray&addObject:person];&&&&&&&&}&&&&&&&&self.dataList&=&mA&&&&}&&&&sqlite3_finalize(stmt);&}&
总得来说,SQLite3的使用还是比较麻烦的,因为都是些c语言的函数,理解起来有些困难。不过在一般开发过程中,使用的都是第三方开源库 FMDB,封装了这些基本的c语言方法,使得我们在使用时更加容易理解,提高开发效率。
大家都在看猜你喜欢
热点头条头条热点头条
24H热文一周话题本月最赞
讲师:12人学习过
讲师:13人学习过
讲师:20人学习过
精选博文论坛热帖下载排行
本书是关于如何使用已有的密码技术和算法对数据库中存储的信息进行保护的书,书中所关注的内容主要是如何设计、建立(或者挑选、集成)一套...
订阅51CTO邮刊}

我要回帖

更多关于 数据库持久化 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信