FMDB操作 管理类封装

由于过年,好久没写了~


FMDB三方库 github地址:https://github.com/ccgus/fmdb

其实本质就是“字符串操作”,使用FMDatabase对象执行SQL语句** 就好了!

优点:不管项目中使用的是ARC,还是MRC,对FMDB的使用 都没有 任何影响,FMDB会在编译项目时进行自动匹配。


FMDB中三个重要的类:
FMDatabase:是一个提供 SQLite 数据库的类,用于执行** SQL 语句
FMResultSet:用在 FMDatabase 中执行查询的结果的类(FMDatabase
结果集)。
FMDatabaseQueue:在
多线程下** 查询更新数据库用到的类。


数据库的创建

FMDatabase是通过一个SQLite数据库文件 路径 创建的,其路径一般在以下三者之中:

  1. 一个文件的系统路径 →→→ 磁盘中可以不存在此文件,因为如果不存在会自动为你创建好。
  2. 一个空的字符串:@"" →→→ 会在临时位置创建一个空的数据库,当 FMDatabase 连接关闭时,该数据库会被删除。
  3. NULL →→→ 会在内存中创建一个数据库,当FMDatabase连接关闭时,该数据库亦会被销毁。

  // 创建数据库示例
  FMDatabase * _db = [FMDatabase databaseWithPath:@"/tmp/goyohol.db"];


配置操作:

导入FMDB三方库 ( 我是下载下来直接拖入的,简单粗暴~~~~~ )

FMDB操作 管理类封装_第1张图片
FMDB的导入

一推错误

FMDB操作 管理类封装_第2张图片
一片 红 .png

FMDB操作 管理类封装_第3张图片
在“Link Binary With Libraries”中加入 libsqlite3.tbd

只需加入“libsqlite3.tbd”依赖库,工程就可以运行了


当然!要是嫌麻烦的话,可以直接使用“CocoaPods”来导入~~



数据库 基本操作
//创建并且打开数据库
//数据库类对象 全局变量
FMDatabase * dataBase;


// 1.获取数据库对象
NSString * pathStr = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]; //路径自选
pathStr = [pathStr stringByAppendingPathComponent:@"goyohol.sqlite"];
// 创建数据库
dataBase = [FMDatabase databaseWithPath:pathStr];

// 2.打开数据库(若不存在,会创建并且打开)
BOOL open = [dataBase open];
if(open){  
    NSLog(@"dataBase open successfully");
}

//3.创建表
NSString * createTableStr = @"create table if not exists tab_user(id integer primary key,name varchar)";  // 简单粗暴地执行 SQL语句
//autoincrement修饰(id integer autoincrement primary key) 会报错:DB Error: 1 "near "autoincrement": syntax error"
//原因:SQLite不支持关键字AUTO_INCREMENT。
//在SQLite中,自增字段需要使用关键字INTEGER PRIMARY KEY

BOOL createtab_Succ = [dataBase executeUpdate:createTableStr];
if(createtab_Succ){
    NSLog(@"create table successfully");
}

//4.插入数据
NSString * insertSqlStr = @"insert into tab_user(id,name) values(?,?)"; 
// “?”,相当于OC里面的“%@”。

//    插入语句1
bool insert_Succ_1 = [dataBase executeUpdate:insertSqlStr,@(2),@"Hellen"];
//    插入语句2
bool insert_Succ_2 = [dataBase executeUpdate:insertSqlStr withArgumentsInArray:@[@(5),@"Amanda"] ];

//    插入语句3
bool insert_Succ_3 = [dataBase executeUpdateWithFormat:@"insert into tab_user(id,name) values(%d,%@)",6,@"Bob"];


//5.删除语句
NSString * deleteStr = @"delete from tab_user";
BOOL delete_Succ = [dataBase executeUpdate:deleteStr];
if(delete_Succ){
    NSLog(@"delete successfully");
}

//6.修改语句
NSString * updateStr = @"update tab_user set name=? ";
BOOL update_Succ =  [dataBase executeUpdate:updateStr,@"Jack"];
if(update_Succ){
    NSLog(@"update successfully");
}


//7.查询数据FMDB的FMResultSet,提供了多个方法来获取不同类型的数据
NSString * sqlStr = @" select * from tab_user ";
FMResultSet * result = [dataBase executeQuery:sqlStr];
while(result.next){  // 依次遍历FMResultSet

    int ids = [result intForColumn:@"id"];
    NSString * name = [result stringForColumn:@"name"];

    //int ids = [result intForColumnIndex:0];  //第1列
    //NSString * name = [result stringForColumnIndex:1];  //第2列
    NSLog(@"%@,%d",name,ids);     
}

效果:
产生的数据库:“goyohol.sqilte”文件。在沙盒路径中找到,使用“Navicat Premium”打开。

