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,数据库就会自动升级一次,就能保证数据正常了。

 

原文地址:https://www.cnblogs.com/lsc183/p/4450761.html