美文网首页
封装简单数据库

封装简单数据库

作者: 孤城99 | 来源:发表于2016-12-12 20:21 被阅读0次
    第一步 导入数据库 libsqlite3.0.tbd

    屏幕快照 2016-12-12 19.24.07.png
    第二步 创建一个继承于NSObject的类,并声明单例方法
    //单例方法的声明
    + (DataBaseHelper*)sharedDataBaseHelper;
    

    //单例方法的实现
    + (DataBaseHelper*)sharedDataBaseHelper{
    //定义一个静态的DataBaseHelper对象,赋值为空
    static DataBaseHelper* dbHelper = nil;
    if (dbHelper == nil) {
        dbHelper = [[DataBaseHelper alloc] init];
    }
    return dbHelper;
    }
    
    第三步:在类的(.m)文件中进行类的扩展 --- 延展(category)
    @interface DataBaseHelper ()
    {
    //数据库句柄---句柄:指代数据库的对象
    sqlite3 *sqliteHandle;  
    }
    @property (nonatomic,strong) NSString* dbFileName;//数据库文件路径,全局化
    @end
    
    第四步:创建数据库存储的文件路径,一般在documents或者library下的caches(缓存文件夹)
    - (void)dbFileNameWithName:(NSString*)fileName{
    
    //将fileName中的空格替换,防止文件名中存在空格
    fileName = [fileName stringByReplacingOccurrencesOfString:@" " withString:@""];
    
    //判断用户传递进来的文件名是否为nil
    if (fileName) {
        //判断文件明是否为空字符串
        if (fileName.length == 0) {
            //空字符串 @“”
            NSLog(@"数据库文件无名称,当程序关闭的时候,数据库文件也会销毁");
        }else{
            //判断文件名是否带后缀名,如果有,直接使用,如果没有后缀名,添加后缀名之后再使用
            if (![fileName hasSuffix:@".sqlite"]) {
                //如果没有后缀名,添加后缀名在使用
                [fileName stringByAppendingString:@".sqlite"];
            }
            
        }
    }else{
       //说明文件名为nil
        NSLog(@"数据库文件无名称,当程序关闭的时候,数据库文件也会销毁");
        fileName = @"";
    }
    //将文件名称拼接成一个有效的文件路径
    //获取沙盒下documents的路径
    NSString* documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
    //拼接文件路径
    fileName = [documentsPath stringByAppendingPathComponent:fileName];
    //将处理好的文件名赋值给属性让其他方法是用
    self.dbFileName = fileName;
    }
    
    第五步:打开或者创建数据库
    - (sqlite3*)createDB{
    //创建数据库文件的函数,如果数据库文件存在,那么这个方法就是打开数据库文件,如果数据库不文件存在,这个方法就是创建数据库文件,再打开
    //第一个参数:数据库文件的路径,并且需要将其转换为char * 类型(是C语言的字符串类型)
    //第二个参数:数据库文件的句柄,取地址  & 符号就是取地址
    //将数据库句柄指向数据库内存,我们对数据库的操作,都是通过句柄来完成的
    int result = sqlite3_open(self.dbFileName.UTF8String, & sqliteHandle);
    //判断数据库库是否打开或者创建成功
    if (result == SQLITE_OK) {
        NSLog(@"创建或者打开数据库成功");
        return  sqliteHandle;
    }else{
        NSLog(@"创建或者打开数据库失败 === %d",result);
        return NULL;
    }
    }
    
    第六步:非查询操作(无返回结果集执行的操作)创建、插入、更新、删除等
    参数为:需要执行的sql语句
    
    - (BOOL)noQueryWithSql:(NSString*)sql{
    //执行任何数据库操作之前,先打开数据库,操作执行完毕记得关闭数据库
    sqlite3 *sqlite = [self createDB];
    //执行sql语句
    if (sqlite) {//保证数据库打开成功
        int result = sqlite3_exec(sqlite, sql.UTF8String, NULL, NULL, NULL);
        //当操作有结果的时候,一定要关闭数据库
        //参数可以填sqlite,也可以填sqliteHandle
        sqlite3_close(sqlite);
        //判断执行的非查询操作是否成功
        if (result == SQLITE_OK) {
            NSLog(@"执行非查询操作成功");
            return YES;
        }else{
            NSLog(@"执行非查询操作失败");
            return NO;
        }
    }
    
    NSLog(@"执行操作的时候,打开数据库失败了");
    return NO;
    }
    
    第六步:通用查询方法

    ==注意:数据表的列数、字段名(作为字典的key)、字段的类型都是变化的,不能写死==

    - (NSArray*)queryWithSql:(NSString*)sql{
    //打开数据库
    sqlite3 *sqlite = [self createDB];
    
    //创建可变数组,用来存放所有的记录
    NSMutableArray *resultMArray = [[NSMutableArray alloc] init];
    
    //伴随指针 当我们进行查询操作的时候,该指针可以理解为存储一条一条的记录。我们获取一条记录的所有信息都是通过伴随指针。
    //声明伴随指针,作用存放所有的记录,赋值为NULl
    sqlite3_stmt *stmt = NULL;
    
    //预执行sql语句,如果预执行成功说明,那么我们就可以获取一条一条的记录;如果预执行失败,说明我们的sql语句有问题 不能获取表中的记录信息
    //第一个参数:数据库句柄
    //第二个参数:要执行的SQ语句
    //第三个参数:要执行的长度,如果全部执行,这里就赋值为-1
    //第四个参数:伴随指针
    //第五个参数:如果sql语句不全部执行,该参数保存未执行的sql语句
    int result = sqlite3_prepare(sqliteHandle, sql.UTF8String, -1, &stmt, NULL);
    
    //判断预执行是否成功
    if(result == SQLITE_OK){
        //说明sql语句没有问题
        //从伴随指针中遍历取出每一条记录
        while (sqlite3_step(stmt) == SQLITE_ROW) {
            //每执行一次循环体,就取出一条记录
            //创建字典
            NSMutableDictionary *mDic = [NSMutableDictionary dictionary];
            //确定该条记录有几个字段
            //参数为伴随指针
            int sumColumns = sqlite3_column_count(stmt);
            //for循环遍历一条记录中的所有字段,
            for (int i = 0; i < sumColumns; i++) {
                //获取当前字段(列)的数据类型
                int type = sqlite3_column_type(stmt, i);
                //获取字段名 key
                const char* name = sqlite3_column_name(stmt, i);
                //将char*类型转换为我们OC中可用的字符串类型
                NSString *key = [NSString stringWithCString:name encoding:NSUTF8StringEncoding];
                //取出每一列的值
                //这里只取两个基本的类型,别的类型可自行添加
                switch (type) {
                    case SQLITE_INTEGER:
                        //int型
                    {//在case下如果有多行代码,加一个{}
                        int value = sqlite3_column_int(stmt, i);
                        //为字典赋值
                        [mDic setObject:@(value) forKey:key];
                    }
                        break;
                    case SQLITE_TEXT:{
                        //字符串型
                        const unsigned char* value = sqlite3_column_text(stmt, i);
                        //将char*类型转换为我们OC中可用的字符串类型
                        NSString* valueString = [NSString stringWithCString:(const char*)value encoding:NSUTF8StringEncoding];
                        //为字典赋值
                        [mDic setObject:valueString forKey:key];
                    }
                        break;
                    default:
                        break;
                }
            }
            //一次for循环结束,一条记录才转换为一个字典
            [resultMArray addObject:mDic];
        }
        //while循环结束,说明所有的记录都已经获取完整
    //        return resultMArray;
        
    }else{
       //说明sql语句有问题
        NSLog(@"执行查询操作有误 === %d",result);
    //        return resultMArray;
    }
    //释放资源,关闭数据库
    sqlite3_finalize(stmt);
    //关闭数据库
    sqlite3_close(sqlite);
    
    //返回数组
    return resultMArray;
    
    }
    
    第七步:将需要从外界传参数的方法在(.h)文件中声明,方便调用
    第八章:数据库的调用

    相关文章

      网友评论

          本文标题:封装简单数据库

          本文链接:https://www.haomeiwen.com/subject/jifvmttx.html