FMDB操作 管理类封装_第4张图片
打开“goyohol.sqilte”文件


Navicat Premium购买地址:https://www.navicat.com.cn/store/navicat-premium

FMDB操作 管理类封装_第5张图片
Navicat Premium


查看数据库里面的数据:
FMDB操作 管理类封装_第6张图片

FMDB操作 管理类封装_第7张图片
表中的数据




在应用中,若使用了多线程 操作数据库, 就需要使用FMDatabaseQueue来保证线程安全了。
应用中不可以 在多个线程中共同使用一个FMDatabase对象 操作数据库,否则会引起 数据库数据混乱

为了多线程 操作数据库安全,FMDB使用了FMDatabaseQueue:
首先用一个数据库文件地址来初使化FMDatabaseQueue;
然后就可以将一个 闭包(block) 传入inDatabase方法中。 在闭包操作 数据库,而不直接参与FMDatabase的管理。

多线程操作

//1.创建并且打开数据库(根据数据库的存储路径)
NSString *pathStr = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
pathStr = [pathStr stringByAppendingPathComponent:@"goyohol.sqlite"];
FMDatabaseQueue * queue = [FMDatabaseQueue databaseQueueWithPath:pathStr];

//2.创建表
[queue inDatabase:^(FMDatabase * db) {
    NSString * createStr = @"create table if not exists tab_book(id integer,name varchar)";
    BOOL createtab_Succ = [db executeUpdate:createStr];
    if(createtab_Succ ){
        NSLog(@"create table successfully");
    }
}];

//3.插入    (删除、修改 类似)
[queue inDatabase:^(FMDatabase *db) {
        NSString * insertSqlStr = @"insert into tab_book(id,name) values(?,?)";
    
      //插入语句
        bool insert_Succ = [db executeUpdate:insertSqlStr,@(2),@"Jane Eyre"];
       if(insert_Succ){
           NSLog(@"insert successfully");
       }
}];

//4.查询表
[queue inDatabase:^(FMDatabase *db) {
    FMResultSet * returnData = [db executeQuery:@" select * from tab_book "];
    
    while (returnData.next) {  // 依次遍历FMResultSet

        int ids = [returnData intForColumn:@"id"];
        NSString * name = [returnData stringForColumn:@"name"];
        NSLog(@"%@",name);
        NSLog(@"%i",ids);   
    }
}];

以上即是对FMDB的使用、操作。
接下来就进入主题吧!自定制一个 单例的数据库管理






自定制数据库 管理类

创建一个数据库单例管理类
并在单例管理类中导入“FMDB.h”,进行单例(数据库)管理类的书写

FMDB操作 管理类封装_第8张图片
数据库管理单例类 创建


“SqliteTool.h”文件里:

#import 

#import "FMDB.h"

@interface SqliteTool : NSObject
/**
 *  可以存储数据类型  text  integer  blob  boolean  date
 *  keyTypes      存储的字段  以及对应数据类型
 *  keyValues     存储的字段  以及对应的值
 */


/**
*  数据库工具单例
*
*  @return 数据库工具对象
*/
+(SqliteTool *)shareTool;


/**
 *  创建数据库
 *
 *  @param dbName 数据库名称(带后缀.sqlite)
 */
-(FMDatabase *)getDBWithDBName:(NSString *)dbName;



/**
 *  给指定数据库建表
 *
 *  @param db        指定数据库对象
 *  @param tableName 表的名称
 *  @param keyTypes   所含字段以及对应字段类型 字典
 */
-(void)DataBase:(FMDatabase *)db createTable:(NSString *)tableName keyTypes:(NSDictionary *)keyTypes;



/**
 *  给指定数据库的表添加值
 *
 *  @param db        数据库名称
 *  @param keyValues 字段及对应的值
 *  @param tableName 表名
 */
-(void)DataBase:(FMDatabase *)db insertKeyValues:(NSDictionary *)keyValues intoTable:(NSString *)tableName;


/**
 *  给指定数据库的表更新值
 *
 *  @param db        数据库名称
 *  @param keyValues 要更新字段及对应的值
 *  @param tableName 表名
 */
-(void)DataBase:(FMDatabase *)db updateTable:(NSString *)tableName setKeyValues:(NSDictionary *)keyValues;

/**
 *  条件更新
 *
 *  @param db        数据库名称
 *  @param tableName 表名称
 *  @param keyValues 要更新的字段及对应值
 *  @param condition 条件字典
 */
-(BOOL)DataBase:(FMDatabase *)db updateTable:(NSString *)tableName setKeyValues:(NSDictionary *)keyValues whereCondition:(NSDictionary *)condition;



