Android數據庫升級不丟失數據解決方案


  在Android開發中,sqlite至關重要,增刪查改不多說,難點在於,1,並發,多個線程同時操作數據庫。2,版本升級時,如果數據庫表中新加了個字段,如何在不刪除表的情況下順利過渡,從而不丟失數據。

  數據庫操作建議用ORM框架,簡單高效。這里推薦xUtils,里面包含DBUtils。github地址:https://github.com/wyouflf/xUtils。關於DBUtils,它是這樣介紹的:

  • android中的orm框架,一行代碼就可以進行增刪改查;
  • 支持事務,默認關閉;
  • 可通過注解自定義表名,列名,外鍵,唯一性約束,NOT NULL約束,CHECK約束等(需要混淆的時候請注解表名和列名);
  • 支持綁定外鍵,保存實體時外鍵關聯實體自動保存或更新;
  • 自動加載外鍵關聯實體,支持延時加載;
  • 支持鏈式表達查詢,更直觀的查詢語義,參考下面的介紹或sample中的例子。

     用單例方式獲取數據庫實例。

  static DbUtils db = null;

  public static DbUtils getDb(Context context) {

    if (context == null) {

      context = DoctorApplication.getInstance();

    }

    if (db == null) {

      db = DbUtils.create(context, "xUtils.db");

    });

    db.configAllowTransaction(true);

    return db;

  }

    db.configAllowTransaction(true);

    return db;

}

    db.configAllowTransaction(true); 標示開啟事務,這樣多個線程操作數據庫時就不會出現問題了。

   數據庫升級解決方案。首先創建一個實體類,對應數據庫中的表。

@Table(name = "User")

  public class User {

    private int id; //主鍵ID,必須

    private String uid;  

    private String type;

    public int getId() {

          return id;

      }

       public void setId(int id) {

            this.id = id;

      }

    public String getType() {

      return type;

    }  

    public void setType(String type) {

      this.type = type;

    }

    public String getUid() {

      return uid;

    }

    public void setUid(String uid) {

      this.uid = uid;

    } 

  }

 

  如果由版本1到版本2中,User表中新增了個字段title,如何在不刪除表User的情況下順利過渡呢,我們知道,如果不作處理,數據庫就會報錯,沒有列title。我們修改數據庫的創建方式,實現升級接口。 

  

db = DbUtils.create(context, "xUtils.db", 3, new DbUpgradeListener() {

  @Override

  public void onUpgrade(DbUtils db, int oldVersion, int newVersion) {

    if (newVersion > oldVersion) {

      updateDb(db, "User");

    }

  }

  });

 

  updateDb方法中比較類的屬性和之前版本數據庫表中的字段,如果屬性沒有對應到字段,則添加相應的字段。

private static void updateDb(DbUtils db, String tableName) {

try {

Class<EntityBase> c = (Class<EntityBase>) Class.forName("com.henizaiyiqi.doctorassistant.entitis." + tableName);// 把要使用的類加載到內存中,並且把有關這個類的所有信息都存放到對象c中

if (db.tableIsExist(c)) {

List<String> dbFildsList = new ArrayList<String>();

String str = "select * from " + tableName;

Cursor cursor = db.execQuery(str);

int count = cursor.getColumnCount();

for (int i = 0; i < count; i++) {

dbFildsList.add(cursor.getColumnName(i));

}

cursor.close();

Field f[] = c.getDeclaredFields();// 把屬性的信息提取出來,並且存放到field類的對象中,因為每個field的對象只能存放一個屬性的信息所以要用數組去接收

for (int i = 0; i < f.length; i++) {

String fildName = f[i].getName();

if (fildName.equals("serialVersionUID")) {

continue;

}

String fildType = f[i].getType().toString();

if (!isExist(dbFildsList, fildName)) {

if (fildType.equals("class java.lang.String")) {

db.execNonQuery("alter table " + tableName + " add " + fildName + " TEXT ");

} else if (fildType.equals("int") || fildType.equals("long") || fildType.equals("boolean")) {

db.execNonQuery("alter table " + tableName + " add " + fildName + " INTEGER ");

}

} 

}

}

} catch (Exception e) {

}

}

 

   這樣以后如果表中新增了字段,只需把數據庫版本號加1,數據庫就會自動升級一次,就能保證數據正常了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM