JQFMDB, simple operation, thread safety, scalability

JQFMDB, simple operation, thread safety, scalability

JQFMDB features

  • Two package for FMDB
  • Thread safety
  • Simple operation, direct storage of Model and Dictionary
  • Strong expansibility
  • Support transaction operations
  • Do not invade any of your Model

Install JQFMDB


1. add `pod'JQFMDB'` in Podfile. 2. execute `pod install` or `pod update`. 3. import /< JQFMDB/JQFMDB.h/>.

Manual installation

1. Download all contents in the JQFMDB folder. 2. add JQFMDB.h (and JQFMDB.m) and FMDB (drag and drop) to your project. 3. import "JQFMDB.h"".

Usage method

Create database

Singleton method
  • + (instancetype) shareDatabase;
  • + (instancetype) shareDatabase: (NSString *) dbName;
  • + (instancetype) shareDatabase: (NSString) dbName path: (NSString) dbPath;

Create a database of single cases, if the use of shareDatabase to create a default, create a JQFMDB.sqlite in NSDocumentDirectory, but as long as the use of these three methods to create an arbitrary success after three can use any method to obtain the same instance name parameter free dbName database or nil
@ “Users.sqlite”, such as: if dbName = nil, dbName=@ JQFMDB.sqlite
dbPath “is the default database path, if dbPath = nil, the default path is NSDocumentDirectory

Create database JQFMDB *db = [JQFMDB / shareDatabase]; JQFMDB *db = [JQFMDB or shareDatabase:@ "test.sqlite"]; JQFMDB *db = [JQFMDB or shareDatabase:@ "test.sqlite" path:[NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES) lastObject]];
Init method
  • – – (instancetype) initWithDBName: (NSString *) dbName;
  • – – (instancetype) initWithDBName: (NSString) dbName path: (NSString) dbPath;

If you operate several databases, you can obtain different instances of the init method, with parameter descriptions ibid

Create table

Mode 1 (create table with Model)
//Person Person: NSObject @property (@interface nonatomic strong) NSString *name @property (nonatomic, strong); NSNumber *phoneNum; @property (nonatomic, strong) NSData *photoData; @property (nonatomic, assign) NSInteger luckyNum @property (nonatomic, assign); BOOL sex; @property (nonatomic assign, int age @property (nonatomic); float height; //float, assign) into 172.12 types will be 172.19995, when%.2f is equal to the original value of 172.12 @property (nonatomic, assign) double weight; / / in order to test in addition to the above types, the type is not involved in the construction of table @property (nonatomic, strong) NSDictionary (nonatomic, *testDic; @property NSArray *testArr; @property (strong) nonatomic, strong, NSError) *testError (nonatomic, strong); @property Person *testP; / / @end Create table > @ user '= table name, table field' Person ', valid attribute' [db ',' jq_createTable:@ ',' user ',' dicOrModel:[Person ',' class]]';
Mode two (create table with dictionary)
/ / create table @ "user" = table table name field dictionary key dictionary value, type "user" [db jq_createTable:@ dicOrModel:@{@ "name", "TEXT": @ @ @ "age": "INTEGER"}];

Insertion of additions and deletions

Whether you want to insert a model or dictionary is no problem, will receive and store intelligent
– (BOOL) jq_insertTable: (NSString *) tableName dicOrModel: (ID) parameters;
into a set of data, also supports the model and dictionary mixed array
(NSArray) jq_insertTable: (NSString) tableName dicOrModelArray: (NSArray * dicOrModelArray);

Insert a data
Person *person = [[Person alloc] init]; person.name = cleanmonkey; person.phoneNum = @ @ (18866668888); person.photoData UIImagePNGRepresentation ([UIImage imageNamed:@ = "bg.jpg"]); person.luckyNum = 7; person.sex = 0; person.age = 26; person.height = 172.12; person.weight = 120.4555; / / insert a data [db jq_insertTable:@ "user" dicOrModel:person] table user; or you can also be part of [db data jq_insertTable:@ "user" dicOrModel:@{@ "name" into the dictionary: @ "cleanmonkey", "phoneNum": @ @ (18866668888)}];
Insert a set of data
NSMutableArray *mArr [NSMutableArray for (int = arrayWithCapacity:0]; I = 0; I 3; < i++) {Person *person = [[Person alloc] init]; person.name [self = randomName]; person.phoneNum = @ (18866668888); person.photoData UIImagePNGRepresentation ([UIImage imageNamed:@ = "bg.jpg"]); person.luckyNum = 7; person.sex = arc4random (%2; person.age) = 26; person.height = 172.12; person.weight = 120.4555; [mArr addObject:person];} / / insert a set of data [db jq_insertTable:@ "user" dicOrModelArray:mArr] to the user table; / / or it can be model and DIC mixed form of an array of [db jq_insertTable:@ "user" dicOrModelArray:@[person, @{@ "name": "cleanmonkey"}, @ person]]
Asynchronous (non blocking main thread) to insert data, can think or feel the asynchronous package not too good in JQFMDB.
/ / asynchronous (to prevent the insertion of a UI card dead) data, also can use the method of thread safe (inserted in jq_inDatabase block (dispatch_async) dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{[db jq_insertTable:@ "user" dicOrModel:person];});