#pragma mark --顺序查询 数据库表中的所有值(无限制全部 ⭐️升序⭐️)
/**
 *    按条件查询
 *
 *    @param db        数据库名称
 *    @param keyTypes  表名称
 *    @param tableName 要更新的字段及对应值
 *    @param colunm    要查询的类型  (顺序查询)
 *
 *    @return  数组
 */
-(NSArray *)SortAllInformationDataBase:(FMDatabase *)db selectKeyTypes:(NSDictionary *)keyTypes fromTable:(NSString *)tableName colunm:(NSString *)colunm;

#pragma mark --查询数据库表中的所有值(无限制全部)
/**
 *    按条件查询所有数据
 *
 *    @param db        数据库名称
 *    @param keyTypes  字典{数据格式及名称}
 *    @param tableName 表名
 *
 *    @return 数据返回数组
 */
-(NSArray *)AllInformationDataBase:(FMDatabase *)db selectKeyTypes:(NSDictionary *)keyTypes fromTable:(NSString *)tableName;

//按条件
-(NSArray *)AllInformationDataBase:(FMDatabase *)db selectKeyTypes:(NSDictionary *)keyTypes fromTable:(NSString *)tableName whereCondition:(NSDictionary *)condition;



/**
 *  查询数据库表中的所有值 限制数据条数10
 *
 *  @param db        数据库名称
 *  @param keyTypes 查询字段以及对应字段类型 字典
 *  @param tableName 表名称
 *  @return 查询得到数据
 */
-(NSArray *)DataBase:(FMDatabase *)db selectKeyTypes:(NSDictionary *)keyTypes fromTable:(NSString *)tableName;

/**
 *  条件查询数据库中的数据 限制数据条数10
 *
 *  @param db        数据库名称
 *  @param keyTypes 查询字段以及对应字段类型 字典
 *  @param tableName 表名称
 *  @param condition 条件
 *
 *  @return 查询得到数据 限制数据条数10
 */
-(NSArray *)DataBase:(FMDatabase *)db selectKeyTypes:(NSDictionary *)keyTypes fromTable:(NSString *)tableName whereCondition:(NSDictionary *)condition;


/**
 *  模糊查询 某字段以指定字符串开头的数据 限制数据条数10
 *
 *  @param db        数据库名称
 *  @param keyTypes 查询字段以及对应字段类型 字典
 *  @param tableName 表名称
 *  @param key       条件字段
 *  @param str       开头字符串
 *
 *  @return 查询所得数据 限制数据条数10
 */
-(NSArray *)DataBase:(FMDatabase *)db selectKeyTypes:(NSDictionary *)keyTypes fromTable:(NSString *)tableName whereKey:(NSString *)key beginWithStr:(NSString *)str;

/**
 *  模糊查询 某字段包含指定字符串的数据 限制数据条数10
 *
 *  @param db        数据库名称
 *  @param keyTypes 查询字段以及对应字段类型 字典
 *  @param tableName 表名称
 *  @param key       条件字段
 *  @param str       所包含的字符串
 *
 *  @return 查询所得数据
 */
-(NSArray *)DataBase:(FMDatabase *)db selectKeyTypes:(NSDictionary *)keyTypes fromTable:(NSString *)tableName whereKey:(NSString *)key containStr:(NSString *)str;

/**
 *  模糊查询 某字段以指定字符串结尾的数据 限制数据条数10
 *
 *  @param db        数据库名称
 *  @param keyTypes 查询字段以及对应字段类型 字典
 *  @param tableName 表名称
 *  @param key       条件字段
 *  @param str       结尾字符串
 *
 *  @return 查询所得数据
 */
-(NSArray *)DataBase:(FMDatabase *)db selectKeyTypes:(NSDictionary *)keyTypes fromTable:(NSString *)tableName whereKey:(NSString *)key endWithStr:(NSString *)str;


#pragma mark - 清除

/**
 *  清理指定数据库中的数据  (只删除数据不删除数据库)
 *
 *  @param db 指定数据库
 */
-(void)clearDatabase:(FMDatabase *)db from:(NSString *)tableName;

/**
 *  删除表
 */
-(void)dropTableFormDatabase:(FMDatabase *)db table:(NSString *)tableName;

/**
 *  删除指定表(数据库) 中的 单条数据          (单一指定条件)
 */
-(void)deleteOneDataFormDatabase:(FMDatabase *)db fromTable:(NSString *)tableName whereConditon:(NSDictionary *)condition;


#pragma mark - 查询
/**
 *  特定条件查integer
 */
- (NSInteger)DHSelectIntegerWithDB:(FMDatabase *)db table:(NSString *)table colunm:(NSString *)colunm  whereCondition:(NSDictionary *)conditon;
/**
 *  特定条件查text
 */
