UI_19 数据持久化(本地存储)

一、数据持久化概述

    数据持久化就是数据的永久存储。其本质是将数据保存为文件,存到程序的沙盒中。

1、数据持久化的方式

1.1 writeToFile:简单对象写入文件

1.2 NSUserDefaults:应用程序偏好设置
1.3 Sqlite:
轻量级关系型数据库,不能直接存储对象(NSData除外),需要用到一些SQL语句,先将复杂对象归档(对象->NSData)

1.4 CoreData:对象型数据库,实质是将数据库的内部存储细节封装

1.5 Plist文件


2、应用程序沙盒

    每一应用程序都有自己的应用沙盒,沙盒的本质就是一个文件夹,名字是随机分配的。

    与其他应用程序沙盒隔离,应用程序本身只能访问自己沙盒的数据。(iOS8+对沙盒之间的访问部分开放)


2.1 应用程序包(.app)

     包含了应用程序中所用到的所有资源文件和可执行文件(Base on Unix)。iOS8时,app不存储在沙盒中,有单独的文件夹存储所有程序的app包。


2.2 HomeDirectory

Documents:保存应用运行时生成的需要持久化的数据,iTunes同步设备时会备份该目录。例如,游戏应用可将游戏存档保存在该目录


tmp:保存应用运行时所需的临时数据,使用完毕后再将相应的文件从该目录删除。应用没有运行时,系统也可能会清除该目录下的文件。iTunes同步设备时不会备份该目录


Library/Caches:保存应用运行时生成的需要持久化的数据,iTunes同步设备时不会备份该目录。一般存储体积大、不需要备份的非重要数据


Library/Preference:保存应用的所有偏好设置,iOS的Settings(设置)应用会在该目录中查找应用的设置信息。iTunes同步设备时会备份该目录


2.3 获取沙盒路径

沙盒根目录NSHomeDirectory();

沙盒临时目录:NSTemporaryDirectory();


Library/Preferences:NSUserDefaults


    //1.获取沙盒中Documents文件夹的路径

    //第一种方式:

    NSString *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;    //NO, path = @"~/"(相对路径); YES 绝对路径

    NSLog(@"%@", documentPath);

    //第二种方式: (不建议采用,因为新版本的操作系统可能会修改目录名)

    NSString *homePath = NSHomeDirectory();
   
NSString *documentPath2 = [homePath stringByAppendingPathComponent:@"library/caches"];
   
NSLog(@"%@", documentPath2);
   
//2.获取应用程序包路径(.app)
   
NSLog(@"%@", [NSBundle mainBundle].resourcePath);


二、简单对象持久化

1、简单对象

NSString\NSArray\NSDictionary\NSData

使用writeToFile:方法,将数据存储为.plist文件

atomically参数为是否写入缓存

    //字符串

    NSString *string = @"I U";
   
//数组
   
NSArray *array = @[@"张三", @"李四", @"王五"];
   
//字典
   
NSDictionary *dictionary = @{@"name":@"张三", @"age":@"20", @"sex":@""};
   
//NSData
   
UIImage *image = [UIImage imageNamed:@"1.jpg"];
   
NSData *data = UIImageJPEGRepresentation(image, 1);
   
   
//1.拼接存储路径
   
NSString *strPath = [documentPath stringByAppendingPathComponent:@"string.txt"];
   
NSString *arrayPath = [documentPath stringByAppendingPathComponent:@"array.txt"];
   
NSString *dicPath   = [documentPath stringByAppendingPathComponent:@"dict.txt"];
   
NSString *dataPath  = [documentPath stringByAppendingPathComponent:@"data.txt"];
   
   
//2.写入文件
    [string
writeToFile:strPath atomically:YES encoding:NSUTF8StringEncoding error:nil];
    [array     
writeToFile:arrayPath   atomically:YES];
    [dictionary
writeToFile:dicPath     atomically:YES];
    [data      
writeToFile:dataPath    atomically:YES];
   
   
//3.读取文件内容
   
NSString *fileString = [NSString stringWithContentsOfFile:strPath encoding:NSUTF8StringEncoding error:nil];
   
NSArray      *fileArray = [NSArray      arrayWithContentsOfFile:arrayPath];
   
NSDictionary  *fileDict = [NSDictionary dictionaryWithContentsOfFile:dicPath];
   
