BZObjectStore 1.3.13

BZObjectStore 1.3.13

测试已测试
语言语言 Obj-CObjective C
许可证 MIT
发布最后发布2014年12月

Takeshi Shimada维护。



  • BONZOO LLC

BZObjectStore 会自动将您的模型存储到 SQLite 表中,并为您的应用程序提供有用选项。

要求

  • iOS 5.0 或更高版本
  • OS X 10.8 或更高版本
  • ARC

特性

  • 易于使用
  • 将模型映射到 SQLite 表
  • 支持 NSObject、NSArray、NSDictionary、NSSet、NSOrderedSet 中的关系
  • 自动生成模式
  • 线程安全
  • 懒加载、单次更新和其他有用选项
  • 模型中不需要任何超级类
  • 支持 ActiveRecord
  • 支持 Parse.com

安装

BZObjectStore 可以使用 CocoaPods 进行安装。

pod 'BZObjectStore'
pod 'BZObjectStore/CoreLocation' // if needed
pod 'BZObjectStore/ActiveRecord' // if needed
pod 'BZObjectStore/Parse' // if needed

示例

#import "BZObjectStore.h"

NSError *error = nil;

// open datbase
BZObjectStore *os = [BZObjectStore openWithPath:@"database.sqlite" error:&error];

// save a object
[os saveObject:YOUROBJECT error:&error];

// close database
[os close];

处理后,您可以在控制台中找到 'database path=/XXXX/database.sqlite'。
使用您的 SQLite 工具打开此文件并检查表。

方法

假设您有类似下面的模型。

#import "BZObjectStore.h"

@interface SampleModel : NSObject
@property (nonatomic,strong) NSString *name;
@property (nonatomic,assign) NSInteger price;
@property (nonatomic,strong) SampleModel *sample;
@end

@implementation SampleModel
@end

SampleModel *sample1 = [[SampleModel alloc]init];
sample1.name = @"sample1";
sample1.price = 100;

SampleModel *sample2 = [[SampleModel alloc]init];
sample2.name = @"sample2";
sample2.price = 50;
sample2.sample = sample1;

打开数据库

#import "BZObjectStore.h"

NSError *error = nil;

// default path is NSLibraryDirectory
BZObjectStore *os = [BZObjectStore openWithPath:@"database.sqlite" error:&error];

// open in memory
BZObjectStore *os = [BZObjectStore openWithPath:nil error:&error];

保存对象

// save a object
[os saveObject:sample1 error:&error];

// save objects in array
[os saveObjects:@[sample1,sample2] error:&error];

获取对象

// fetch objects
NSArray *fetchObjects = [os fetchObjects:[SampleModel class] condition:nil error:&error];

// fetch latest data from database
SampleModel *latest = [os refreshObject:sample1 error:&error];

// fetch referencing objects
NSArray *referencingObjects = [os fetchReferencingObjectsTo:sample1 error:&error];

删除对象

// delete a object
[os deleteObject:sample1 error:&error];

// delete objects
[os deleteObjects:[SampleModel class] condition:nil error:&error];

// delete objects in array
[os deleteObject:@[sample1,sample2] error:&error];

按条件获取对象

BZObjectStoreConditionModel *fetchCondition = [BZObjectStoreConditionModel condition];
fetchCondition.sqlite.where = @"name = 'sample1' and price > 50";
fetchCondition.sqlite.orderBy = @"name desc";

NSArray *objects = [os fetchObjects:[SampleModel class] condition:fetchCondition error:&error];

按条件删除对象

BZObjectStoreConditionModel *deleteCondition = [BZObjectStoreConditionModel condition];
deleteCondition.sqlite.where = @"name = 'sample1'";

[os deleteObjects:[SampleModel class] condition:deleteCondition error:&error];

关闭数据库

// close database
[os close];

获取计数值

NSNumber *count = [os count:[SampleModel class] condition:nil error:&error];

获取最大值

NSNumber *max = [os max:@"price" class:[SampleModel class] condition:nil error:&error];

获取最小值

NSNumber *min = [os min:@"price" class:[SampleModel class] condition:nil error:&error];

获取总和值

NSNumber *sum = [os sum:@"price" class:[SampleModel class] condition:nil error:&error];

获取总值

NSNumber *total = [os total:@"price" class:[SampleModel class] condition:nil error:&error];

获取平均值

NSNumber *avg = [os avg:@"price" class:[SampleModel class] condition:nil error:&error];

事务

