天天看點

LKDBHelper的各種接口使用方式,及各種sql組合條件語句。

LKDBHelper 、FMDB的簡介。

在項目的開發過程中,我們大部分時候都需要對資料做一個持久化的操作,最典型的就是 IM 類型的項目,消息都要做儲存。 還有就是像個人重要的資訊,一般也會存本地,和伺服器做一個同步處理。 資料的持久化可以有多種方法。 這裡簡單講講 FMDB 、以及 基于FMDB 二次封裝,提供簡單接口的 LKDBHelper 第三方庫的使用。

LKDBHelper Git 位址 : https://github.com/li6185377/LKDBHelper-SQLite-ORM

部分接口整合,代碼。

隻要是繼承 NSObject  的類,都可以使用 LKDBHelper 的接口進行對 Model 的一個增删改查。 (可以建立一個 BaseModel 的基類,然後其他Model 都繼承于此,這樣方法統一管理 Model)

直接上代碼 :

1.先建立一個簡單的工程 ,再建立一個 LKModelTest 類。 (帶上各種類型的屬性)

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface LKModelTest : NSObject

@property (nonatomic, assign) int ID;

@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *nickName;
@property (nonatomic, assign) NSUInteger age;
@property (nonatomic, assign) BOOL isMan;

@property (nonatomic, strong) UIImage *image;
@property (nonatomic, strong) UIColor *color;
@property (nonatomic, strong) NSDate *date;
@property (nonatomic, strong) NSData *data;
@property (nonatomic, assign) CGFloat floatValue;
@property (nonatomic, assign) CGRect frame;
@property (nonatomic, assign) CGPoint point;
@property (nonatomic, assign) NSRange *range;

@end
           

.m 檔案這幾個方法需要實作下。

#import "LKModelTest.h"

@implementation LKModelTest

//重載、初始化單例、使用的LKDBHelper
+ (LKDBHelper *)getUsingLKDBHelper {
    
    static LKDBHelper* db;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        //DB 路徑
        NSString* DBPath = [NSHomeDirectory() stringByAppendingPathComponent:@"DB/DBTest.db"];
        NSLog(@"%@", DBPath);
        db = [[LKDBHelper alloc] initWithDBPath:DBPath];
    });
    return db;
}

//在類 初始化的時候
+ (void)initialize {

    //如果getTableMapping 傳回 nil, 會取全部屬性, 如果有不想要的屬性,可以使用
//    [self removePropertyWithColumnName:@"age"];
//    [self removePropertyWithColumnNameArray:@[@"age", @"name"]];
    
    //修改列名
//    [self setTableColumnName:@"MyAge" bindingPropertyName:@"age"];
    
    //手動設定關聯外鍵變量名
//    [self setUserCalculateForCN:@""];
}

+ (void)dbDidAlterTable:(LKDBHelper *)helper tableName:(NSString *)tableName addColumns:(NSArray *)columns {

    LKErrorLog(@"your know %@",columns);
}

// 将要插入資料庫
+ (BOOL)dbWillInsert:(NSObject *)entity {
    LKErrorLog(@"将要插入 : %@",NSStringFromClass(self));
    return YES;
}

//已經插入資料庫
+ (void)dbDidInserted:(NSObject *)entity result:(BOOL)result {
    LKErrorLog(@"已經插入 : %@",NSStringFromClass(self));
}

+ (BOOL)dbWillUpdate:(NSObject*)entity {
    LKErrorLog(@"将要更新 : %@",NSStringFromClass(self));
    return YES;
}

+ (void)dbDidUpdated:(NSObject*)entity result:(BOOL)result {
    LKErrorLog(@"已經更新 : %@",NSStringFromClass(self));
}

+ (BOOL)dbWillDelete:(NSObject*)entity {
    LKErrorLog(@"将要删除 : %@",NSStringFromClass(self));
    return YES;
}

+ (void)dbDidDeleted:(NSObject*)entity result:(BOOL)result {
    LKErrorLog(@"已經删除 : %@",NSStringFromClass(self));
}

//手動or自動 綁定sql列
+ (NSDictionary *)getTableMapping {
    //傳回nil 就是自動綁定所有列名
    return nil;
    
//    return @{@"age":@"Myage"};
}

//主鍵
+ (NSString *)getPrimaryKey {
    return @"ID";
}

///複合主鍵  這個優先級最高
//+(NSArray *)getPrimaryKeyUnionArray {
//    return @[@"name",@"age"];
//}

