iOS第三方类库之FMDatabase

FMDatabase 的使用方法

- (NSString*) getPath {

NSArray* paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) ;

return [[pathsobjectAtIndex:0]stringByAppendingPathComponent:@"MyTable"] ;

}

1.创建数据库

-(void)CreateTable;

{

dataBase = [FMDatabasedatabaseWithPath:[selfgetPath]];

if (![dataBase open])

NSLog(@"OPEN FAIL");

}

[dataBaseexecuteUpdate:@"CREATE TABLE IF NOT EXISTS MyTable(aa float,bb text,cc integer,dd integer,ee text)"];

[dataBaseclose];

}

2.查询数据

-(void)QueryData

{

//获取数据

recordArray = [[NSMutableArrayalloc]init];

db = [[FMDatabasealloc]initWithPath:[selfgetPath]];

if ([db open]) {

FMResultSet *rs = [dbexecuteQuery:@"SELECT * FROM MyTable"];

while ([rs next]){

OneRecord = [[OneRecord alloc]init];

OneRecord.aa = [NSNumbernumberWithFloat:[rs doubleForColumn:@"aa"]];

OneRecord.bb = [rs stringForColumn:@"bb"];

OneRecord.cc = [NSNumbernumberWithInt:[rs intForColumn:@"cc"]];

OneRecord.dd = [NSNumbernumberWithInt:[rs intForColumn:@"dd"]];

OneRecord.ee = [rs stringForColumn:@"ee"];

[recordArrayaddObject: OneRecord];

[OneRecordrelease];

}

[rs close];

[dbclose];

}

3.更新数据

-(void)UpdateData

{

if ([dbopen]) {

[dbbeginTransaction];

[dbexecuteUpdate:@"UPDATE MyTable SET aa = ? WHERE date = ?",aa1,aa2];

[dbexecuteUpdate:@"UPDATE MyTable SET bb = ? WHERE date = ?",bb1,bb2];

[dbexecuteUpdate:@"UPDATE MyTable SET cc = ? WHERE date = ?",cc1,cc2];

[dbexecuteUpdate:@"UPDATE MyTable SET dd = ? WHERE date = ?",dd1,dd2];

[dbcommit];

db close];

}

}

4。插入数据

-(void)insertData

{

//插入数据库

[dbbeginTransaction];

[dbexecuteUpdate:@"INSERT INTO MyTable (aa,bb,cc,dd,ee) VALUES (?,?,?,?,?)",

NSNumber numberWithFloat:aa],bb,cc,dd,ee];

db commit];

db close];

}

5。官方的使用方法为:

Usage

There are three main classes in FMDB:

  1. FMDatabase - Represents a single SQLite database. Used for executing SQL statements.
  2. FMResultSet - Represents the results of executing a query on anFMDatabase.
  3. FMDatabaseQueue - If you‘re wanting to perform queries and updates on multiple threads, you‘ll want to use this class. It‘s described in the "Thread Safety" section below.

Database Creation

An FMDatabase is created with a path to a SQLite database file. This path can be one of these three:

  1. A file system path. The file does not have to exist on disk. If it does not exist, it is created for you.
  2. An empty string (@""). An empty database is created at a temporary location. This database is deleted with theFMDatabase connection is closed.
  3. NULL. An in-memory database is created. This database will be destroyed with theFMDatabase connection is closed.

(For more information on temporary and in-memory databases, read the sqlite documentation on the subject:http://www.sqlite.org/inmemorydb.html)

FMDatabase *db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];

Opening

Before you can interact with the database, it must be opened. Opening fails if there are insufficient resources or permissions to open and/or create the database.

if (![db open]) {

[db release];

return;

}

Executing Updates

Any sort of SQL statement which is not a SELECT statement qualifies as an update. This includes CREATE,PRAGMA,UPDATE, INSERT, ALTER,COMMIT, BEGIN, DETACH,DELETE, DROP, END,EXPLAIN, VACUUM, and REPLACE statements (plus many more). Basically, if your SQL statement does not begin withSELECT, it is an update statement.

Executing updates returns a single value, a BOOL. A return value of YES means the update was successfully executed, and a return value of NO means that some error was encountered. If you use the -[FMDatabase executeUpdate:error:withArgumentsInArray:orVAList:] method to execute an update, you may supply anNSError ** that will be filled in if execution fails. Otherwise you may invoke the-lastErrorMessage and-lastErrorCode methods to retrieve more information.

Executing Queries

A SELECT statement is a query and is executed via one of the-executeQuery... methods.

Executing queries returns an FMResultSet object if successful, and nil upon failure. Like executing updates, there is a variant that accepts anNSError ** parameter. Otherwise you should use the-lastErrorMessage and-lastErrorCode methods to determine why a query failed.

In order to iterate through the results of your query, you use a while() loop. You also need to "step" from one record to the other. With FMDB, the easiest way to do that is like this:

FMResultSet *s = [db executeQuery:@"SELECT * FROM myTable"];

while ([s next]) {

//retrieve values for each record

}