- (NSString *)DHSelectTextWithDB:(FMDatabase *)db table:(NSString *)table colunm:(NSString *)colunm whereCondition:(NSDictionary *)condition;
/**
 *  通过特定条件返回data数据
 *  @param conditon 字典:@{@"某行":@"值"}
 *
 *  @return data
 */
- (NSData *)DHSelectDataWithDB:(FMDatabase *)db table:(NSString *)table colunm:(NSString *)colunm  whereCondition:(NSDictionary *)conditon;

#pragma mark - 更新
/**
 *  特定条件更新,注意:***条件只有一个键值对***
 */
- (BOOL)DHUpdateWithDB:(FMDatabase *)db table:(NSString *)table
       setKeyValue:(NSDictionary *)keyValue
         condition:(NSDictionary *)condition;

#pragma mark - 判断是否存在
/**
 *  判断有没有该字段
 */
- (BOOL)DHisExistObjectInDataBase:(FMDatabase *)db fromTable:(NSString *)tableName colunm:(NSString *)colunm identify:(NSString *)identify;
/**
 *  判断有没有该字段,多个条件的
 */
- (BOOL)DHisExistObjectInDataBase:(FMDatabase *)db fromTable:(NSString *)tableName condition:(NSDictionary *)condition;
/**
 *  判断有没表
 */
- (BOOL)DHisExistTable:(NSString *)tableName DataBase:(FMDatabase *)db;


#pragma mark - other
/**
 *  查找最后一行
 */
- (NSArray *)DHLastLineDataBase:(FMDatabase *)db fromTable:(NSString *)tableName colunm:(NSString *)colunm;


@end






“SqliteTool.m”文件里面:

#import "SqliteTool.h"


static SqliteTool * tool = nil;

@implementation SqliteTool

+ (SqliteTool *)shareTool {

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (tool == nil) {
            tool = [[self alloc] init];
        }
    });
    return tool;
}

+(instancetype)allocWithZone:(struct _NSZone *)zone {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (tool == nil) {
            tool = [super allocWithZone:zone];
        }
    });
    return tool;
}






#pragma mark --创建数据库
-(FMDatabase *)getDBWithDBName:(NSString *)dbName
{
    NSArray *library = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);// 沙盒路径
    NSString *dbPath = [library[0] stringByAppendingPathComponent:dbName];
    FMDatabase *db = [FMDatabase databaseWithPath:dbPath];
    NSLog(@"sqlite地址-->%@",dbPath);
    if (![db open]) {
        NSLog(@"无法获取数据库");
        return nil;
    }
    return db;
}

