数据存储的核心都是写文件
1.XML属性列表,写成plist文件
NSString、NSArray、NSDictionary、NSData对象可以采用writeToFile方式直接写文件,存储的为plist文件.plist文件中只能存放以下7中数据类型:array、dictionary、string、bool、data、date、number.
2.用户偏好存数据:
获取NSUserDefault对象
存储对象
强制数据立刻保存 [[NSUserDefaults standardUserDefaults] synchronize]
取数据:[[NSUserDefaults standardUserDefaults] objectForKey]
3.归档解档(对象序列化)
对于自定义对象,一般通过直接写文件是不方便的,采用归档解档的方式可以比较方便的存储.存值的时候,通过序列化的形式,键值关系存储到本地,转化成二进制流,[NSKeyedArchiver archiveRootObject]
。取值的时候把二进制数据转化为本来的类型,[NSKeyedUnarchiver unarchiveObjectWithFile]
.
自定义类需要遵守NSCoding协议,并且实现它的两个方法:encodeWithCoder:以及initWithCoder:
当子类继承父类时,如果增加了属性,一定要重写父类的这两个方法,给自己的属性进行归档解档设置
FMDB
FMDB是以OC的方式封装了SQLite的C语言API,面向对象,使用起来更加的灵活,并且还提供了多线程安全的操作方法,有效防止数据的紊乱.FMDB主要有三个类:FMDatabase
(一个该对象代表一个单独的SQLite数据库,使用该对象执行sql语句),FMResultSet(FMDatabase
执行查询操作后的结果集),FMDatabaseQueue
(在多线程中调度数据库操作任务,执行更新和查询,保证了线性安全)
-
DB的使用
- 创建单例类来隔离FMDB
- 创建FMDatabaseQueue的一个队列,由队列来操作数据库(采用线性安全的方式,扩展性强)
- 创建数据库:如果数据库不存在就创建,已经存在就打开数据库
sql语句:
CREATE TABLE IF NOT EXISTS "T_SHStatus" (
"statusid" INTEGER NOT NULL,
"userid" INTEGER NOT NULL,
"status" TEXT,
"createtime" TEXT DEFAULT (datetime('now','localtime')),
PRIMARY KEY("statusid","userid"))
queue.inDatabase { (db) -> Void in
// 执行sql
let result = db.executeStatements(sql)
if result {
print("创建表成功")
}else{
print("创建表失败")
}
}
向队列中添加任务的两种方式:
非事务队列:- (void)inDatabase:(void (^)(FMDatabase *db))block;和 事务队列:- (void)inTransaction:(void (^)(FMDatabase *db, BOOL
使用事务处理就是将所有任务执行完成以后将结果一次性提交到数据库,如果此过程出现异常则会执行回滚操作,这样节省了大量的重复提交环节所浪费的时间。 比如说:假如北京的一家A工厂接了上海一家B公司的500件产品的订单,思考一下:A工厂是生产完一件立即就送到B公司还是将500件产品全部生产完成后再送往B公司?答案肯定是后者,因为前者浪费了大量的时间、人力物力花费在往返于北京和上海之间。同样这个道理也能用在我们的数据库操作上。增删改,都是使用executeUpdate方法,先准备SQL语句,然后再执行SQL语句的过程
数据操作语言,即增insert into ...values...,删delete from ...where...,改update...set...where...),DQL(数据查询语言select...from...order by ... asc/desc)
- 查:
executeQuery
方法
-(NSArray*)seletRecord:(NSString *)sql{
NSMutableArray * array = [NSMutableArray array];
[self.mainqueue inDatabase:^(FMDatabase *db) {
FMResultSet *result = [db executeQuery:sql withArgumentsInArray:nil];
while (result.next) {
NSMutableDictionary * dict = [NSMutableDictionary dictionary];
for (int i = 0; i< [result columnCount]; i++) {
NSString * key = [result columnNameForIndex:i];
id value = [result objectForColumnIndex:i];
dict[key] = value;
}
[array addObject:dict];
}
}];
return array.copy;
}
NSString * sql = [NSString stringWithFormat:@"SELECT * FROM T_SHStatus order by userid desc"];
// order by ... desc 倒序查询
// order by... asc 顺序查询
NSArray * array = [[SqliteManager sharedManager] seletRecord:sql];
NSLog(@"%@",array);
- 数据库创建后,在以后的使用中可能数据发生改变,需要添加字段
-(void)addTableWith:(NSString*)tableName{
[self.mainqueue inDatabase:^(FMDatabase *db) {
// 判断总段是否已经存在
BOOL result = [db columnExists:@"isLogin" inTableWithName:@"T_SHStatus"];
if (!result) {
// sql 语句
NSString * sql = [NSString stringWithFormat:@"ALTER TABLE T_SHStatus ADD COLUMN %@ BOOL",tableName];
// 执行sql语句
BOOL result = [db executeUpdate:sql];
if (result) {
NSLog(@"添加字段成功");
}else{
NSLog(@"添加字段失败");
}
}
}];
}