做项目的过程中经常会遇到处理一些比较大而且比较固定的数据,比如汽车的品牌,型号,系列,或者是地区列表,这些数据都有一个共同的特点,那就是数据基本上不会发生太大的变化,而且数据量比较大,如果从请求服务器,会非常慢,性能非常差,所以就需要将其放到本地处理,一般我们会将地区制作成plist文件读取,但是对于汽车品牌数据量大的数据,这种做法就不适用了。这里提供一种比较方便的方法,就是找一个.db文件的资源,然后将其导入项目,使用FMDB对其进行操作。
SQLite是一个轻量级的关系数据库,iOS本身也是支持SQLite的,但是使用时非常不便,于是就出现了FMDB开源库,FMDB实际上是对SQLite API进行了进一步的封装,使用更加便捷,代码也比较清晰。在使用FMDB之前,首先要导入FMDB库,相信大家都已经会导第三方库了,所以在这里就不再赘述导库的过程,直接说说如何使用FMDB吧。
首先我们来认识一下FMDB中比较重要的三个类
1.FMDatabase
:是一个提供 SQLite 数据库的类,用于执行 SQL 语句。
2.FMResultSet
:用在 FMDatabase 中执行查询的结果的类。
3.FMDatabaseQueue
:在多线程下查询和更新数据库用到的类。
然后就是对数据库的相应的操作了,在对数据库操作之前,先给大家分享一个链接,便于随时查询SQLite语句,SQLite语句学习链接,好了,废话不多说,接下来就是对数据库的操作了。
对已经存在的数据库的操作
获取数据库的路径
NSString *path = [[NSBundle mainBundle] pathForResource:@"Vehicle_DICT (1)" ofType:@"db"];
创建执行SQLite数据库的类
FMDatabase *dataBase = [FMDatabase databaseWithPath:path];
打开数据库
[dataBase open];
执行查询操作
FMResultSet *result = [dataBase executeQuery:@"select distinct DVN_BRAND, DVN_BRAND_LOGO, DVN_BRAND_ENGLISH from DICT_VEHICLE_NEW order by DVN_BRAND_ENGLISH ASC;"];
while ([result next]) {
VehicledModel *model = [[VehicledModel alloc] init];
model.DVN_BRAND = [result objectForColumnName:@"DVN_BRAND"];
model.DVN_BRAND_ENGLISH = [result objectForColumnName:@"DVN_BRAND_ENGLISH"];
NSString *logoImage = [[result objectForColumnName:@"DVN_BRAND_LOGO"] stringByReplacingOccurrencesOfString:@"/Content/Images/carbrand/" withString:@""];
model.DVN_BRAND_LOGO = logoImage;
[self.dataSource addObject:model];
}
FMDB提供了如下几种方法来获取不同类型的数据
intForColumn:
longForColumn:
longLongIntForColumn:
boolForColumn:
doubleForColumn:
stringForColumn:
dateForColumn:
dataForColumn:
dataNoCopyForColumn:
UTF8StringForColumnIndex:
objectForColumn:
通常我们并不需要关闭FMResultSet
,因为FMResultSet
会随着相关数据库的关闭而自动关闭。
执行更新语句 SQLite更新语句
[dataBase executeUpdate:@"update dict_vehicle_new set dvn_brand = '凯瑞', dvn_brand_english = 'K'"];
执行插入语句SQLite插入语句
//1.executeUpdate:不确定的参数用?来占位(后面参数必须是oc对象,;代表语句结束)
[dataBase executeUpdate:@“INSERT INTO dict_vehicle_new (dvn_brand, dvn_brand_english) VALUES (?,?);”,'宝马','B'];
//2.executeUpdateWithForamat:不确定的参数用%@,%d等来占位 (参数为原始数据类型,执行语句不区分大小写)
[dataBase executeUpdateWithForamat:@“insert into dict_vehicle_new (dvn_brand, dvn_brand_english) values (%@,%@);”,'宝马','B]
//3.参数是数组的使用方式
[dataBase executeUpdate:@“INSERT INTO
dict_vehicle_new(dvn_brand, dvn_brand_english) VALUES (?,?);”withArgumentsInArray:@['宝马','B']];
执行删除语句SQLite删除语句
[dataBase executeUpdate:@“delete from dict_vehicle_new where dvn_brand = ?;”,'宝马'];
**FMDatabaseQueue **
FMDatabase
这个类线程是不安全的,如果在多个线程中同时使用一个FMDatabase
实例,会造成数据混乱等问题
为了保证线程安全,FMDB提供方便便捷的FMDatabaseQueue
FMDatabaseQueue 的创建
NSString *path = [[NSBundle mainBundle] pathForResource:@"Vehicle_DICT (1)" ofType:@"db"];
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:path];
简单使用
[queue inDatabase:^(FMDatabase *db) { [db executeUpdate:@"INSERT INTO dict_vehicle_new(dvn_brand) VALUES (?)", @"宝马"];
[db executeUpdate:@"INSERT INTO dict_vehicle_new(dvn_brand) VALUES (?)", @"保时捷"];
[db executeUpdate:@"INSERT INTO dict_vehicle_new(dvn_brand) VALUES (?)", @"福特"];
FMResultSet *rs = [db executeQuery:@"select * from dict_vehicle_new"];
while ([rs next]) {
// …
}
}];
使用事物
[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
db executeUpdate:@"INSERT INTO dict_vehicle_new(dvn_brand) VALUES (?)", @"宝马"];
[db executeUpdate:@"INSERT INTO dict_vehicle_new(dvn_brand) VALUES (?)", @"保时捷"];
[db executeUpdate:@"INSERT INTO dict_vehicle_new(dvn_brand) VALUES (?)", @"福特"];
FMResultSet *rs = [db executeQuery:@"select * from dict_vehicle_new"];
while ([rs next]) {
// …
}
}];
工具
为了查看sqlite中的数据,一个好的图形化数据库的管理工具是必不可少的,起初我使用的是SQLPro for SQLite Read-Only这个工具,但是后来发现这个工具是只读的,即只能执行查询操作,并不能进行增,删,更新操作,经同事推荐,现在使用DB Browser for Sqlite,这个工具能够实现增,删,改,查,使用也非常方便,如下图所示:
屏幕快照 2017-04-23 下午12.09.28.png
代码示例
我写了一个简单的demo,读取数据库汽车的品牌,型号,系列的例子,demo地址,如果有任何问题,可以私聊。如果哪里写的有问题,欢迎大神指正,小弟将不甚感激.
网友评论