盲人摸象——iOS简单应用ToDoList之sqlite数据本地化
2015-10-25 19:42
387 查看
最近花两天学习sqlite的简单应用,加到ToDolist中,然后搬运到github上面。
github 地址:
git@github.com:RootChen/ToDoList.git
这里设置的是一个相对路径,sqlite的表数据就存储在这个路径里。
这个方法的输入参数是 NSString 类型的 sql,是指传入一句sql语句,根据 ToDOList 的每一项任务数据包含的内容:任务内容、任务标记、任务创建时间,我们这样调用 - (void)createTable:(NSString *)sql 方法:
可以把任务创建时间当做任务数据的 id,因为每一项任务的创建时间是唯一的。
添加、删除、修改都是调用了- (BOOL)dealData:(NSString )sql paramsarray:(NSArray )params方法:
比如在删除一个任务的方法 - (BOOL)deleteTask:(Task *)task中,sql 语句 :
如果 @”DELETE FROM Task WHERE date = ‘%@’” 写成 @”DELETE FROM Task WHERE content = ‘%@’” ,那么你就无法添加多条内容相同的任务了,新建的任务会覆盖之前已经有的但是内容与它相同的任务。
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 = ‘%@’” ,那么你就无法添加多条内容相同的任务了,新建的任务会覆盖之前已经有的但是内容与它相同的任务。
相关文章推荐
- 关系型数据库
- mysql 学习记录(十六)--优化常用sql
- 数据库五个例子总结
- 数据库基础
- Oracle添加数据文件创建表空间,创建用户代码
- 常用SQL语句大全
- SQL语言的应用
- 数据库设计的步骤
- ORACLE建表练习
- 关于用 ZIP 包 安装 MySql 的详细步骤以及可能的错误
- 浅析数据库安全技术
- 我的django之旅(三)数据库和模型
- SQL中char、varchar、nvarchar的区别
- 使用 Oracle GoldenGate 在 Microsoft SQL Server 和 Oracle Database 之间复制事务
- 淘宝内部分享:怎么跳出MySQL的10个大坑
- java与mysql连接
- Mysql分页-Limit
- 学习数据库必须掌握的54条SQL查询语句
- mysql命令行下的编码转换查询
- oracle捕获异常和字符截取