工具:火狐浏览器+SQLite Manager插件 ; Xcode; FMDB库;
效果:
项目地址: https://github.com/sven713/PackFMDB
主要参考这两篇博客:
1. http://www.jianshu.com/p/dd170b1cbc3b iOS 基于FMDB简单封装
2. http://www.jianshu.com/p/54e74ce87404# FMDB的使用方法(附Demo)
使用步骤:
1.在工程中导入 libsqlite3.tdb
2.从GitHub下载FMDB库,拖到项目中(或者使用cocoaPods安装) https://github.com/ccgus/fmdb
3.新建一个类,用于封装FMDB,封装一层肯定比直接使用要好一点,但是我这项目没有封装好,还要再调整. 不封装的话就直接使用 FMDatabase 这个类了.
参考这个博客,http://www.jianshu.com/p/dd170b1cbc3b 只封装了下面一些简单的接口:
#import <Foundation/Foundation.h>
#import "FMDB.h"
/** 封装了FMDB的工具类 */ @interface FMDBHelp : NSObject @property (nonatomic, strong) FMDatabase *dataBase; //!<数据库对象 /** 支持外界自定义数据库文件名 @param dbName 自定义的数据库文件名 */ - (void)createDBWithName:(NSString *)dbName; /** 没有返回结果 @param sql sql语句 @return YES NO */ - (BOOL)noResultSetWithSql:(NSString *)sql; /** 有返回结果 @param sql sql @return 返回字典数组 */ - (NSArray<NSDictionary *> *)queryWithSql:(NSString *)sql; /** 单例 @return FMDBHelper */ +(instancetype)shareInstance; //- (void)insertTableName:(NSString *)tableName propertyKeyArray:(NSArray *)key value:(NSString *)values; /** *@brief 插入一個實體---参考HDF这个接口还不能用!!!!! *@param entity -要插入的實體,含有結果值的實體,設置用 *@return 操作成功與否 */ - (BOOL)insert:(id)entity tableName:(NSString *)tableName; @end
就 queryWithSql 这个方法用的比较多,封装的可以用, 另外就是建表的时候用的一下第一个方法 createDBWithName
最后一个方法参考老东家的代码,没整好,还不能用
总之,这个封装非常不完全,至少还要封装出增删改查四个接口
4.继承UITableViewController,用死数据搭建UI
5.在FMDBHelp类的基础上再封装一个工具类:PersonCarDataBaseHelper 人车数据库工具类, 所有控制器直接调用这个工具类的方法实现数据库的增删改查,这个类只能用于这个项目,其他项目还是要使用FMDB的API
PersonCarDataBaseHelper 接口如下:
#import <Foundation/Foundation.h> @class People; @class Car; /** 人车数据库工具类 */ @interface PersonCarDataBaseHelper : NSObject /** 添加人物------增 @param people 被加入的人物 */ - (void)addPerson:(People *)people; /** 获取人物列表----查 @return 人物列表数组 */ - (NSMutableArray *)getPersonArray; /** 删除人物-------删 @param person 被删除的人物 */ - (void)deletePerson:(People *)person; /** 删除某人的车---删 @param car 被删除的车 @param person 车所属的人 */ - (void)deletCar:(Car *)car owner:(People *)person; /** 向某人添加小车----增 @param car 新添加小车 @param person 车主 */ - (void)addCar:(Car *)car toPerson:(People *)person; /** 查询某人拥有的车-----查 @param person 谁的车 */ - (NSMutableArray *)getCarFromPerson:(People *)person; /** 修改person模型--改 @param people 被修改的person */ - (void)updatePerson:(People *)people; /** 两表关联查询----查 @return 查询结果数组 */ - (NSMutableArray *)queryTwoTable; +(instancetype)shareInstance; @end
倒数第二个接口, 两表关联查询----查 里面的Sql语句是写死的,应该再封装一下
6.增加人接口的实现:
先打开数据库,然后执行sql语句,最后再关闭数据库
直接调用FMDB的 - (BOOL)executeUpdate:(NSString*)sql, ...;这个方法(增)
- (void)addPerson:(People *)people { [[FMDBHelp shareInstance].dataBase open]; NSNumber *maxID = @(0); FMResultSet *res = [[FMDBHelp shareInstance].dataBase executeQuery:@"SELECT * FROM person "]; //获取数据库中最大的ID while ([res next]) { // 第一次循环没有next,不会走进去这个判断,maxID就是1 这个循环的作用就是拿到最后一个person_id,再加一,往后添加 if ([maxID integerValue] < [[res stringForColumn:@"person_id"] integerValue]) { // [res stringForColumn:@"person_id"]第一次是nil maxID = @([[res stringForColumn:@"person_id"] integerValue] ) ; // 如果maxID比personId小,就让maxID = personID person_id从1开始的? } } maxID = @([maxID integerValue] + 1); [[FMDBHelp shareInstance].dataBase executeUpdate:@"INSERT INTO person(person_id,person_name,person_age,person_updateTime)VALUES(?,?,?,?)",maxID,people.name,@(people.age),@(0)]; [[FMDBHelp shareInstance].dataBase close]; }
7.查询所有的人:
先打开数据库,然后执行sql语句,最后再关闭数据库
调用的自己封装的方法 queryWithSql(其实是封装的FMDB的 - (FMResultSet *)executeQuery:(NSString*)sql, ...;),对于不用传参数的,可以直接使用封装的方法,传入Sql语句就可以执行了,返回查询结果
- (NSMutableArray *)getPersonArray { NSArray *arr = [[FMDBHelp shareInstance] queryWithSql:@"SELECT * FROM person"]; NSMutableArray *resultArr = [NSMutableArray array]; for (NSDictionary *dict in arr) { People *person = [[People alloc]init]; person.name = [dict objectForKey:@"person_name"]; person.age = [[dict objectForKey:@"person_age"] integerValue]; person.ID = [dict objectForKey:@"person_id"]; // person_id-->maxID-->person.ID person.updateTime = [[dict objectForKey:@"person_updateTime"] integerValue]; [resultArr addObject:person]; } return resultArr; }
8.删除某个人:
直接调用FMDB的API - (BOOL)executeUpdate:(NSString*)sql, ...;
- (void)deletePerson:(People *)person { // 打开 [[FMDBHelp shareInstance].dataBase open]; // 执行 [[FMDBHelp shareInstance].dataBase executeUpdate:@"DELETE FROM person WHERE person_id = ?", person.ID]; // executeQuery不行 // 关闭 [[FMDBHelp shareInstance].dataBase close]; }
9. 修改某个人的年龄:
直接调用FMDB的API - (BOOL)executeUpdate:(NSString*)sql, ...;
- (void)updatePerson:(People *)people { FMDatabase *db = [FMDBHelp shareInstance].dataBase; [db open]; NSNumber *updateNum = @(people.updateTime + 1); [db executeUpdate:@"UPDATE 'person' SET person_updateTime = ? WHERE person_id = ?", updateNum, people.ID]; [db executeUpdate:@"UPDATE 'person' SET person_age = ? WHERE person_id = ?", @(people.age),people.ID]; [db close]; }
总结: 只有查询的时候用 - (FMResultSet *)executeQuery:(NSString*)sql, ...;
其他时候用 - (BOOL)executeUpdate:(NSString*)sql, ...;
10. 给某人增加车:
跟增加人类似,使用FMDB:- (BOOL)executeUpdate:(NSString*)sql, ...; 但是要先从人的表里面查出特定人的车
车的own_id = person.ID,将own_id跟person.ID关联
/**增加车*/ - (void)addCar:(Car *)car toPerson:(People *)person { FMDatabase *db = [FMDBHelp shareInstance].dataBase; [db open]; NSString *sql = [NSString stringWithFormat:@"SELECT * FROM car WHERE own_id = %@",person.ID]; FMResultSet *resultSet = [db executeQuery:sql]; NSInteger maxID = 0; while ([resultSet next]) { // while 写成了 if 循环就走一次,造成carID是相同 if (maxID < [resultSet stringForColumn:@"car_id"].integerValue) { maxID = [resultSet stringForColumn:@"car_id"].integerValue; } } maxID = maxID + 1; // NSNumber *max = [NSNumber numberWithInteger:maxID]; [db executeUpdate:@"INSERT INTO car(own_id,car_id,car_brand,car_price)VALUES(?,?,?,?)",person.ID,@(maxID),car.brand,@(car.price)]; // own_id == person_id car_id == maxID // maxID递增,car_id也递增 car_id作用类似person_id [db close]; }
11. 默认买车(增):
跟增加人类似,直接用FMDB API - (BOOL)executeUpdate:(NSString*)sql, ...; 但是要传查询人的id
12.查询某人拥有的车(查):
跟查询人类似,可以用封装的方法(里面是FMDB的 - (FMResultSet *)executeQuery:(NSString*)sql, ...;),但是sql语句要传查询人的id.
13.删除某人拥有的车(删):
跟删除人类似,直接用FMDB API - (BOOL)executeUpdate:(NSString*)sql, ...;, 要多传一个参数 person_id
14. 多表关联查询:
用自己封装的API [[FMDBHelp shareInstance]queryWithSql:sql]; 前提是写对传入的sql语句,person_id写死了,没有封装,只是用了一下
- (NSMutableArray *)queryTwoTable { NSMutableArray *arrMu = [NSMutableArray array]; NSString *sql = @"SELECT person.person_name,car.id,car.car_brand FROM car,person where car.own_id = person.id and person.id=1"; arrMu = [[[FMDBHelp shareInstance]queryWithSql:sql] copy]; return arrMu; }