Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 1583|回复: 0

Android数据库升级不丢失数据解决方案

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-7-22 06:49:45 | 显示全部楼层 |阅读模式

      在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.getName();
    
    if (fildName.equals("serialVersionUID")) {
    
    continue;
    
    }
    
    String fildType = f.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,数据库就会自动升级一次,就能保证数据正常了。

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-12-22 18:52 , Processed in 0.054493 second(s), 28 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表