盲人摸象——iOS简单应用ToDoList之sqlite数据本地化

最近花两天学习sqlite的简单应用,加到ToDolist中,然后搬运到github上面。
github 地址:
git@github.com:RootChen/ToDoList.git

设置文件路径

sqlite实现数据增删查改,存储在本地。那么存储在本地哪里呢?这就需要我们设置文件路径了:

- (NSString *)filePath {
    NSString *filePath = [NSHomeDirectory() stringByAppendingFormat:@"/Documents/%@",kFilename];
    return filePath;
}

这里设置的是一个相对路径,sqlite的表数据就存储在这个路径里。

创建表

设置好文件相对路径之后我们要进行sqlite的基本操作,第一步就是创建表:

- (void)createTable:(NSString *)sql {
    sqlite3 *sqlite = nil;
    //打开数据库
    if (sqlite3_open([self.filePath UTF8String], &sqlite) != SQLITE_OK) {
        NSLog(@"打开数据库失败");
        sqlite3_close(sqlite);
        return;
    }

    //执行创建表SQL语句
    char *errmsg = nil;
    if (sqlite3_exec(sqlite, [sql UTF8String], NULL, NULL, &errmsg) != SQLITE_OK) {
        NSLog(@"创建表失败:%s",errmsg);
        sqlite3_close(sqlite);
    }
    NSLog(@"创建表成功");
    //关闭数据库
    sqlite3_close(sqlite);

}

这个方法的输入参数是 NSString 类型的 sql,是指传入一句sql语句,根据 ToDOList 的每一项任务数据包含的内容:任务内容、任务标记、任务创建时间,我们这样调用 - (void)createTable:(NSString *)sql 方法:

- (void)createTable {
    NSString *sql = @"CREATE TABLE IF NOT EXISTS Task (content TEXT,isMark TEXT,date TEXT primary key);";
    [self createTable:sql];
}

可以把任务创建时间当做任务数据的 id,因为每一项任务的创建时间是唯一的。

sqlite的操作抽象出两个类

创建之后会有插入(增)、删除、查找、修改数据的操作,跟创建操作有一个共同之处,就是有 sqlite对应的基本操作的方法,调用方法时插入相关的 sql 语句,所以上述的 - (void)createTable:(NSString *)sql 方法连同增删改查的基本操作我们可以写在一个类 BaseDB中,可以在其他工程中重用,而调用基本操作的方法与业务数据相关,不具备好的重用性,所以将 - (void)createTable等方法写在类 TaskDb 中。

表数据处理的基本操作

/**
 * 接口描述:插入数据、删除数据、修改数据
 * 参数:  sql: SQL语句
 * 返回值:是否执行成功
 *
 */
- (BOOL)dealData:(NSString *)sql paramsarray:(NSArray *)params {
    sqlite3 *sqlite = nil;
    sqlite3_stmt *stmt = nil;

    //打开数据库
    if (sqlite3_open([self.filePath UTF8String], &sqlite) != SQLITE_OK) {
        NSLog(@"打开数据库失败");
        sqlite3_close(sqlite);
        return NO;
    }

    //编译SQL语句
    if (sqlite3_prepare_v2(sqlite, [sql UTF8String], -1, &stmt, NULL) != SQLITE_OK) {
        NSLog(@"SQL语句编译失败");
        sqlite3_close(sqlite);
        return NO;
    }

    //绑定数据
    for (int i=0; i<params.count; i++) {
        NSString *value = [params objectAtIndex:i];
        sqlite3_bind_text(stmt, i+1, [value UTF8String], -1, NULL);
    }

    //执行SQL语句
    if(sqlite3_step(stmt) == SQLITE_ERROR) {
        NSLog(@"SQL语句执行失败");
        sqlite3_close(sqlite);
        return NO;        
    }

    //关闭数据库
    sqlite3_finalize(stmt);
    sqlite3_close(sqlite);

    return YES;
}

添加、删除、修改都是调用了- (BOOL)dealData:(NSString )sql paramsarray:(NSArray )params方法:

//增加一个任务
- (BOOL)addTask:(Task *)task {
    NSString *sql = @"INSERT INTO Task (content,isMark,date) VALUES (?,?,?)";

    NSArray *params = [NSArray arrayWithObjects:task.content,
                       [NSString stringWithFormat: @"%d",task.isMark],
                       [NSString stringWithFormat:@"%@", task.date], nil];

    return [self dealData:sql paramsarray:params];
}
//删除一个任务
- (BOOL)deleteTask:(Task *)task {
    NSString *sql = [NSString stringWithFormat:@"DELETE FROM Task WHERE date = '%@'", [NSString stringWithFormat:@"%@", task.date]];

    NSArray *params = [NSArray arrayWithObjects:task.content,
                       [NSString stringWithFormat: @"%d",task.isMark],
                       [NSString stringWithFormat:@"%@", task.date], nil];

    return [self dealData:sql paramsarray:params];
}
//更新一个任务的标记状态
- (BOOL)updateTask:(Task *)task {
    NSString *sql = [NSString stringWithFormat:@"UPDATE Task SET isMark = '%@' WHERE date = '%@' ",[NSString stringWithFormat: @"%d",task.isMark], [NSString stringWithFormat:@"%@", task.date]];
    NSArray *params = [NSArray arrayWithObjects:task.content,
                       [NSString stringWithFormat: @"%d",task.isMark],
                       [NSString stringWithFormat:@"%@", task.date], nil];

    return [self dealData:sql paramsarray:params];
}

一个删除导致添加有误的bug

BaseDB 这个类是无限互联3G学院的代码,对我等小白而言实在是赞,直接调用,上手容易。读懂代码以后,在BaseDB中单步调试,可以解决数据被覆盖等常见bug。
比如在删除一个任务的方法 - (BOOL)deleteTask:(Task *)task中,sql 语句 :

NSString *sql = [NSString stringWithFormat:@"DELETE FROM Task WHERE date = '%@'", [NSString stringWithFormat:@"%@", task.date]];

如果 @”DELETE FROM Task WHERE date = ‘%@’” 写成 @”DELETE FROM Task WHERE content = ‘%@’” ,那么你就无法添加多条内容相同的任务了,新建的任务会覆盖之前已经有的但是内容与它相同的任务。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值