NSData            *fileData = [NSData      dataWithContentsOfFile:dataPath];
   
   
NSLog(@"%@", fileString);
   
NSLog(@"%@", fileArray);
   
NSLog(@"%@", fileDict);

    NSLog(@"%@", fileData);

2、文件管理类:NSFileManager

2.1、功能

     NSFileManager使用defaultManager创建单例对象。可以创建文件夹,可以删除、移动、创建文件,判断文件是否存在。


2.2、使用

    //缓存文件夹所在路径
   
NSString *cachesPath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).lastObject;
   
NSLog(@"%@", cachesPath);


    //cachesPath路径下创建一个文件夹

    NSString *directoryPath = [cachesPath stringByAppendingPathComponent:@"path"];
   
NSFileManager *fileManager = [NSFileManager defaultManager];    //创建文件管理类单例对象
   
//根据路径创建文件夹
   
NSDictionary *fileDate = @{@"createTime":@"2015-9-9"};

    [fileManager createDirectoryAtPath:directoryPath withIntermediateDirectories:YES attributes:fileDate error:nil];

    //根据路径创建文件(只能写入NSData类型的数据)

    [fileManager createFileAtPath:directoryPath contents:data attributes:fileDate];

    //删除文件

    [fileManager removeItemAtPath:dicPath error:nil];   //删除~/documents/dict.txt

3、NSUserDefaults

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];   //单例
    [defaults
setValue:@"yfyfyfyfyfyfyfy" forKey:@"username"];

    [defaults setValue:@"123" forKey:@"password"];

    //注意:UserDefaults设置数据时,不是立即写入,而是根据时间戳定时地把缓存中的数据写入本地磁盘。所以调用了set方法之后数据有可能还没有写入磁盘应用程序就终止了。出现以上问题,可以通过调用synchornize方法强制写入到文件中

    [defaults synchronize];


    //读取

     NSString *name = [defaults valueForKey:@"username"];

    NSString *pwd = [defaults valueForKey:@"password"];

   



二、复杂对象持久化(NSKeyedArchiver)

1、复杂对象

     复杂对象是在Foundation框架内不存在的数据类,无法通过writeToFile写入到文件内,且至少包含一个实例对象。

     由于复杂对象无法通过writeToFile:方法写入文件,只能将复杂对象转化为NSData对象,再进行数据持久化。


2、NSCoding协议

@protocol NSCoding

- (void)encodeWithCoder:(NSCoder *)aCoder;

- (id)initWithCoder:(NSCoder *)aDecoder; // NS_DESIGNATED_INITIALIZER

@end


3、复杂对象写入文件

Person.h

//复杂对象归档 一:遵守NSCoding协议
@interface Person : NSObject<NSCoding>
@property (nonatomic, assign) NSInteger age;
@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) NSString *gender;

@end


Person.m

#import "Person.h"

@implementation Person  //实现NSCoding协议

#pragma mark -- 进行编码 --
- (void)encodeWithCoder:(NSCoder *)coder
{

//    [super encodeWithCode:coder]; 如果父类也遵守了NSCoding协议,确保继承的实例变量也能被编码,即也能被归档

    [coder encodeObject:self.name forKey:@"name"];

    [coder encodeInteger:self.age forKey:@"age"];
    [coder
encodeObject:self.gender forKey:@"gender"];

}

#pragma mark -- 进行解码 --

- (id)initWithCoder:(NSCoder *)aDecoder
{

//    self = [super initWithCoder:aDecoder]; 确保继承的实例变量也能被解码,即也能被恢复

   self = [super init];

    if (self) {
       
self.name = [aDecoder decodeObjectForKey:@"name"];
       
self.gender = [aDecoder decodeObjectForKey:@"gender"];
       
self.age = [aDecoder decodeIntegerForKey:@"age"];
    }
   
return self;

}

@end


ViewController.m

类方法进行编码\解码(只能归档一个对象):

    NSString *objPath = [cachesPath stringByAppendingPathComponent:@"person.txt"];

    [NSKeyedArchiver archiveRootObject:person toFile:objPath];

   

    Person *p2 = [NSKeyedUnarchiver unarchiveObjectWithFile:objPath];

实例方法(可以归档多个对象):

