數據庫操作(增刪改查+升級表結構)

這幾天在做數據庫,數據庫的創建,表的創建和刪除。表內數據的增刪改查都是老生常談的問題了。今天說數據庫主要是剛建立數據庫的時候需要注意些什麼。

新建數據庫時考慮到數據庫需要升級的問題所以數據庫需要判斷app的版本號,這樣就可以在升級app的時候同時升級數據庫,從而防止數據庫的升級遇到不可修復的bug。新建數據庫語句如下:

NSString *pathDocuments = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *createPath = [NSString stringWithFormat:@"%@/DB", pathDocuments];
//db路徑
        self.dbPath = [NSString stringWithFormat:@"%@/database.sqlite",createPath,version];
        if (![fileManager fileExistsAtPath:createPath]) {
            [fileManager createDirectoryAtPath:createPath withIntermediateDirectories:YES attributes:nil error:nil];
            [fileManager createFileAtPath:_dbPath contents:nil attributes:nil];
        }
        //創建數據庫
        qfdb = [FMDatabase databaseWithPath:_dbPath];

其實數據庫的創建跟普通文件的創建一模一樣,下面就應該是創建表了,而當數據庫升級的時候實質上是升級表。所以下面就需要慎重了。
我這裏爲了使用統一的方法,創建不同的表使用同一個方法所以自己封裝了下sql語句的拼接,代碼如下

