<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Android數(shù)據(jù)庫(kù)無縫升級(jí)方案

      軟件迭代過程中,業(yè)務(wù)不斷更新,也要求軟件持續(xù)更新。相應(yīng)地,數(shù)據(jù)庫(kù)更新升級(jí)也是不可避免的一個(gè)環(huán)節(jié)。Android作為客戶端應(yīng)用,數(shù)據(jù)庫(kù)升級(jí)相對(duì)于服務(wù)端來說會(huì)麻煩一些。常見的升級(jí)方式有:

        1.刪除舊表和數(shù)據(jù),創(chuàng)建新表。優(yōu)點(diǎn)是簡(jiǎn)單方便,缺點(diǎn)是丟失了舊數(shù)據(jù)。適用于應(yīng)用數(shù)據(jù)依賴度低的情況。

        2.在代碼中兼容處理各版本數(shù)據(jù)庫(kù),創(chuàng)建新表,遷移舊數(shù)據(jù)到新表。優(yōu)點(diǎn)是保留了舊數(shù)據(jù),缺點(diǎn)是需要處理兼容個(gè)版本數(shù)據(jù)庫(kù)差異,比較麻煩。如果通過代碼來記錄維護(hù)版本差異,會(huì)導(dǎo)致代碼臃腫且極易出錯(cuò)。

       

      本文介紹一種簡(jiǎn)單無縫的數(shù)據(jù)庫(kù)升級(jí)方案,也是屬于上述的第二種方式,但是簡(jiǎn)單、高效地處理了數(shù)據(jù)庫(kù)版本兼容。代碼已實(shí)現(xiàn)在DBFramework中,這是一個(gè)輕量的數(shù)據(jù)庫(kù)框架,簡(jiǎn)單、規(guī)范、高效,能夠很好的處理表之間的繼承關(guān)系,可以為你節(jié)省很多開發(fā)工作。

      感興趣的朋友可以了解一下。

       

      數(shù)據(jù)庫(kù)升級(jí),其實(shí)是對(duì)其中的表進(jìn)行升級(jí)。要更新表并且保留數(shù)據(jù),這就必須要知道新表和舊表之間的差異。如果我們靠開發(fā)人員來記錄各版本之間表的差異,無疑是一個(gè)困難和繁雜的工作。那么當(dāng)我們進(jìn)行數(shù)據(jù)庫(kù)的時(shí)候,客戶端應(yīng)用有沒有辦法知道這些差異,知道有哪些表需要更新呢?答案是肯定的。在Sqlite中有一張叫做sqlite_master的系統(tǒng)表,其中記錄了sqlite中的所有表信息,如下:

      可以看到,其中除了表名,還有表創(chuàng)建語句。有了創(chuàng)建語句,我們就能解析出表的字段信息,然后對(duì)比新表和舊表的字段,有差異則說明表需要更新,反之則不需要更新。如下代碼用來獲取現(xiàn)有的表信息:

      /**
           * Get old tables.
           * @return A map contains old tables which takes table name as key.
           */
          public Map<String, Table> getOldTables() {
              final String table = "sqlite_master";
              final String[] columns = {"name", "sql"};
              Cursor cursor = mDB.query(table, columns, "type='table'", null, null, null, null);
              HashMap<String, Table> ret = null;
              if (cursor.getCount() > 0) {
                  ret = new HashMap<String, Table>(cursor.getCount());
                  Table tmp;
                  while (cursor.moveToNext()) {
                      tmp = new Table(cursor.getString(0), cursor.getString(1));
                      ret.put(tmp.Name, tmp);
                  }
              }
              cursor.close();
              return ret == null ? Collections.EMPTY_MAP : ret;
          }

       

      Table是一個(gè)記錄表信息的類,拿到現(xiàn)有表信息,就可以和新的表信息進(jìn)行對(duì)比,主要對(duì)比表字段的變化:

        public class Table {
      
         ...
      
        public boolean equalsColumns(Table table) {
              String myColumns = getColumnsStatement(CreateSql).toUpperCase();
              String columns = getColumnsStatement(table.CreateSql).toUpperCase();
              return (myColumns.equals(columns));
          }
      
         ...
      
      }

       

       如果無變化則跳過,有變化則更新,更新過程為:

      1.將現(xiàn)有表以別名命名

      2.創(chuàng)建新表

      3.遷移數(shù)據(jù)

      4.刪除現(xiàn)有表

       如下代碼所示:

       @Override
          protected void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion, List<Table> tableList) {
              Map<String, Table> oldMap = getOldTables();
              Iterator<Table> iterator = tableList.iterator();
              Table table;
              Table oldTable;
              String tempTable;
              while (iterator.hasNext()) {
                  table = iterator.next();
                  if ((oldTable = oldMap.get(table.Name)) == null) {
                      //New table, create directly.
                      db.execSQL(table.CreateSql);
                      Log.i(TAG, "Table " + table.Name + " is a new table. Create it directly");
                      continue;
                  }
                  //Remove hit table.
                  oldMap.remove(table.Name);
                  if (oldTable.equalsColumns(table)) {
                      //Table not change.
                      Log.i(TAG, "Table " + table.Name + " doesn't need update");
                      continue;
                  }
                  tempTable = table.Name + TEMP_SUFFIX;
                  Log.i(TAG, "Update table: " + table.Name);
      
                  //Table changed.
                  //Alter old table as temp.
                  alterTableName(oldTable.Name, tempTable);
                  //Create new table.
                  db.execSQL(table.CreateSql);
                  //Copy data.
                  copyData(getCommonColumn(oldTable.getColumns(), table.getColumns()), tempTable, table.Name);
                  //Delete old table
                  deleteTable(tempTable);
              }
              //Delete obsolete tables not hit.
              deleteObsoleteTables(oldMap.values());
          }

       

      更多細(xì)節(jié)可查看源碼:DBFramework

      這種方案簡(jiǎn)單方便,而且?guī)缀跻粍谟酪荨M扑]小伙伴們使用,如果有更好的方式或者寶貴意見,歡迎交流。

       

      posted @ 2017-07-14 13:01  Oxgen  Views(5923)  Comments(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 国产精品青青在线观看爽香蕉| 国产一精品一av一免费| 亚洲成片在线看一区二区| 免费看婬乱a欧美大片| 欧美亚洲另类自拍偷在线拍| 日本高清视频在线www色| 亚洲国产精品自产拍久久| 成人3D动漫一区二区三区| 又黄又硬又湿又刺激视频免费| 国产精品一区二区三区性色| 风韵丰满熟妇啪啪区老熟熟女| 看免费的无码区特aa毛片| 华容县| 日韩人妻一区中文字幕| 一本色道国产在线观看二区 | 精品久久久久久无码人妻蜜桃| 国产精品高清视亚洲乱码| 中文字幕在线精品人妻| 国产成人亚洲综合图区| 90后极品粉嫩小泬20p| 少妇仑乱a毛片无码| 91久久偷偷做嫩草影院免费看| 忘忧草日本在线播放www| 亚洲精品一区二区三区片| 精品国产成人午夜福利| 91福利视频一区二区| 鱼台县| 国产精品久久久久久av| 五十路久久精品中文字幕| 涩涩爱狼人亚洲一区在线| 伊人久久大香线蕉av五月天| 亚洲精品国产精品乱码不| 日本视频一区二区三区1| 潮喷失禁大喷水无码| 黑人异族巨大巨大巨粗| 亚洲精品麻豆一二三区| 老女老肥熟国产在线视频| 亚洲第一无码专区天堂| 国产极品美女网站在线观看| 一个色综合亚洲热色综合| 日韩一区国产二区欧美三区 |