You must always invoke -[FMResultSet next] before attempting to access the values returned in a query, even if you‘re only expecting one:

FMResultSet *s = [db executeQuery:@"SELECT COUNT(*) FROM myTable"];

if ([s next]) {

int totalCount = [s intForColumnIndex:0];

}

FMResultSet has many methods to retrieve data in an appropriate format:

  • intForColumn:
  • longForColumn:
  • longLongIntForColumn:
  • boolForColumn:
  • doubleForColumn:
  • stringForColumn:
  • dateForColumn:
  • dataForColumn:
  • dataNoCopyForColumn:
  • UTF8StringForColumnIndex:
  • objectForColumn:

Each of these methods also has a {type}ForColumnIndex: variant that is used to retrieve the data based on the position of the column in the results, as opposed to the column‘s name.

Typically, there‘s no need to -close an FMResultSet yourself, since that happens when either the result set is deallocated, or the parent database is closed.

Closing

When you have finished executing queries and updates on the database, you should -close the FMDatabaseconnection so that SQLite will relinquish any resources it has acquired during the course of its operation.

[db close];

Transactions

FMDatabase can begin and commit a transaction by invoking one of the appropriate methods or executing a begin/end transaction statement.

Data Sanitization

When providing a SQL statement to FMDB, you should not attempt to "sanitize" any values before insertion. Instead, you should use the standard SQLite binding syntax:

INSERT INTO myTable VALUES (?, ?, ?)

The ? character is recognized by SQLite as a placeholder for a value to be inserted. The execution methods all accept a variable number of arguments (or a representation of those arguments, such as anNSArray,NSDictionary, or ava_list), which are properly escaped for you.

Alternatively, you may use named parameters syntax:

INSERT INTO myTable VALUES (:id, :name, :value)

The parameters must start with a colon. SQLite itself supports other characters, but internally the Dictionary keys are prefixed with a colon, donot include the colon in your dictionary keys.

NSDictionary *argsDict = [NSDictionary dictionaryWithObjectsAndKeys:@"My Name", @"name", nil];

[db executeUpdate:@"INSERT INTO myTable (name) VALUES (:name)" withParameterDictionary:argsDict];

Thus, you SHOULD NOT do this (or anything like this):

[db executeUpdate:[NSString stringWithFormat:@"INSERT INTO myTable VALUES (%@)", @"this has \" lots of ‘ bizarre \" quotes ‘"]];

Instead, you SHOULD do:

[db executeUpdate:@"INSERT INTO myTable VALUES (?)", @"this has \" lots of ‘ bizarre \" quotes ‘"];

All arguments provided to the -executeUpdate: method (or any of the variants that accept a va_list as a parameter) must be objects. The following will not work (and will result in a crash):

[db executeUpdate:@"INSERT INTO myTable VALUES (?)", 42];

The proper way to insert a number is to box it in an NSNumber object:

[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:42]];

Alternatively, you can use the -execute*WithFormat: variant to use NSString-style substitution:

[db executeUpdateWithFormat:@"INSERT INTO myTable VALUES (%d)", 42];

Internally, the -execute*WithFormat: methods are properly boxing things for you. The following percent modifiers are recognized:%@, %c, %s,%d, %D, %i,%u, %U, %hi,%hu, %qi, %qu,%f, %g, %ld,%lu, %lld, and %llu. Using a modifier other than those will have unpredictable results. If, for some reason, you need the% character to appear in your SQL statement, you should use%%.

Using FMDatabaseQueue and Thread Safety.

Using a single instance of FMDatabase from multiple threads at once is a bad idea. It has always been OK to make a FMDatabase objectper thread. Just don‘t share a single instance across threads, and definitely not across multiple threads at the same time. Bad things will eventually happen and you‘ll eventually get something to crash, or maybe get an exception, or maybe meteorites will fall out of the sky and hit your Mac Pro. This would suck.

So don‘t instantiate a single FMDatabase object and use it across multiple threads.

Instead, use FMDatabaseQueue. It‘s your friend and it‘s here to help. Here‘s how to use it:

First, make your queue.

FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath];

Then use it like so:

[queue inDatabase:^(FMDatabase *db) {

[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]];

[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]];

[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]];

FMResultSet *rs = [db executeQuery:@"select * from foo"];

while ([rs next]) {

}

}];

An easy way to wrap things up in a transaction can be done like this:

[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {

[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]];

[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]];

[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]];

if (whoopsSomethingWrongHappened) {

*rollback = YES;

return;

}

// etc…

[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:4]];

}];

FMDatabaseQueue will make a serialized GCD queue in the background and execute the blocks you pass to the GCD queue. This means if you call your FMDatabaseQueue‘s methods from multiple threads at the same time GDC will execute them in the order they are received. This means queries and updates won‘t step on each other‘s toes, and every one is happy.

iOS第三方类库之FMDatabase

时间: 2024-10-29 00:09:17

iOS第三方类库之FMDatabase的相关文章

IOS第三方类库之ASIHTTPRequest