Delete additions and deletions to check

According to the statement you want to delete delete data
– (BOOL) jq_deleteTable: (NSString) tableName whereFormat: (NSString) format,
…; delete all data in the
table (BOOL) – jq_deleteAllDataFromTable: (NSString * tableName);

Delete specified data
Delete the last data [db / jq_deleteTable:@ "user" whereFormat:@ "WHERE (SELECT ROWID = max (ROWID) FROM user)"];
Delete all data in the table
Delete all data [db / / jq_deleteAllDataFromTable:@ "user"];

Renewal of additions and deletions

Parameters to update the data, can be model or dictionary, format
(BOOL) – conditional jq_updateTable: (NSString) tableName dicOrModel: (ID) parameters whereFormat: (NSString) format,…;

Update specified data
Finally, a name=testName / / update data, the parameters of the dicOrModel can also be name testName person [db jq_updateTable:@ "user" dicOrModel:@{@ "name": @ "testName"} "WHERE ROWID = whereFormat:@ (SELECT Max FROM user (ROWID))"];
Update all data
The table / / all name into godlike [db jq_updateTable:@ "user" dicOrModel:@{@ "name": "godlike"} @ whereFormat:nil];

Search for additions and deletions

Parameters to find the model for each data to deposit the data, can be model or dictionary –
(NSArray) jq_lookupTable: (NSString) tableName dicOrModel: (ID) parameters whereFormat: (NSString * format),…;

Find specified data
NSArray *personArr = [db jq_lookupTable:@ "user" dicOrModel:[Person class] whereFormat:@ "where name ='cleanmonkey'/ name=cleanmonkey] data search; NSLog (@" name=cleanmonkey:%@ ", personArr);
Find data in all tables
All the data in the lookup table / / NSArray = *personArr [db jq_lookupTable:@ "user" dicOrModel:[Person class] whereFormat:nil]; NSLog (@ "table of all data:% @", personArr);

Thread safety for multithreaded operations

The above operation is not thread safe, to ensure the security thread, or the prototype of FMDB, all operations are put in execution in the following block, and the block block code will be submitted to a queue, so as to ensure thread safety, but it is important to note that block cannot be nested

The statement in block / * * operation to ensure thread safety, such as: Person *p = [[Person alloc] init]; p.name = @ "Li"; [jqdb jq_inDatabase:^{[jqdb jq_insertTable:@ "users" dicOrModel:p];}]; * / - (void) jq_inDatabase: (void (^) (void)) block;
Example: placing a set of operations in block guarantees thread safety
[db jq_inDatabase:^{[db jq_insertTable:@ "user" dicOrModel:@{@ "name": @ "cleanmonkey"}]; [db jq_lookupTable:@ "user" dicOrModel:[Person class] whereFormat:@ "where name ='cleanmonkey'"}]];

Using A B to transfer 100 yuan to the problem this simple transaction, first check balances, A if > =100 yuan, then the A account to minus 100 yuan, then the balance of query B accounts, B accounts plus 100 yuan, if in between any part of the problem (the balance is not enough, minus 100 yuan or A query operation failed B query or plus 100 yuan), then rollback operation failed operation, equivalent to return to the state before operation, simply said, this is a business operation

Transaction operations are also very simple and can be done in the following block
Person *p alloc] init] / * * = [[Person; p.name = @ "Li"; for (int i=0, I 1000, < i++) {[jq jq_inTransaction:^ (BOOL *rollback) {BOOL flag = [jq jq_insertTable:@ users dicOrModel:p]; if (! Flag) {*rollback = YES; / / as long as there is a time not successful, then for rollback return;}} * / / /}]; method of transaction operation - (void) jq_inTransaction: (void (^) (BOOL *rollback)) block;



The Demo (usage notes are very detailed) and JQFMDB have been placed on my GitHub, more functions will be updated, if you feel useful, help a point of star, thank you very much!

Screenshot of JQFMDB, simple operation, thread safety, scalability

What should I write here?