[os inTransaction:^(BZObjectStore *os, BOOL *rollback) {

    NSError *error = nil;
    [os saveObject:sample1 error:&error];
    [os saveObject:sample2 error:&error];

    // rollback if needed
    *rollback = YES;
}];

注册类

// Improve response time (Not required but recommended)
[os registerClass:[SampleModel class] error:&error];

注销类

[os unRegisterClass:[SampleModel class] error:&error];

条件模型

有三个类

  1. BZObjectStoreConditionModel - 此类包含以下类。您在需要时创建一个实例并将其设置到每个方法中。
  2. BZObjectStoreSQLiteConditionModel - SQLite条件。
  3. BZObjectStoreReferenceConditionModel - 引用对象条件。

BZObjectStoreConditionModel

// create insntance
BZObjectStoreConditionModel *condition = [BZObjectStoreConditionModel condition];

// access to BZObjectStoreSQLiteConditionModel
condition.sqlite.XXXXX

// access to BZObjectStoreReferenceConditionModel
condition.reference.XXXXX

BZObjectStoreSQLiteConditionModel

// where condition
condition.sqlite.where = @"name = ?";

// where parameters
condition.sqlite.parameters = @[@"sample1"];

// order By
condition.sqlite.orderBy = @"code desc";

// limit
condition.sqlite.limit = @20;

// offset
condition.sqlite.offset = @20;

BZObjectStoreReferenceConditionModel

// set object referencing from
condition.reference.from = sample1;

// no object referencing from
condition.reference.from = [NSNull null];

// set object referenced to
condition.reference.to = sample1;

// no object referenced to
condition.reference.from = [NSNull null];

选项

OSIdenticalAttribute

定义相同属性

#import "BZObjectStoreModelInterface.h"

@interface OrderModel : NSObject
@property (nonatomic,strong) NSString<OSIdenticalAttribute> *no;
@property (nonatomic,assign) NSArray *items;
@end

OSIgnoreAttribute

忽略属性

#import "BZObjectStoreModelInterface.h"

@interface OrderModel : NSObject
@property (nonatomic,strong) NSString<OSIdenticalAttribute> *no;
@property (nonatomic,assign) NSArray *items;
@property (nonatomic,assign) NSIndexPath<OSIgnoreAttribute> *indexPath;
@end

OSWeakReferenceAttribute

在删除对象时不删除关联对象。

#import "BZObjectStoreModelInterface.h"

@interface OrderModel : NSObject
@property (nonatomic,strong) NSString<OSIdenticalAttribute> *no;
@property (nonatomic,strong) NSArray<OSWeakReferenceAttribute> *items;
@end

@interface ItemModel : NSObject
@property (nonatomic,strong) NSString<OSIdenticalAttribute> *code;
@property (nonatomic,assign) NSInteger price;
@end

OSFetchOnRefreshingAttribute

仅在refreshObject方法中获取关联对象,在fetchObjects方法中不获取。

#import "BZObjectStoreModelInterface.h"

@interface NodeModel : NSObject
@property (nonatomic,strong) NSArray<OSFetchOnRefreshingAttribute> *children;
@end

OSNotUpdateIfValueIsNullAttribute

值是空时不要更新属性。

#import "BZObjectStoreModelInterface.h"

@interface ProfileModel : NSObject
@property (nonatomic,strong) NSString *name;
@property (nonatomic,strong) UIImage<OSNotUpdateIfValueIsNullAttribute> *image;
@end

OSOnceUpdateAttribute

只更新一次属性。

#import "BZObjectStoreModelInterface.h"

@interface ProfileModel : NSObject
@property (nonatomic,strong) NSString *name;
@property (nonatomic,strong) NSDate<OSOnceUpdateAttribute> *registAt;
@property (nonatomic,strong) NSDate *updateAt;
@end

OSIgnoreSuperClass

忽略父类属性

#import "BZObjectStoreModelInterface.h"

@interface OrderModel : NSObject
@property (nonatomic,strong) NSString *remarks;
@end

@interface DailyOrderModel : OrderModel<OSIgnoreSuperClass>
@property (nonatomic,strong) NSString *no;
@property (nonatomic,assign) NSArray *details;
@end

OSFullTextSearch3

使用sqlite的FTS3

#import "BZObjectStoreModelInterface.h"

@interface Address : NSObject<OSFullTextSearch3>
@property (nonatomic,assign) NSString *address;
@end

OSFullTextSearch4