ASIHTTPRequest ASIHTTPRequest 是一个直接在CFNetwork上做的开源项目,提供了一个比官方更方便更强大的HTTP网络传输的封装.它的特色功能如下:1,下载的数据直接保存到内存或文件系统里2,提供直接提交(HTTP POST)文件的API3,可以直接访问与修改HTTP请求与响应HEADER4,轻松获取上传与下载的进度信息5,异步请求与队列,自动管理上传与下载队列管理机6,认证与授权的支持7,Cookie8,请求与响应的GZIP9,代理请求   下面来两个ASIHTT

iOS第三方类库之-SDWebImage使用

SDWebImage使用——一个可管理远程图片加载的类库 SDWebImage托管在github上.https://github.com/rs/SDWebImage 这个类库提供一个UIImageView类别以支持加载来自网络的远程图片. 具有缓存管理.异步下载.同一个URL下载次数控制和优化等特征. 将SDWebImage类库添加入工程时,一定注意需要添加MapKit.framework,如图所示,因为MKAnnotationView+WebCache.h依赖该framework. 使用示范的

iOS第三方类库之-GDataXMLNode

一.GDataXMLNode说明 GDataXMLNode是Google提供的用于XML数据处理的类集.该类集对libxml2--DOM处理方式进行了封装,能对较小或中等的xml文档进行读写操作且支持XPath语法. 使用方法: 1.获取GDataXMLNode.h/m文件,将GDataXMLNode.h/m文件添加到工程中 2.向工程中增加“libxml2.dylib”库 3.在工程的“Build Settings”页中找到“Header Search Path”项,添加/usr/includ

iOS第三方类库JSPatch(热更新)

原文地址: 一.前言 场景一:我们在做iOS开发的过程中,难免会由于自己的不细心导致一些小问题.如果产品没上线之前发现还好,如果上线了才发现问题,那么问题就大了,可能直接影响KPI,更严重的甚至直接面临着fire. 场景二.一旦上线的产品,如果临时遇到需求变动,那么久必须重新修改代码.一旦修改了项目代码的话,我们就必须重新发版.这样岂不是很麻烦? 现在就来让我们看一下JSPatch,它的出现可以在不发版的情况下动态的自行修复或者添加新的需求. 二.JSPatch简介 JSPatch:它是一个第三

【转】iOS开发常用的第三方类库

原文: http://blog.csdn.net/xiazailushang/article/details/9716043 在iOS开发中不可避免的会用到一些第三方类库,它们提供了很多实用的功能,使我们的开发变得更有效率:同时,也可以从它们的源代码中学习到很多有用的东西. Reachability 检测网络连接 用来检查网络连接是否可用:包括WIFI和WWAN(3G/EDGE/CDMA等)两种工作模式. 可以从Apple网站下载到:http://developer.apple.com/libr

iOS开发引入第三方类库的问题

在开发iOS程序的过程中,通常在导入第三方的类库(.a/.o)文件会报出一系列的错误: 看似缺少了某个类库文件,但多次检查之后发现,没缺少啥引用的,甚至跟原来的Demo一个都不差,这是怎么回事? 由于第三方类库多数是用C++或者C编写的,在引用过程中,还需要告诉编译器可能会出现的语言种类,以便使用对应的解释器进行解析. OK,那么我们只需要在XCode环境中检查以下几个配置项是否与下面一致即可: TARGETS->Build Settings,搜索 1.Other Linker Flags:-O

IOS网络编程——第三方类库

IOS网络编程——第三方类库 目录 概述 ASIHttpRequest AFNetworking 其他 概述 ASIHttpRequest AFNetworking 其他

【iOS开发-13】大神器:如何利用cocoapods使用第三方类库,以针对UISwitch的第三方类库为例

上一篇笔记以及之前部分笔记里面有些属性设置了没效果,比如UISwitch开关控件的开关背景图片:或者直接没有那种我们想要的属性,比如直接用代码设置控件大小. 所以,我们需要用第三方类库,意思大概是我们不用UISwitch类来实例化一个对象了,而是用第三方的类来实例化一个对象,然后这个对象可以进行各种修改随心所欲. 当然,这里的逻辑就是,我们要导入第三方类库,可能需要把它头文件神马的引入进来,然后就可以实例化,但是如何用第三方类库?cocoapods神器. 安装和使用教程如下:点击这里(相当齐全)

iOS 优化内存(七)开发中使用第三方类库

在iOS中使用第三方类库 方法一:直接复制所有源文件到项目中 这种方法就是把第三方类库的所有源文件复制到项目中,直接把所有.h和.m文件拖到XCode项目中即可.如果第三方类库引用了一些系统自带类库,那么在项目中还需要额外引用那些类库. 如果当前的项目启用了ARC,而引用的第三方类库未使用ARC,那还需要在项目信息的Targets – Build Parses里找到第三方类库的.m文件,并为它们加上-fno-objc-arc标记. 而对于在未启用ARC的项目用引用使用了ARC的第三方类库,则需要