#pragma mark -- 对复杂对象进行持久化(归档\编码) --

//过程:(复杂对象->归档->NSData->writeToFile:)

    Person *person = [[Person alloc] init];
    person.
name = @"yf";
    person.
age = 20;
    person.
gender = @"man";
   
   
NSMutableData *mtData = [NSMutableData data];
   
//创建归档器
   
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:mtData];
   
//进行归档
    [archiver
encodeObject:person forKey:@"person"];
   
//***结束归档
    [archiver
finishEncoding];
   
//将归档之后的mtData写入文件
   
NSString *personPath = [cachesPath stringByAppendingPathComponent:@"person.txt"];
    [mtData
writeToFile:personPath atomically:YES];
   
NSLog(@"%@", personPath);

    NSLog(@"%@", mtData);


#pragma mark -- 从文件中读取复杂对象(反归档\恢复\解码) --
//过程:(读取文件(NSData)->反归档->复杂对象)
   
//读取
   
NSData *readData = [NSData dataWithContentsOfFile:personPath];
   
//创建反归档工具
   
NSKeyedUnarchiver *unArchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:readData];
   
//使用反归档工具对readData进行反归档

    Person *readPerson = [unArchiver decodeObjectForKey:@"person"];

4、使用NSKeyedArchive进行深复制

比如对一个Person对象进行深复制

// 临时存储person1的数据

NSData *data = [NSKeyedArchiver archivedDataWithRootObject:person1];

// 解析data,生成一个新的Person对象

Student *person2 = [NSKeyedUnarchiver unarchiveObjectWithData:data];

// 分别打印内存地址

NSLog(@"person1:0x%x", person1); // person1:0x7177a60

NSLog(@"person2:0x%x", person2); // person2:0x7177cf0




三、SQLite

1、常用SQL语句

  1、说明:创建数据库

  CREATE DATABASE database-name

  2、说明:删除数据库

  drop database dbname

  3、说明:备份sql server

  --- 创建 备份数据的 device

  USE master

  EXEC sp_addumpdevice 'disk', 'testBack', 'c:\mssql7backup\MyNwind_1.dat'

  --- 开始 备份

  BACKUP DATABASE pubs TO testBack

  4、说明:创建新表

  create table tabname(col1 type1 [not null] [primary key],col2 type2 [not null],..)

  根据已有的表创建新表:

  A:create table tab_new like tab_old (使用旧表创建新表)

  B:create table tab_new as select col1,col2… from tab_old definition only

  5、说明:删除新表

  drop table tabname

  6、说明:增加一个列

  Alter table tabname add column col type

  注:列增加后将不能删除。DB2中列加上后数据类型也不能改变,唯一能改变的是增加varchar类型的长度。

  7、说明:添加主键: Alter table tabname add primary key(col)

       说明:删除主键: Alter table tabname drop primary key(col)

  10、说明:几个简单的基本的sql语句

  选择:select * from table1 where 范围

  插入:insert into table1(field1,field2) values(value1,value2)

  删除:delete from table1 where 范围

  更新:update table1 set field1=value1 where 范围

  查找:select * from table1 where field1 like ’%value1%’ ---like的语法很精妙,查资料!

  排序:select * from table1 order by field1,field2 [desc]

  总数:select count as totalcount from table1

  求和:select sum(field1) as sumvalue from table1

  平均:select avg(field1) as avgvalue from table1

  最大:select max(field1) as maxvalue from table1

  最小:select min(field1) as minvalue from table1

以上内容摘自:

http://www.php100.com/html/webkaifa/database/Mysql/2012/0720/10713.html

2、iOS使用SQLite

     iOS操作SQLite需要用到动态库libsqlite3.0.dylib。在Build Phases->Link Binary With Libraries下,点击'+' ,输入sqlite之后添加libsqlite3.0.dylib。

     之后,在单例类DatabaseHandle中导入sqlite3.h即可

2.1、连接数据库(若不存在则创建)

1> 获取数据库路径

    NSString *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;

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

2> 连接数据库

    int result = sqlite3_open(dbPath.UTF8String, &_db);

_db为实例变量:

{    sqlite3 * _db;    }

2.2、关闭数据库连接

    int result = sqlite3_close( _db);

2.3、创建表