使用sqlite的FTS4

#import "BZObjectStoreModelInterface.h"

@interface Address : NSObject<OSFullTextSearch4>
@property (nonatomic,assign) NSString *address;
@end

OSInsertPerformance

优先插入性能

#import "BZObjectStoreModelInterface.h"

@interface LogModel : NSObject<OSInsertPerformance>
@property (nonatomic,assign) NSString *code;
@property (nonatomic,assign) NSString *description;
@end

OSUpdatePerformance

优先更新性能

#import "BZObjectStoreModelInterface.h"

@interface ProfileModel : NSObject<OSUpdatePerformance>
@property (nonatomic,assign) NSString *name;
@end

如果是原始类型,请改在您的模型中覆盖attributeIsXXXX方法而不是这些选项。
这些方法定义在OSModelInterface协议中。

OSModelInterface

该接口提供了额外功能。
导入BZObjectStoreModelInterface.h文件,在您的模型中实现OSModelInterface协议,并覆盖您需要的方法。
并覆盖您需要的方法。

更改表名

+ (NSString*)OSTableName
{
    return @"table_name_you_want";
}

更改列名

+ (NSString*)OSColumnName:(NSString*)attributeName
{
    if ([attributeName isEqualToString:@"column_name_you_want_to_change"]) {
        return @"column_name_you_want";
    }
    return attributeName;
}

模型加载事件钩子。

- (void)OSModelDidLoad
{
    // your operation
}

模型保存事件钩子。

- (void)OSModelDidSave
{
    // your operation
}

模型删除事件钩子。

- (void)OSModelDidDelete
{
    // your operation
}

定义 OSIdenticalAttribute 选项

+ (BOOL)attributeIsOSIdenticalAttribute:(NSString*)attributeName
{
    if ([attributeName isEqualToString:@"foo"]) {
        return YES;
    }
    return NO;
}

定义 OSIgnoreAttribue 选项

+ (BOOL)attributeIsOSIgnoreAttribute:(NSString*)attributeName
{
    if ([attributeName isEqualToString:@"foo"]) {
        return YES;
    }
    return NO;
}

定义 OSWeakReferenceAttribute 选项

+ (BOOL)attributeIsOSWeakReferenceAttribute:(NSString*)attributeName
{
    if ([attributeName isEqualToString:@"foo"]) {
        return YES;
    }
    return NO;
}

定义 OSNotUpdateIfValueIsNullAttribute 选项

+ (BOOL)attributeIsOSNotUpdateIfValueIsNullAttribute:(NSString*)attributeName
{
    if ([attributeName isEqualToString:@"foo"]) {
        return YES;
    }
    return NO;
}

定义 OSSerializableAttribute 选项

+ (BOOL)attributeIsOSSerializableAttribute:(NSString*)attributeName
{
    if ([attributeName isEqualToString:@"foo"]) {
        return YES;
    }
    return NO;
}

定义 OSOnceUpdateAttribute 选项

+ (BOOL)attributeIsOSOnceUpdateAttribute:(NSString*)attributeName
{
    if ([attributeName isEqualToString:@"foo"]) {
        return YES;
    }
    return NO;
}

后台运行

可以使用后台进程方法。
导入 BZObjectStoreBackground.h 并调用每个方法名 + 'InBackground' 方法。

#import "BZObjectStore.h"

[os saveObjectInBackground:savedObject completionBlock:^(NSError *error) {
    if (!error) {
        // succeed
    } else {
        // failed
    }
}];

// refer BZObjectStoreBackground.h about other methods

数据类型