#pragma mark --给指定数据库建表
-(void)DataBase:(FMDatabase *)db createTable:(NSString *)tableName keyTypes:(NSDictionary *)keyTypes
{
    if ([self isOpenDatabese:db]) {
        NSMutableString *sql = [[NSMutableString alloc] initWithString:[NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS %@ (id integer primary key,",tableName]];
        int count = 0;
        for (NSString *key in keyTypes) {
            count++;
            [sql appendString:key];
            [sql appendString:@" "];
            [sql appendString:[keyTypes valueForKey:key]];
            if (count != [keyTypes count]) {
                [sql appendString:@", "];
            }
        }
        [sql appendString:@")"];
        [db executeUpdate:sql];
    }
}

#pragma mark --给指定数据库的表添加值
-(void)DataBase:(FMDatabase *)db insertKeyValues:(NSDictionary *)keyValues intoTable:(NSString *)tableName
{
    if ([self isOpenDatabese:db]) {
    
        NSArray *keys = [keyValues allKeys];
        NSArray *values = [keyValues allValues];
        NSMutableString *sql = [[NSMutableString alloc] initWithString:[NSString stringWithFormat:@"INSERT INTO %@ (", tableName]];
        NSInteger count = 0;
        for (NSString *key in keys) {
            [sql appendString:key];
            count ++;
            if (count < [keys count]) {
                [sql appendString:@", "];
            }
        }
        [sql appendString:@") VALUES ("];
        for (int i = 0; i < [values count]; i++) {
            [sql appendString:@"?"];
            if (i < [values count] - 1) {
                [sql appendString:@","];
            }
        }
        [sql appendString:@")"];
    
        [db executeUpdate:sql withArgumentsInArray:values];
    }
}

#pragma mark --给指定数据库的表更新值
-(void)DataBase:(FMDatabase *)db updateTable:(NSString *)tableName setKeyValues:(NSDictionary *)keyValues
{
    if ([self isOpenDatabese:db]) {
        for (NSString *key in keyValues) {
            NSMutableString *sql = [[NSMutableString alloc] initWithString:[NSString stringWithFormat:@"UPDATE %@ SET %@ = ?", tableName, key]];
            [db executeUpdate:sql,[keyValues valueForKey:key]];
        }
    }
}

#pragma mark --条件更新,跟新data
- (BOOL)DataBase:(FMDatabase *)db updateTable:(NSString *)tableName setKeyValues:(NSDictionary *)keyValues whereCondition:(NSDictionary *)condition
{
    BOOL isSuccess = NO;
    NSInteger count = [condition allKeys].count;

    if ([self isOpenDatabese:db]) {
        if (count == 1) {
            for (NSString *key in keyValues) {
                NSMutableString *sql = [[NSMutableString alloc] initWithString:[NSString stringWithFormat:@"UPDATE %@ SET %@ = ? WHERE %@ = ?", tableName, key, [condition allKeys][0]]];
                isSuccess = [db executeUpdate:sql,[keyValues valueForKey:key],[condition valueForKey:[condition allKeys][0]]];
            }
        } else {
            for (NSString *key in keyValues) {
                int condition_count = 0;
                NSMutableArray *condition_valueArr = [NSMutableArray array];
                [condition_valueArr addObject:keyValues[key]];
                NSMutableString *sql = [NSMutableString stringWithFormat:@"update %@ set %@ = ? where ",tableName,key];
                for (NSString *condition_key in condition) {
                    condition_count ++;
                    if (condition_count == count) {
                        [sql appendFormat:@"%@ = ?",condition_key];
                    } else {
                        [sql appendFormat:@"%@ = ? and ",condition_key];
                    }
                    [condition_valueArr addObject:condition[condition_key]];
                }
                isSuccess = [db executeUpdate:sql withArgumentsInArray:condition_valueArr];
            }
        }
    }
    return isSuccess;
}



#pragma mark --顺序查询 数据库表中的所有值(无限制全部 ⭐️升序⭐️)
-(NSArray *)SortAllInformationDataBase:(FMDatabase *)db selectKeyTypes:(NSDictionary *)keyTypes fromTable:(NSString *)tableName colunm:(NSString *)colunm
{
    FMResultSet *result =  [db executeQuery:[NSString stringWithFormat:@"SELECT * FROM %@ ORDER BY %@ ASC",tableName,colunm] ];
    NSLog(@"---->%@",[NSString stringWithFormat:@"SELECT * FROM %@ sort",tableName]);
    return [self getArrWithFMResultSet:result keyTypes:keyTypes];
}

#pragma mark --查询数据库表中的所有值(⭐️无限制全部)
-(NSArray *)AllInformationDataBase:(FMDatabase *)db selectKeyTypes:(NSDictionary *)keyTypes fromTable:(NSString *)tableName
{
    FMResultSet *result =  [db executeQuery:[NSString stringWithFormat:@"SELECT * FROM %@",tableName]];
    NSLog(@"---->%@",[NSString stringWithFormat:@"SELECT * FROM %@",tableName]);
    return [self getArrWithFMResultSet:result keyTypes:keyTypes];
}

#pragma mark --条件查询数据库中 所有的数据   (无限制全部)
-(NSArray *)AllInformationDataBase:(FMDatabase *)db selectKeyTypes:(NSDictionary *)keyTypes fromTable:(NSString *)tableName whereCondition:(NSDictionary *)condition
{
    if ([self isOpenDatabese:db]) {
    
        FMResultSet *result =  [db executeQuery:[NSString stringWithFormat:@"SELECT * FROM %@ WHERE %@ = ?",tableName, [condition allKeys][0]], [condition valueForKey:[condition allKeys][0]]];
        return [self getArrWithFMResultSet:result keyTypes:keyTypes];
    }else
        return nil;
}





#pragma mark --查询数据库表中的所有值  (限制数据条数:10)
-(NSArray *)DataBase:(FMDatabase *)db selectKeyTypes:(NSDictionary *)keyTypes fromTable:(NSString *)tableName
{
    FMResultSet *result =  [db executeQuery:[NSString stringWithFormat:@"SELECT * FROM %@ LIMIT 10",tableName]];
    NSLog(@"---->%@",[NSString stringWithFormat:@"SELECT * FROM %@ LIMIT 10",tableName]);
    return [self getArrWithFMResultSet:result keyTypes:keyTypes];
}

#pragma mark --条件查询数据库中的数据  (限制数据条数:10)
-(NSArray *)DataBase:(FMDatabase *)db selectKeyTypes:(NSDictionary *)keyTypes fromTable:(NSString *)tableName whereCondition:(NSDictionary *)condition;
{
    if ([self isOpenDatabese:db]) {
    
        FMResultSet *result =  [db executeQuery:[NSString stringWithFormat:@"SELECT * FROM %@ WHERE %@ = ? LIMIT 10",tableName, [condition allKeys][0]], [condition valueForKey:[condition allKeys][0]]];
        return [self getArrWithFMResultSet:result keyTypes:keyTypes];
    }else
        return nil;
    }



#pragma mark --模糊查询 某字段以⭐️指定字符串  开头⭐️的数据  (限制数据条数:10)
-(NSArray *)DataBase:(FMDatabase *)db selectKeyTypes:(NSDictionary *)keyTypes fromTable:(NSString *)tableName whereKey:(NSString *)key beginWithStr:(NSString *)str
{
    if ([self isOpenDatabese:db]) {
        FMResultSet *result =  [db executeQuery:[NSString stringWithFormat:@"SELECT * FROM %@ WHERE %@ LIKE %@%% LIMIT 10",tableName, key, str]];
        return [self getArrWithFMResultSet:result keyTypes:keyTypes];
    }else
        return nil;
}

#pragma mark --模糊查询 某字段 ⭐️包含⭐️指定字符串的数据  (限制数据条数:10)
-(NSArray *)DataBase:(FMDatabase *)db selectKeyTypes:(NSDictionary *)keyTypes fromTable:(NSString *)tableName whereKey:(NSString *)key containStr:(NSString *)str
{
    if ([self isOpenDatabese:db]) {
    
        FMResultSet *result =  [db executeQuery:[NSString stringWithFormat:@"SELECT * FROM %@ WHERE %@ LIKE %%%@%% LIMIT 10",tableName, key, str]];
        return [self getArrWithFMResultSet:result keyTypes:keyTypes];
    }else
        return nil;
}

#pragma mark --模糊查询 某字段以指定字符串⭐️结尾⭐️的数据  (限制数据条数:10)
-(NSArray *)DataBase:(FMDatabase *)db selectKeyTypes:(NSDictionary *)keyTypes fromTable:(NSString *)tableName whereKey:(NSString *)key endWithStr:(NSString *)str
{
    if ([self isOpenDatabese:db]) {
        FMResultSet *result =  [db executeQuery:[NSString stringWithFormat:@"SELECT * FROM %@ WHERE %@ LIKE %%%@ LIMIT 10",tableName, key, str]];
        return [self getArrWithFMResultSet:result keyTypes:keyTypes];
    }else
        return nil;
}


#pragma mark --清理指定数据库中 表里的数据
-(void)clearDatabase:(FMDatabase *)db from:(NSString *)tableName
{
    if ([self isOpenDatabese:db]) {
        [db executeUpdate:[NSString stringWithFormat:@"DELETE FROM %@",tableName]];
    }
}

#pragma mark --删除指定数据库中的 表
-(void)dropTableFormDatabase:(FMDatabase *)db table:(NSString *)tableName
{
    if ([self isOpenDatabese:db]) {
        [db executeUpdate:[NSString stringWithFormat:@"DROP TABLE '%@'",tableName]];
    }
}

#pragma mark --(单一指定条件)删除指定数据库、表 中的 单条数据
-(void)deleteOneDataFormDatabase:(FMDatabase *)db fromTable:(NSString *)tableName whereConditon:(NSDictionary *)condition
{
    if ([self isOpenDatabese:db]) {
    [db executeUpdate:[NSString stringWithFormat:@"DELETE FROM %@ WHERE %@='%@';",tableName,[condition allKeys][0],    [condition allValues][0]]];
    }
}



#pragma mark - 查询语句          (1000条数据)
/**
 *  特定条件查integer
 */
- (NSInteger)DHSelectIntegerWithDB:(FMDatabase *)db table:(NSString *)table colunm:(NSString *)colunm  whereCondition:(NSDictionary *)condition {

    NSInteger result = 0;
    if ([self isOpenDatabese:db]) {
        NSString *sql = [NSString stringWithFormat:@"select %@ from %@  WHERE  %@ = '%@' limit 0,1000",colunm,table,[condition allKeys][0],[condition allValues][0]];
        FMResultSet *rs = [db executeQuery:sql];
        while ([rs next]) {
            result = [rs intForColumn:colunm];
        }
    }
    return result;
}
/**
 *  特定条件查text
 */
- (NSString *)DHSelectTextWithDB:(FMDatabase *)db table:(NSString *)table colunm:(NSString *)colunm whereCondition:(NSDictionary *)condition {

    NSString *result_str;
    if ([self isOpenDatabese:db]) {
        NSString *sql = [NSString stringWithFormat:@"select %@ from %@  WHERE  %@ = '%@' limit 0,1000",colunm,table,[condition allKeys][0],[condition allValues][0]];
        FMResultSet *rs = [db executeQuery:sql];
        while ([rs next]) {
            return [rs stringForColumn:colunm];
        }
    }
    return result_str;
}
/**
 *  特定条件查data
 */
- (NSData *)DHSelectDataWithDB:(FMDatabase *)db table:(NSString *)table colunm:(NSString *)colunm  whereCondition:(NSDictionary *)conditon {

    if ([self isOpenDatabese:db]) {
        FMResultSet *rs = [db executeQuery:[NSString stringWithFormat:@"select %@ from %@  WHERE  %@ = '%@' limit 0,1000",colunm,table,[conditon allKeys][0],[conditon allValues][0]]];
        while ([rs next]) {
            NSData *data = [rs dataForColumn:colunm];
            return data;
        }
    }
    return nil;
}




#pragma mark - update
/**
 *  特定条件更新                 注意:***条件只有一个键值对,最好用上面那个***
 *                             而且还只能是字符串之类
 */
- (BOOL)DHUpdateWithDB:(FMDatabase *)db table:(NSString *)table
           setKeyValue:(NSDictionary *)keyValue
             condition:(NSDictionary *)condition 
{
    BOOL isSuccess;
    NSArray *keys = [keyValue allKeys];
    if ([self isOpenDatabese:db]) {
        NSMutableString *sql = [NSMutableString stringWithFormat:@"update %@ set ",table];
        int count = 0;
        for (NSString *key in keyValue) {
            count ++;
            count == keys.count ? [sql appendFormat:@"%@ = '%@' ",key,keyValue[key]] : [sql appendFormat:@"%@ = '%@',",key,keyValue[key]];
        }
        [sql appendFormat:@"where %@ = '%@'",[condition allKeys][0],[condition allValues][0]];
    
        isSuccess = [db executeUpdate:sql];
    }

    return isSuccess;
}



#pragma mark - 判断是否存在
/**
 *  判断 有没有 该字段
 */
- (BOOL)DHisExistObjectInDataBase:(FMDatabase *)db fromTable:(NSString *)tableName colunm:(NSString *)colunm identify:(NSString *)identify
{
    if ([self isOpenDatabese:db]) {
        FMResultSet *rs = [db executeQuery:[NSString stringWithFormat:@"select count(1) from %@ where %@ = '%@'",tableName,colunm,identify]];
        int a = 0;
        while ([rs next]) {
            a = [rs intForColumn:@"count(1)"];
        }
        return a > 0 ? YES : NO;
    }else
        return NO;
}

/**
 *  判断有没有该字段,多个条件的
 */
- (BOOL)DHisExistObjectInDataBase:(FMDatabase *)db fromTable:(NSString *)tableName condition:(NSDictionary *)condition {

    NSArray *keys = [condition allKeys];
    int count = 0;
    if ([self isOpenDatabese:db]) {
        NSMutableString *sql = [NSMutableString stringWithFormat:@"select count(1) from %@ where ",tableName];
        for (NSString *key in condition) {
            count ++;
            [sql appendString:(count == keys.count ? [NSString stringWithFormat:@"%@ = '%@'",key,condition[key]] : [NSString stringWithFormat:@"%@ = '%@' AND ",key,condition[key]])];
        }
        FMResultSet *rs = [db executeQuery:sql];
        int a = 0;
        while ([rs next]) {
            a = [rs intForColumn:@"count(1)"];
        }
        return a > 0 ? YES : NO;
    }
    return NO;
}

/**
 *  判断表的存在
 */
- (BOOL)DHisExistTable:(NSString *)tableName DataBase:(FMDatabase *)db
{
    FMResultSet *rs = [db executeQuery:@"select count(*) as 'count' from sqlite_master where type ='table' and name = ?", tableName];
    while ([rs next])
    {
        // just print out what we've got in a number of formats.
        NSInteger count = [rs intForColumn:@"count"];
        //        NSLog(@"isTableOK %d", count);
        if (0 == count)
        {
            return NO;
        }
        else
        {
            return YES;
        }
    }
    return NO;
}




/**
 *  (获取)查找最后一行
 */
- (NSArray *)DHLastLineDataBase:(FMDatabase *)db fromTable:(NSString *)tableName colunm:(NSString *)colunm
{
    if ([self isOpenDatabese:db]) {
        FMResultSet *result =  [db executeQuery:[NSString stringWithFormat:@"select %@ from %@ order by %@ desc limit 1",colunm,tableName,colunm]];
        return [self getArrWithFMResultSet:result keyTypes:@{colunm:@"text"}];
    }else
        return nil;
}


















// 私有方法
#pragma mark -- CommonMethod   确定类型
-(NSArray *)getArrWithFMResultSet:(FMResultSet *)result keyTypes:(NSDictionary *)keyTypes
{
    NSMutableArray *tempArr = [NSMutableArray array];
    while ([result next]) {
        NSMutableDictionary *tempDic = [NSMutableDictionary dictionary];
        for (int i = 0; i < keyTypes.count; i++) {
            NSString *key = [keyTypes allKeys][i];
            NSString *value = [keyTypes valueForKey:key];
            if ([value isEqualToString:@"text"] || [value isEqualToString:@"TEXT"]) {
                //                字符串
                [tempDic setValue:[result stringForColumn:key] forKey:key];
            }else if([value isEqualToString:@"blob"] || [value isEqualToString:@"BLOB"])
            {
                //                二进制对象
                [tempDic setValue:[result dataForColumn:key] forKey:key];
            }else if ([value isEqualToString:@"integer"] || [value isEqualToString:@"INTEGER"])
            {
                //                带符号整数类型
                [tempDic setValue:[NSNumber numberWithInt:[result intForColumn:key]]forKey:key];
            }else if ([value isEqualToString:@"boolean"] || [value isEqualToString:@"BOOLLEAN"])
            {
                //                BOOL型
                [tempDic setValue:[NSNumber numberWithBool:[result boolForColumn:key]] forKey:key];
            }else if ([value isEqualToString:@"date"] || [value isEqualToString:@"DATA"])
            {
                //                date
                [tempDic setValue:[result dateForColumn:key] forKey:key];
            }
        }
        [tempArr addObject:tempDic];
    }
    return tempArr;
}

#pragma mark -- 数据库 是否已经 打开
-(BOOL)isOpenDatabese:(FMDatabase *)db
{
    if (![db open]) {
        [db open];
    }
    return YES;
}

@end






使用:

#import "SqliteTool.h"

//数据库 对象
FMDatabase * _db;  //全局变量

@property (nonatomic, strong) SqliteTool * sqlTool;          //  数据库对象 

//数据库懒加载
-(SqliteTool *)sqlTool
{
    if (!_sqlTool) {  
        _sqlTool = [SqliteTool shareTool];
        _db = [self.sqlTool getDBWithDBName:@"goyohol.sqlite"];// 数据库获取
    }
    return _sqlTool;
}


self.sqltool对象的使用: (name) 升序 查询数据

NSDictionary * beatProcessTimeDic = [NSDictionary dictionaryWithObjectsAndKeys:@"integer",@"id",@"text",@"name", nil];

//查询 数据库 中 表是否存在
BOOL isExist = [self.sqlTool DHisExistTable:@"tab_user" DataBase:_db];

//从数据库 获取数据
if (isExist) {  // 表存在
    // 顺序  打印出  数组元素
    NSArray * allDataArr = [self.sqlTool SortAllInformationDataBase:_db selectKeyTypes:beatProcessTimeDic fromTable:@"tab_user" colunm:@"name"];
    //数据库( ⭐️name升序 )排序
    
    for (int i = 0; i < allDataArr.count; i++) {
            NSLog(@"表存在 !    第%d个元素   %@",i,allDataArr[i]);
    }

}

打印结果:

FMDB操作 管理类封装_第9张图片
name字符串 升序



(id) 小更改 对比

NSDictionary * beatProcessTimeDic = [NSDictionary dictionaryWithObjectsAndKeys:@"integer",@"id",@"text",@"name", nil];
  
//查询 数据库 中 表是否存在
BOOL isExist = [self.sqlTool DHisExistTable:@"tab_user" DataBase:_db];

//从数据库 获取数据
if (isExist) {  // 表存在
    // 顺序  打印出  数组元素
    NSArray * allDataArr = [self.sqlTool SortAllInformationDataBase:_db selectKeyTypes:beatProcessTimeDic fromTable:@"tab_user" colunm:@"id"];
    //数据库( ⭐️id升序 )排序
    
    for (int i = 0; i < allDataArr.count; i++) {
            NSLog(@"表存在 !    第%d个元素   %@",i,allDataArr[i]);
    }

}

打印结果:

FMDB操作 管理类封装_第10张图片
id数字 升序

本单例类只需要 在 对 管理的数据(增、删、改、查)操作地方,根据单例类对象 调用相应的方法就好!




数据库路径自由放置:我就没创建数据库了,直接把之前路径(“Documents”)里面的数据库 copy了一份 在“Library”路径下面~~

FMDB操作 管理类封装_第11张图片
数据库新路径



当然我也只是列出了大部分需要的存储功能,如果有针对的可以直接在这个单例类里面封装好自己所需数据处理操作(增、删、改、查) 对应的方法形式!
或者再根据自己存储数据对应的类型,添加一个(或“多个”)接口来实现存储也可以(更加 直观明了)。

封装出来之后,调用只需要一个确定了文件路径的单例类!操作简单便捷!!
而且更重要的是以OC形式 来操作数据库了,不像使用FMDatabase对象来 单独执行SQL语句 那么容易出错。














goyohol's essay

你可能感兴趣的:(FMDB操作 管理类封装)