1> SQL语句-创建表

    //create table 表名(字段1 类型, 字段2 类型, ..., 字段n 类型)
   
NSString *createTable = @"CREATE TABLE students (\
    name TEXT,\
    number TEXT PRIMARY KEY,\

    age INTEGER, stu BLOB)";

2> 执行SQL语句

    char *errorMsg = NULL;
   
int result = sqlite3_exec(_db, createTable.UTF8String, NULL, NULL, &errorMsg);
   
if (result == SQLITE_OK) {
       
NSLog(@"创建表成功");

    }

2.4、插入、修改、删除数据

0> 打开数据库

1> 新建SQL语句

    NSString *insertSQL = @"insert into students(name, age, number, stu) values(?,?,?,?)";

2> 检查语法

    sqlite3_stmt *stmt = nil //跟随指针. 用来让sqlite3_step()执行编译完成的sql语句.sqlite3中并没有定义该类型指针, 是一个抽象类型(结构体指针)

    int result = sqlite3_prepare_v2(_db, insertSQL.UTF8String, -1, &stmt, NULL);

语法正确时:result == SQLITE_OK

3> 字段绑定值

     sqlite3_bind_?();

4> 执行编译好的sql语句.

     sqlite3_step(stmt);

5> 销毁之前sqlite3_prepare_v2()所检查通过的SQL语句(结束跟随指针)

     sqlite3_finalize(stmt);

6> 关闭数据库连接

2.5、查询

0> 打开数据库

1> 新建SQL语句

    NSString *selectSQL = @"select * from students";

2> 检查语法

    sqlite3_stmt *stmt = nil;   //跟随指针

    int result = sqlite3_prepare(_db, selectSQL.UTF8String, -1, &stmt, NULL);

3> 取字段下的值

首先,需要用stmt指针遍历:

     while (sqlite3_step(stmt)==SQLITE_ROW)

其次,取值:

     sqlite3_column_text(sqlite3_stmt *, int iCol);

     iCol代表第几列,从0开始

     NSString *name = [NSString stringWithUTF8String:(const char *)sqlite3_column_text(stmt, 0)];

当取出的数据为对象时,需要解码

     NSData *data = [NSData dataWithBytes:sqlite3_column_blob(stmt, 3) length:sqlite3_column_bytes(stmt, 3)];

     NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; 

     Student *stu = [unarchiver decodeObjectForKey:[NSString stringWithFormat:@"student%@",number]];

     [unarchiver finishDecoding];

4> 销毁跟随指针

     sqlite3_finalize(stmt);

5> 关闭数据库连接

3、Demo

Student.h

@interface Student : NSObject<NSCoding>
@property (nonatomic, retain) NSString *name;
@property (nonatomic, assign) int age;
@property (nonatomic, retain) NSString *number;

#pragma mark -- 自定义初始化方法 --
- (instancetype)initWithName:(NSString *)name number:(NSString *)number age:(int)age;

@end

Student.m

@implementation Student
- (
void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder
encodeObject:self.name forKey:@"name"];
    [aCoder
encodeObject:self.number forKey:@"number"];
    [aCoder
encodeInt:self.age forKey:@"age"];
}

- (
id)initWithCoder:(NSCoder *)aDecoder
{
   
self = [super init];
   
if (self) {
       
self.name = [aDecoder decodeObjectForKey:@"name"];
       
self.number = [aDecoder decodeObjectForKey:@"number"];
       
self.age = [aDecoder decodeIntForKey:@"age"];
    }
   
return self;
}

- (
instancetype)initWithName:(NSString *)name number:(NSString *)number age:(int)age
{
   
self = [super init];
   
if (self) {
       
self.name = name;
       
self.number = number;
       
self.age = age;
    }
   
return self;
}

@end

DataBaseHandle.h

@class Student;

@interface DataBaseHandle : NSObject
#pragma mark -- 获取单例对象 --
+ (instancetype)sharedInstance;

- (
void)createDB;

#pragma mark -- 插入信息 --
- (void)insertStudent:(Student *)student;

#pragma mark -- 根据学号修改 --
- (void)updateNameOfStudent:(NSString *)name byNumber:(NSString *)number;

#pragma mark -- 根据学号删除 --
- (void)deleteStudentByNumber:(NSString *)number;