Objective-C 和 C 数据类型 SQLite 数据类型 映射列名 备注
char* INTEGER attributeName
short INTEGER attributeName
int INTEGER attributeName
long INTEGER attributeName
long long INTEGER attributeName
double REAL attributeName
float REAL attributeName
unsigned char* INTEGER attributeName
unsigned short INTEGER attributeName
unsigned int INTEGER attributeName
unsigned long INTEGER attributeName
NSInteger INTEGER attributeName
CGFloat REAL attributeName
CGPoint REAL attributeName + '_x',+ '_y' 分为两列
CGSize REAL attributeName + '_width',+ '_height' 分为两列
CGRect REAL attributeName + '_x', + '_y', + '_width', + '_height' 分为四列
NSRange INTEGER attributeName + '_length', + '_location' 分为两列
NSDate REAL attributeName 保存为 Unix 时间
NSData BLOB attributeName
NSString TEXT attributeName
NSMutableString TEXT attributeName
NSNull BLOB attributeName 保存为 null
NSNumber INTEGER attributeName 保存为原始值
NSURL TEXT attributeName 保存为绝对 URL 字符串
NSValue BLOB attributeName 保存为序列化数据
UIColor TEXT attributeName 保存为 RGBA 字符串
UIImage BLOB attributeName 保存为 GIF 二进制数据
NSArray INTEGER attributeName
NSDictionary INTEGER attributeName
NSSet INTEGER attributeName
NSOrderedSet INTEGER attributeName
NSMutableArray INTEGER attributeName
NSMutableDictionary INTEGER attributeName
NSMutableSet INTEGER attributeName
NSMutableOrderedSet INTEGER attributeName
NSObject INTEGER attributeName
ID NONE attributeName,attributeName + '_attributeType' 分为两列
CLLocationCoordinate2D REAL attributeName + '_latitude',+ '_longitude' 分为两列
CLLocation REAL attributeName + '_altitude',+ '_latitude',+ '_longitude',+ '_course',+ '_horizontalAccuracy',+ '_speed',+ '_timestamp',+ '_verticalAccuracy' 分为八列

其他 C 结构将保存为 NSValue。

关系

NSObject、NSArray、NSDictionary、NSSet、NSOrderedSet 中的对象将自动映射到 SQLite 表中。

ActiveRecord 支持

设置
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    BZObjectStore *os = [BZObjectStore openWithPath:@"database.sqlite" error:&error];
    [BZActiveRecord setupWithObjectStore:os];
}
在您的模型中导入NSObject-ActiveRecord.h
#import "NSObject-ActiveRecord.h"

@interface SampleModel : NSObject
@property (nonatomic,strong) NSString *name;
@property (nonatomic,assign) NSInteger price;
@property (nonatomic,strong) SampleModel *sample;
@end
@implementation SampleModel
@end
示例
- (void)foo
{
    NSError *error = nil;
    SampleModel *sample = [SampleModel alloc]init];
    [sample save:&error];
    NSArray *samples = [SampleModel fetchs:nil error:&error];
    [sample delete:&error];
}
如果您使用PFObject,请在您的模型中导入NSObject-ActiveRecordParse.h。
- (void)foo
{
    NSError *error = nil;
    SampleModel *sample = [SampleModel alloc]init];
    [sample OSSave:&error];
    NSArray *samples = [SampleModel OSFetchs:nil error:&error];
    [sample OSDelete:&error];
}

Parse支持

BZObjectStore支持以下Parse对象。

  • PFObject实现了PFSubclassing
  • PFUser
  • PFFile
  • PFGeoPoint
Parse数据类型 SQLite 数据类型 映射列名 备注
PFGeoPoint REAL attributeName + '_latitude',+ '_longitude' 分为两列
PFFile TEXT,BLOB attributeName + '_name',+ '_data' 分为两列

其他

迁移

// migrate database
[os migrate error:&error];

当仅向模型添加属性时,迁移将自动运行。所以不要运行'migrate'方法。

FMDatabaseQueue 和 FMDatabase

为了使用FMDatabaseQueue,请使用dbQueue属性。
#import "BZObjectStore.h"
#import "FMDatabaseQueue.h"
#import "FMDatabase.h"

- (void)foo
{
    BZObjectStore *os = [BZObjectStore openWithPath:@"database.sqlite" error:nil];
    FMDatabaseQueue *dbQueue = os.dbQueue;
    [dbQueue inDatabase:^(FMDatabase *db) {
        FMResultSet *rs = [db getTableSchema:@"SampleModel"];
        while (rs.next) {
            NSString *columnName = [rs stringForColumnIndex:1];
        }
        [rs close];
    }];
    [os close];
}
为了使用FMDatabase,请继承BZObjectStore类并重写以下方法。
#import "FMDatabase.h"

- (void)transactionDidBegin:(FMDatabase *)db
{
    // called when call fetch,delete,save methods 
}

- (void)transactionDidEnd:(FMDatabase *)db
{
    // called when call fetch,delete,save methods 
}

限制

  • 只读属性始终会被忽略。
  • 后台进程方法不能在inTransactionInBackground方法中使用。

MICS

作者:Shimada Takeshi
历史:[https://github.com/expensivegasprices/BZObjectStore/History.md](https://github.com/expensivegasprices/BZObjectStore/History.md)
灵感来自AFNetworkingJSONModelFMDB