//表名
+ (NSString *)getTableName {
    return NSStringFromClass(self);
}

//是否将父實體類的屬性也映射到sqlite庫表
+ (BOOL)isContainParent {
    return YES;
}

@end
           
+ (NSDictionary *)getTableMapping;
           

這個方法是用來綁定目前表需要哪些列屬性的, 如果傳回 nil , 則預設綁定 Model 所有的屬性名,作為 列名。  如果有個别不想綁定進資料庫的,可以在 initialize 方法中,使用 [self removePropertyWithColumnName:@"列名"] ;     來進行移除,也可以手動修改個别你需要更改列名的列:

[self setTableColumnName:@"新列名" bindingPropertyName:@"原列名"];

如果你有兩張或者以上的表互相關聯,需要設定外鍵的話,可以在 initialize 方法中調這個方法:

[self setUserCalculateForCN:@"關聯的表,在目前屬性中建立的變量名"];

這個參數什麼意思? 比如: 有個A 類 和 B類 關聯。

那麼在 B 類的屬性中,就會建立一個這樣的屬性

@property (nonatomic, strong) A *thisAObj;

則在 B 的這個方法裡就要這麼寫:

[self setUserCalculateForCN:@"thisAObj"];

+ (NSString *)getTableName {
    return NSStringFromClass(self);
}
           

表也需要個表名, 是以這個方法 預設将 類名 作為 表名。

//主鍵
+ (NSString *)getPrimaryKey {
    return @"ID";
}

///複合主鍵  這個優先級最高
//+(NSArray *)getPrimaryKeyUnionArray {
//    return @[@"name",@"age"];
//}
           

一般情況下,你的Model資料也都會有一個唯一的值,這個值就可以來作為 主鍵, 主鍵的用途,後面再插入資料,或者删除,更改 都可以用來快速定位到某條資料條件,主鍵不能為空, 也不可能重複,如果你 儲存某條 資料進去,但是主鍵對應的資料已經存在,則會覆寫那條資料。 複合主鍵,相當于多個條件一起限制一條資料,這種情況适用于當一個主鍵不能滿足的時候。

//是否将父實體類的屬性也映射到sqlite庫表
+ (BOOL)isContainParent {
    return YES;
}
           

這個方法是設定 是否需要将父類的屬性 也一起綁定在表中。

Model 的方法大緻就這樣設定 基本上就行了。

接下來在 ViewController.m 中,開始使用資料庫存儲。

///擷取 LKTest 類使用的 LKDBHelper
    LKDBHelper *globalHelper = [LKModelTest getUsingLKDBHelper];
    [globalHelper dropAllTable];
    
    //清空表資料  clear table data
    [LKDBHelper clearTableData:[LKModelTest class]];
    
    LKModelTest *model = [LKModelTest new];
    model.name = @"張三1";
    model.nickName = @"馬蓉婊子";
    model.isMan = YES;
    
    model.image = [UIImage imageNamed:@"imageValue"];
    model.color = [UIColor blueColor];
    model.date = [NSDate new];
    model.data = [@"yutianlong9306" dataUsingEncoding:NSUTF8StringEncoding];
    model.floatValue = 3.1415926f;
    model.frame = CGRectMake(0, 0, 100, 100);
    model.point = CGPointMake(200, 200);    
    
    //插入5條資料
    for (int i = 1; i < 6 ; i++) {
        model.ID = i;
        model.age = 20 + i;
        [model saveToDB];
    }
           

先插入 5 條 Model 資料。

下面的代碼, 就是各種SQL 條件組合查詢語句 : (最後會附上Demo 下載下傳位址)