#pragma mark -- 查询所有学生信息 --
- (NSArray *)selectAllStudents;

@end


DataBaseHandle.m

#import "DataBaseHandle.h"
#import
<sqlite3.h>
#import
"Student.h"

@interface DataBaseHandle ()
{
   
//表示的是数据库连接对象,对数据库中表的操作都基于这个连接.
   
sqlite3 * _db;
}
@end

@implementation DataBaseHandle
static DataBaseHandle *handle = nil;

+ (
instancetype)sharedInstance
{
   
@synchronized (self) {
       
if (!handle) {
           
handle = [[DataBaseHandle alloc] init];
        }
       
return handle;
    }
}

#pragma mark -- 连接数据库 --
- (void)createDB
{
   
//指定存放在沙盒中的数据库路径
   
NSString *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;
   
NSString *dbPath = [documentPath stringByAppendingPathComponent:@"student.db"];
   
NSLog(@"%@", dbPath);
   
//打开一个Sqlite数据库(若数据库已存在则创建)并且返回其数据库连接对象
   
int result = sqlite3_open(dbPath.UTF8String, &_db);
   
if (result == SQLITE_OK) {
       
NSLog(@"打开数据库成功!%d", result);
       
//创建表
        [
self createTable];
    }
else {
       
NSLog(@"打开数据库失败!%d", result);
    }
}

#pragma mark -- 创建表 --
- (void)createTable
{
   
//1.SQL语句-创建表
   
//create table 表名(字段1 类型, 字段2 类型, ..., 字段n 类型)
   
NSString *createTable = @"CREATE TABLE students (\
    name TEXT,\
    number TEXT PRIMARY KEY,\
    age INTEGER, stu BLOB)"
;
   
//2.执行sql语句
   
char *errorMsg = NULL;
   
int result = sqlite3_exec(_db, createTable.UTF8String, NULL, NULL, &errorMsg);
   
if (result == SQLITE_OK) {
       
NSLog(@"创建表成功");
    }
else {
       
NSLog(@"创建表失败%s", errorMsg);
    }
}

#pragma mark -- 关闭数据库连接 --
- (void)closeDB
{
   
int result = sqlite3_close(_db);
   
if (result == SQLITE_OK) {
       
NSLog(@"关闭连接成功");
    }
else {
       
NSLog(@"关闭连接失败!%d", result);
    }
}

- (
void)insertStudent:(Student *)student
{
    [
self createDB];
   
   
//1.SQL语句-插入数据
   
//insert into 表名(字段1, 字段2, ..., 字段n) values(value1, value2, ..., valuen)
   
NSString *insertSQL = @"insert into students(name, age, number, stu) values(?,?,?,?)";
   
   
sqlite3_stmt *stmt = nil //跟随指针. 用来让sqlite3_step()执行编译完成的sql语句. sqlite3中并没有定义该类型指针, 是一个抽象类型(结构体指针)
   
//2.检查语法
   
int result = sqlite3_prepare_v2(_db, insertSQL.UTF8String, -1, &stmt, NULL);
   
if (result == SQLITE_OK) {
       
//3.字段绑定值
//第二个参数从1开始,对应insertSQL中第i?;第三个参数表示绑定值大小,未知写-1
       
sqlite3_bind_text(stmt, 1, [student.name UTF8String], -1, NULL);
       
sqlite3_bind_int(stmt, 2, student.age);
       
sqlite3_bind_text(stmt, 3, student.number.UTF8String, -1, NULL);
       
       
//student实例需要编码后存储(转换为NSData)
       
NSMutableData *data = [NSMutableData data];
       
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
        [archiver
encodeObject:student forKey:[NSString stringWithFormat:@"student%@", student.number]];
        [archiver
finishEncoding];
       
       
sqlite3_bind_blob(stmt, 4, [data bytes], (int)[data length], NULL);
       
       
//4.执行编译好的sql语句. 如果执行insert, update, delete, 只需执行一次.
       
sqlite3_step(stmt);
       
    }
else {
       
NSLog(@"INSERT ERROR %d", result);
    }
   
//5.销毁之前sqlite3_prepare_v2()所检查通过的SQL语句(结束跟随指针)
   
sqlite3_finalize(stmt);
   
    [
self closeDB];
}

