zoukankan      html  css  js  c++  java
  • 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,数据库就会自动升级一次,就能保证数据正常了。

     

  • 相关阅读:
    java 类的关系
    Oracle lock table
    shell 标准输出重定向
    pygame 安装
    进程检查机制
    oracle pivot unpivot
    qt paintEvent
    centos7.5+Ambari2.7.3部署安装
    Linux机器间配置ssh互信
    普通视图和物化视图的区别
  • 原文地址:https://www.cnblogs.com/lsc183/p/4450761.html
Copyright © 2011-2022 走看看