在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,數據庫就會自動升級一次,就能保證數據正常了。