#pragma mark -- 修改信息 --
- (void)updateNameOfStudent:(NSString *)name byNumber:(NSString *)number
{
    [
self createDB];
   
   
//1.SQL语句-update
   
//update 表名 set 字段=? where 字段=?
   
NSString *updateSQL = @"update students set name= ? where number= ?";
   
//2.检查SQL语句是否合法
   
sqlite3_stmt *stmt = nil;    //跟随指针
   
int result = sqlite3_prepare(_db, updateSQL.UTF8String, -1, &stmt, NULL);
   
if (result == SQLITE_OK) {
       
//3.绑定
       
sqlite3_bind_text(stmt, 1, name.UTF8String, -1, NULL);
       
sqlite3_bind_text(stmt, 2, number.UTF8String, -1, NULL);
       
       
//4.执行
       
sqlite3_step(stmt);
       
    }
else {
       
NSLog(@"UPDATE ERROR!%d", result);
    }
   
//5.销毁
   
sqlite3_finalize(stmt);
   
   
    [
self closeDB];
}

#pragma mark -- 根据学号删除 --
- (void)deleteStudentByNumber:(NSString *)number
{
    [
self createDB];
   
   
//1.SQL语句-删除
   
//delete from 表名 where 字段=?
   
NSString *deleteSQL = @"delete from students where number=?";
   
   
//2.检查
   
sqlite3_stmt *stmt = nil;   //跟随指针
   
int result = sqlite3_prepare(_db, deleteSQL.UTF8String, -1, &stmt, NULL);
   
if (result == SQLITE_OK) {
       
//3.绑定
       
sqlite3_bind_text(stmt, 1, number.UTF8String, -1, NULL);
       
       
//4.执行
       
sqlite3_step(stmt);
       
    }
else {
       
NSLog(@"DELETE ERROR! %d", result);
    }
   
//结束跟随指针
   
sqlite3_finalize(stmt);
   
    [
self closeDB];
}

#pragma mark -- 查询所有学生信息 --
- (NSArray *)selectAllStudents
{
    [
self createDB];
   
//1.SQL语句-查询
   
//select 字段 from 表名 where 字段=?, 字段=?
   
NSString *selectSQL = @"select * from students";
   
   
//2.检查
   
sqlite3_stmt *stmt = nil;   //跟随指针
   
int result = sqlite3_prepare(_db, selectSQL.UTF8String, -1, &stmt, NULL);

   
NSMutableArray *stuArray = [NSMutableArray array];

   
if (result == SQLITE_OK) {
   
while (sqlite3_step(stmt)==SQLITE_ROW) {
           
//取字段下的值\
            sqlite3_column_text(sqlite3_stmt *, int iCol);\
            iCol
代表第几列,0开始
           
NSString *name = [NSString stringWithUTF8String:(const char *)sqlite3_column_text(stmt, 0)];
           
NSString *number = [NSString stringWithUTF8String:(const char *)sqlite3_column_text(stmt, 1)];
           
int age = sqlite3_column_int(stmt, 2);
           
           
//反归档(解码)
           
NSData *data = [NSData dataWithBytes:sqlite3_column_blob(stmt, 3)
                                         
length:sqlite3_column_bytes(stmt, 3)];
           
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
           
           
Student *stu = [unarchiver decodeObjectForKey:[NSString stringWithFormat:@"student%@",number]];
            [unarchiver
finishDecoding];
           
NSLog(@"%@ %@ %@ %d", stu.name, stu.number, stu, stu.age);
           
            [stuArray
addObject:stu];
        }
    }
   
sqlite3_finalize(stmt);
    [
self closeDB];
   
return stuArray;
}

@end


使用:

{

...

   Student *stu1 = [[Studentalloc] initWithName:@"YF"number:@"0000"age:23];

    Student *stu2 = [[Student alloc] initWithName:@"ss" number:@"0001" age:24];
   
    [
DBHANDLE insertStudent:stu1];
    [
DBHANDLE insertStudent:stu2];
   
    stu1.
name = @"yyask";
   
    [
DBHANDLE updateNameOfStudent:stu1.name byNumber:stu1.number];
   
//    [DBHANDLE deleteStudentByNumber:stu1.number];
   

    [DBHANDLE selectAllStudents];

...

}


转载于:https://my.oschina.net/zooyf/blog/504095

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值