sleep(2);
    
    NSMutableArray *searchResultArray = nil;

    //同步搜尋 執行sql語句 把結果再變成對象 **************查詢操作*******
    
    // sql 1    查找表所有記錄
    NSString *sql1 = @"select * from LKModelTest";
    searchResultArray = [globalHelper searchWithSQL:sql1 toClass:[LKModelTest class]]; 
    
    addText(@"********** 查找表所有記錄 \n");
    
    for (id obj in searchResultArray) {
        addText(@"%@", [obj printAllPropertys]);
    }
    
    // sql 2    按條件查詢 (多條件)
    NSString *sql2 = @"select * from LKModelTest where name = '張三1' and age = 22";
    searchResultArray = [globalHelper search:[LKModelTest class] withSQL:sql2];
    
    
    addText(@"********** 按條件查詢 (多條件) \n");
    
    for (id obj in searchResultArray) {
        addText(@"%@", [obj printAllPropertys]);
    }
    
    // sql 3    條件使用動态參數 ? ,即接口傳進來的,search使用如下接口
    NSString *sql3 = @"select * from LKModelTest where name = ?";
    NSString *name = @"張三1";     //假設這個 name 是接口傳進來的 , 就可以有以下的寫法
    searchResultArray = [globalHelper search:[LKModelTest class] withSQL:sql3, name];
    
    
    addText(@"********** 條件使用動态參數 ? \n");

    for (id obj in searchResultArray) {
        addText(@"%@", [obj printAllPropertys]);
    }
    //*********************查詢操作************************************
    
    

    //使用對象對進查詢操作  orderBy 可以指定某個列倒叙查詢 offset是跳過多少行 count是查詢多少條(為0查詢所有)
    
    //  無條件查詢 10 條
    searchResultArray = [LKModelTest searchWithWhere:nil orderBy:nil offset:0 count:10];
    
    //  無條件查詢 某個列的值
    searchResultArray = [LKModelTest searchColumn:@"age" where:nil orderBy:nil offset:0 count:10];
    
    //  根據一個自增長的列,倒叙查詢 最新10條資料  (自增長的列可以是 自定義屬性ID,也可以是自帶的 rowid)
    searchResultArray = [LKModelTest searchWithWhere:nil orderBy:@"ID desc" offset:0 count:10];
    
    //  根據 and 條件 查詢所有資料
    NSString *conditions = @"age = 23 and name = '張三1'";
    searchResultArray = [LKModelTest searchWithWhere:conditions orderBy:nil offset:0 count:0];
    
    //  根據 字典條件,查詢所有資料
    NSDictionary *conditions1 = @{@"age" : @23, @"name" : @"張三1"};
    searchResultArray = [LKModelTest searchWithWhere:conditions1 orderBy:nil offset:0 count:0];
    
    //  根據 or 條件,查詢所有資料
    NSString *conditions2 = @"age = 23 or ID = 5";
    searchResultArray = [LKModelTest searchWithWhere:conditions2 orderBy:nil offset:0 count:0];
    
    //  根據 in 條件,查詢所有資料
    NSString *conditions3 = @"age in (23, 24)";
    searchResultArray = [LKModelTest searchWithWhere:conditions3 orderBy:nil offset:0 count:0];
    
    //  根據 字典 in 條件,查詢所有資料
    NSDictionary *conditions4 = @{@"age" : @[@23, @24]};
    searchResultArray = [LKModelTest searchWithWhere:conditions4 orderBy:nil offset:0 count:0];
    
    //  查詢符合條件的資料有多少條
    NSString *conditions5 = @"age = 23 and name = '張三1'";
    NSInteger rowCount = [LKModelTest rowCountWithWhere:conditions5];
    NSLog(@"%ld", rowCount);
    
    
    for (id obj in searchResultArray) {
        [obj printAllPropertys];
    }


    //*********************更新操作*********************************

    //  帶條件更新 , 一般來說,這種方式更新不需要where條件,因為會根據主鍵更新
    model.name = @"馬蓉 婊子";
    BOOL isUpdate1 = [globalHelper updateToDB:model where:nil];
    
    //  更新 通路表名 更新内容跟條件進行更新
    BOOL isUpdate2 = [globalHelper updateToDBWithTableName:@"LKModelTest" set:@"name = '馬蓉小婊砸'" where:@"age = 22"];
    
    //  根據 實類、條件進行更新
    BOOL isUpdate3 = [globalHelper updateToDB:[LKModelTest class] set:@"name = '馬蓉小畜生'" where:@"age = 23"];

    
        
    //*********************删除操作*********************************

    //  根據model 删除 ,兩種方式
    BOOL isDelete1 = [globalHelper deleteToDB:model];
    //or
    [model deleteToDB];
    

    //  根據條件,删除多條資料
    BOOL isDelete2 = [globalHelper deleteWithClass:[LKModelTest class] where:@"age >= 22 and age <= 24"];
           

Demo 會把部分 sql 執行接口列印在螢幕上,如果童鞋們 有需要列印其他資訊,調用 addText(@""); 方法即可。

列印資訊 :

LKDBHelper的各種接口使用方式,及各種sql組合條件語句。

Demo 下載下傳位址:

http://download.csdn.net/detail/yutianlong9306/9607446