項目中遇到一個數(shù)據(jù)庫版本升級問題,最后還是解決了,現(xiàn)在來記錄下這個坑。
iOS項目中有數(shù)據(jù)庫方面的知識,之后的數(shù)據(jù)庫表比較簡單,為了實現(xiàn)產(chǎn)品經(jīng)理給的需求,不得不和服務(wù)器那邊協(xié)調(diào)通過增加數(shù)據(jù)表字段的方式來達(dá)到目的。之前,沒有做數(shù)據(jù)庫版本的記錄問題,需求什么的都滾一邊,產(chǎn)品太不專業(yè)了?,F(xiàn)在我的需求是在不改變原來APP上的數(shù)據(jù)的基礎(chǔ)上增加新的字段來實現(xiàn)消息推薦的已同意拒絕過期等狀態(tài)。剛開始時,覺得這個問題不是很難,所以有點大意了,中間遇到很多坑,SQLite語法很嚴(yán)謹(jǐn),所以遇到各種語法問題。還好,之前到隨手記面試的時候,也遇到過這個面試題,當(dāng)時沒想太多,就說每次刪掉舊的數(shù)據(jù)庫DB,現(xiàn)在想想當(dāng)時腦袋被門擠了吧。廢話不多說,說多了也是淚啊。。
我的思路:要想確保之前的數(shù)據(jù)不丟失,應(yīng)當(dāng)在之前數(shù)據(jù)庫表的基礎(chǔ)上創(chuàng)建新的數(shù)據(jù)庫表,哈哈,解決方案應(yīng)運而生了。
1.判斷數(shù)據(jù)庫版本號和保存數(shù)據(jù)庫版本號
NSString * const kdbManagerVersion = @"DBManagerVersion";
const static NSInteger DB_MANAGER_VER = 1;
// 升級操作
NSInteger ver = [[NSUserDefaults standardUserDefaults] integerForKey:kdbManagerVersion];
if (ver < DB_MANAGER_VER) {
[self upgrade];
}
- (void)saveDBVersion {
[[NSUserDefaults standardUserDefaults] setInteger:DB_MANAGER_VER forKey:kdbManagerVersion];
[[NSUserDefaults standardUserDefaults] synchronize];
}
2.數(shù)據(jù)庫升級
- (void)upgrade {
// 獲取舊版本號
NSInteger oldVersionNum = [[NSUserDefaults standardUserDefaults] integerForKey:kdbManagerVersion];
if (DB_MANAGER_VER <= oldVersionNum) {
return;
}
// 升級
[self upgrade:oldVersionNum];
// 保存新版本號
[self saveDBVersion];
}
- (void)upgrade:(NSInteger)oldVersion {
if (oldVersion >= DB_MANAGER_VER) {
return;
}
switch (oldVersion) {
case 0:
[self upgradeFromOldToNew];
break;
case 1:
[self upgradeFromOldToNew];
break;
case 2:
break;
default:
break;
}
oldVersion++;
// 判斷是否需要升級
[self upgrade:oldVersion];
}
- (void)upgradeFromOldToNew {
// 執(zhí)行版本1到版本2的更新
[self changeDBData:_db];
}
3.數(shù)據(jù)庫升級的SQL語句操作
- (void)changeDBData:(FMDatabase *)db {
[db open];
// 變更數(shù)據(jù)庫表為一個舊數(shù)據(jù)表
NSString *sqlStr = [NSString stringWithFormat:@"ALTER TABLE %@ RENAME TO %@", self.tableName, [self.tableName stringByAppendingString:@"_Old"]];
// 執(zhí)行SQL語句操作
[db executeUpdate:sqlStr];
// 創(chuàng)建新的數(shù)據(jù)表
NSString *executeStr = [NSString stringWithFormat:@"create table if not exists %@ (LocID integer primary key autoincrement not null,messageID text unique,Content text,TypeName text,SendTime text,CreateTime integer,Status integer,msgtype text,apply_id text,userid text,message_last_id text)",self.tableName];
BOOL bRet = [db executeUpdate:executeStr];
if (bRet) {
// 從舊數(shù)據(jù)表把舊數(shù)據(jù)插入新的數(shù)據(jù)表中
NSString *insertSql = [NSString stringWithFormat:@"INSERT INTO %@ SELECT * ,'','','' FROM %@", self.tableName, [self.tableName stringByAppendingString:@"_Old"]];
[db executeUpdate:insertSql];
}
// 刪除舊的數(shù)據(jù)表
[db executeUpdate:[NSString stringWithFormat:@"DROP TABLE %@", [self.tableName stringByAppendingString:@"_Old"]]];
[db close];
}