-(void)createTableInDataBase:(NSString*)tableName withAllKeys:(NSArray*)keys
{
    //sql 語句
    if ([qfdb open]) {
        NSString *createSqlStr = @"";
        for (NSString *sqfStr in keys) {
            if ([createSqlStr isNotEmpty]) {
                {
                if ([sqfStr isEqualToString:@"articleid"] && [tableName isEqualToString:@"have_read_articles"]) {
                    createSqlStr = [NSString stringWithFormat:@"'%@' TEXT PRIMARY KEY,",sqfStr];
                }
                else
                {
                    createSqlStr = [NSString stringWithFormat:@"'%@' TEXT,",sqfStr];
                }
        }
        createSqlStr = [createSqlStr substringToIndex:createSqlStr.length - 1];
        NSString *sqlCreateTable;
        if ([tableName isEqualToString:@"have_load_articles"]) {
            sqlCreateTable =  [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS '%@' ('id' INTEGER PRIMARY KEY AUTOINCREMENT, %@)",tableName,createSqlStr];
        }
        else
        {
            sqlCreateTable =  [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS '%@' ('id' INTEGER identity(1,1), %@)",tableName,createSqlStr];
        }
        BOOL res = [qfdb executeUpdate:sqlCreateTable];
        if (!res) {
            NSLog(@"創建qfdb失敗!");
        } else {
            NSLog(@"創建qfdb成功!");
        }
        [qfdb close];
    }
}

上面就是根據傳入的數組來新建表以及表結構的。然後就是插入數據了,代碼如下:

-(void)inseartIntoTable:(NSString*)tableName withKeyAndValues:(NSArray*)list
{
    if ([qfdb open]) {
        NSString *inseartSqlKeyStr = @"";
        NSString *inseartSqlValueStr = @"";
        for (NSDictionary *sqfDic in list) {
            if ([inseartSqlKeyStr isNotEmpty]) {
                NSString *keyStr = sqfDic[@"key"];
                NSString *valueStr = sqfDic[@"value"];
                inseartSqlKeyStr = [inseartSqlKeyStr stringByAppendingFormat:@"'%@',",keyStr];
                inseartSqlValueStr = [inseartSqlValueStr stringByAppendingFormat:@"'%@',",valueStr];
            }
            else
            {
                NSString *keyStr = sqfDic[@"key"];
                NSString *valueStr = sqfDic[@"value"];
                inseartSqlKeyStr = [NSString stringWithFormat:@"'%@',",keyStr];
                inseartSqlValueStr = [NSString stringWithFormat:@"'%@',",valueStr];
            }
        }
        inseartSqlKeyStr = [inseartSqlKeyStr substringToIndex:inseartSqlKeyStr.length - 1];
        inseartSqlValueStr = [inseartSqlValueStr substringToIndex:inseartSqlValueStr.length - 1];
        NSString *insertSql= [NSString stringWithFormat: @"INSERT INTO '%@' (%@) VALUES (%@)", tableName,inseartSqlKeyStr,inseartSqlValueStr];
        BOOL res = [qfdb executeUpdate:insertSql];
        if (!res) {
            NSLog(@"插入數據失敗!");
        } else {
            NSLog(@"插入數據成功!");
        }
        [qfdb close];
    }
}

下面就是更新數據的方法,根據需要修改的條件去修改特定的表中的內容,代碼如下:

-(void)updateDataInTable:(NSString*)tableName withAnalyseDic:(NSDictionary*)dict withChangedKeyAndValues:(NSArray*)list
{
    if ([qfdb open]) {
        NSString *updateSqlStr = @"";
        for (NSDictionary *sqfDic in list) {
            if ([updateSqlStr isNotEmpty]) {
                NSString *keyStr = sqfDic[@"key"];
                NSString *valueStr = sqfDic[@"value"];
                updateSqlStr = [updateSqlStr stringByAppendingFormat:@"%@ = '%@',",keyStr,valueStr];
            }
            else
            {
                NSString *keyStr = sqfDic[@"key"];
                NSString *valueStr = sqfDic[@"value"];
                updateSqlStr = [updateSqlStr stringByAppendingFormat:@"%@ = '%@',",keyStr,valueStr];
            }
        }
        updateSqlStr = [updateSqlStr substringToIndex:updateSqlStr.length - 1];
        NSString *updateSql = [NSString stringWithFormat:@"UPDATE '%@' SET %@ WHERE %@ = '%@'",tableName,updateSqlStr,dict[@"key"],dict[@"value"]];
        BOOL res = [qfdb executeUpdate:updateSql];
        if (!res) {
            NSLog(@"更新數據庫數據表失敗!");
        } else {
            NSLog(@"更新數據庫數據表成功!");
        }
        [qfdb close];
    }
}

由於時間緊迫就簡單寫一個表的查詢方法,不統一使用的方法來查詢表內容了,不過依然可以借鑑,代碼如下:

#pragma mark-查詢表中的數據
-(NSArray*)selectRowsFromTable:(NSString*)tableName withselectedDic:(NSDictionary*)dict
{
    NSMutableArray *resultArray = [NSMutableArray new];
    if ([qfdb open]) {
        NSString *selectSql =@"";
        if ([dict isNotEmpty]) {
            selectSql = [NSString stringWithFormat:@"SELECT * FROM '%@' WHERE %@ = '%@' Order By id Desc Limit 15",tableName,dict[@"key"],dict[@"value"]];
        }
        //查詢結果
        FMResultSet *result = [qfdb executeQuery:selectSql];
        //聲明數組用於保存查詢結果
        NSMutableArray *resultArr = [NSMutableArray new];
        while ([result next])
        {

            NSString *aid = [result stringForColumn:@"aid"];
            NSString *title = [result stringForColumn:@"title"];
            NSString *public_url = [result stringForColumn:@"public_url"];
            NSString *master_img = [result stringForColumn:@"master_img"];
            NSString *look_num = [result stringForColumn:@"look_num"];
            NSString *commend_num = [result stringForColumn:@"commend_num"];
            NSString *atime = [result stringForColumn:@"atime"];
            NSString *private_url = [result stringForColumn:@"private_url"];
            NSString *durationInMMSS = [result stringForColumn:@"durationInMMSS"];
            NSString *trace_id = [result stringForColumn:@"trace_id"];
            NSString *acate = [result stringForColumn:@"acate"];
            NSString *segement = [result stringForColumn:@"segement"];

            NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:(aid?aid:@""),@"aid",(title?title:@""),@"title",(public_url?public_url:@""),@"public_url",(master_img?master_img:@""),@"master_img",(look_num?look_num:@""),@"look_num",(commend_num?commend_num:@""),@"commend_num",(atime?atime:@""),@"atime",(private_url?private_url:@""),@"private_url",(durationInMMSS?durationInMMSS:@""),@"durationInMMSS",(trace_id?trace_id:@""),@"trace_id",(acate?acate:@""),@"acate",(segement?segement:@""),@"segement", nil];
            [resultArr addObject:dict];
        }
        NSArray *arrayM = [MainRecommondModule mj_objectArrayWithKeyValuesArray:resultArr];
        if (arrayM.count) {
            for (NSInteger i=arrayM.count - 1; i>0; i--) {
                [resultArray addObject:arrayM[i]];
            }
        }
        [qfdb close];
    }
    return resultArray;
}

最後就是刪除數據了,代碼如下:

-(BOOL)deleteRowFormTable:(NSString*)tableName withAnalyseDic:(NSDictionary*)dict
{
    BOOL result;
    if ([qfdb open]) {
        NSString *selectSql =@"";
        if ([dict isNotEmpty]) {
            NSString *idStr = dict[@"id_key"];
            selectSql = [NSString stringWithFormat:@"Delete from %@ WHERE id = '%@' ",tableName,idStr];
        }
        result = [qfdb executeUpdate:selectSql];
        [qfdb close];
    }
    return result;
}
#pragma mark-清空表數據
-(BOOL)deleteAllRowsFormTable:(const char *)tableName
{
    BOOL result;
    if ([qfdb open]) {
        NSString *selectSql = [NSString stringWithFormat:@"Delete from %s",tableName];
        result = [qfdb executeUpdate:selectSql];
        [qfdb close];
    }
    return result;
}

最後上重點,現在先講下思路,升級數據庫,其實就是先根據原來的表新建一個新表,然後從舊錶裏面取出數據插入新表當中,然後再把舊錶刪除掉,這裏所說的刪除表是drop掉表而不是delete清空表內容。到這一步以後其實新表就建好了,如果我們查詢,插入等sql語句不想改的話就需要將新建的表名稱改回舊錶名稱了。這樣的話就是新建舊錶名的‘新’表,然後將剛剛的新表裏面的內容插入到‘新’表之中。這樣再把剛剛的新表drop掉就完全達到我們的目的了。
sql語句如下:

//新建修改字段後的表CREATE TABLE table_new(ID INTEGER PRIMARY KEY AUTOINCREMENT, Modify_Username text not null)
//從舊錶中查詢出數據 並插入新表INSERT INTO table_new SELECT ID,Username FROM table
//刪除舊錶DROP TABLE table

//新建修改字段後的表CREATE TABLE table(ID INTEGER PRIMARY KEY AUTOINCREMENT, Username text not null)
//從舊錶中查詢出數據 並插入新表INSERT INTO table SELECT ID,Username FROM table_new
//刪除舊錶DROP TABLE table_new

到此結束,當然還有更方便的方法,我上面的步驟需要六步,而還有其他的需要四步的方式。今天就到此了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章