原码笔记

原码笔记

android轻量级无侵入式管理数据库自动升级组件

小诸哥 0

目录

SpeSqliteManager4Android

改动日志

  1. 2023.2.14 完成SQLiteOpenHelper
  2. 2023.2.23 完成room
  3. 2023.2.25 完成架构重构
  4. 2023.2.26 新增架构设计图说明

介绍

一个轻量级无侵入式管理android数据库自动升级的管理类(支持SQLiteOpenHelper、room)

妈妈再也不用担心写一坨坨的migration或是手动sql去升级数据库

核心设计思想

1.以静制动:配置项代替代码,保证代码稳定性

架构设计

android轻量级无侵入式管理数据库自动升级组件

关配置项json:

  • 1.dbName:数据库文件名称,要保持稳定,不能修改。
  • 2.dbVersion:数据库版本号,判断本地数据库文件是否升级就通过此key,升级时要保证新版本号大于当前的。
  • 3.dbTables:想要创建的表名,每个表名下是具体的字段。


集成步骤

1.导入依赖库

  1.      implementation 'com.google.code.gson:gson:2.8.9'
  2.      implementation "androidx.room:room-runtime:2.0.0"
  3.      annotationProcessor "androidx.room:room-compiler:2.0.0"

2.在assets目录下新建dbupdate.json 注意:dbconfig的配置不要动,自己的表在后面新增

3.SQLiteOpenHelper的调用方法

  1.      //1.直接创建SQLiteOpenHelper
  2.      SpeSqliteOpenHelperService.getInstance(this);
  3.      //2.创建SQLiteOpenHelper且需要监听db
  4.      SpeSqliteOpenHelperService.getInstance(this, new SpeSqliteBaseInterface() {
  5.          @Override
  6.          public <T> void onCreate(T db, RoomDatabase room) {
  7.                 
  8.          }
  9.          @Override
  10.          public <T> void onOpen(T db, RoomDatabase room) {
  11.                     
  12.          }
  13.          @Override
  14.          public <T> void onUpgrade(T db, int oldVersion, int newVersion, RoomDatabase room) {
  15.                     
  16.          }
  17.      });

4.Room的调用方法

  1.      //3.直接创建room
  2.          SpeSqliteRoomService.getInstance(this,AppDatabase.class);
  3.      //4.创建room,且需要监听db
  4.          SpeSqliteRoomService.getInstance(this,AppDatabase.class,new SpeSqliteBaseInterface() {
  5.              @Override
  6.              public <T> void onCreate(T db, RoomDatabase room) {
  7.                  //TODO 删除测试插入代码
  8.                  if(room != null){
  9.                      ServerModel model = new ServerModel();
  10.                      model.setId("1");
  11.                      model.setHost("1");
  12.                      model.setLang("1");
  13.                      model.setName("1");
  14.                      model.setVersion("1");
  15.                      insert(room,model);
  16.                  }
  17.  
  18.              }
  19.              @Override
  20.              public <T> void onOpen(T db, RoomDatabase room) {
  21.  
  22.              }
  23.  
  24.              @Override
  25.              public <T> void onUpgrade(T db, int oldVersion, int newVersion, RoomDatabase room) {
  26.  
  27.              }
  28.          });

核心代码

SpeSqliteUpdateManager 负责针对本地db的创建、新建表、表字段升级、删除表,通过配置的方式去升级数据库,减少代码的改动,核心思想:以静制动

  1.      /**
  2.          * 数据库第一次创建时的调用函数
  3.          * @param db db
  4.          */
  5.      public void create(SQLiteDatabase db){
  6.          SpeSqliteSettingModel currentDBModel = SpeSqliteUpdateManager.getInstance().currentAppDBSetting();
  7.          for(int i=0;i<currentDBModel.dbTables.size();i++){
  8.              SpeSqliteTableSettingModel table = currentDBModel.dbTables.get(i);
  9.              String sql = " create table if not exists "+table.tableName+" (";
  10.              for(int j=0;j<table.columns.size();j++){
  11.                  SpeSqliteColumnSettingModel column = table.columns.get(j);
  12.                  sql+=column.key+" ";
  13.                  sql+=column.keyType;
  14.                  if(j==table.columns.size()-1){
  15.                      sql+=" ";
  16.                  }else {
  17.                      sql+=",";
  18.                  }
  19.              }
  20.              sql+=")";
  21.              executeSQL(db,sql);
  22.          }
  23.          //SQLiteDatabase数据库才需要升级本地数据配置
  24.          if(db instanceof SQLiteDatabase){
  25.              SQLiteDatabase _db = (SQLiteDatabase)db;
  26.              updateConfig2DB(_db,currentDBModel);
  27.          }
  28.      }
  29.  
  30.      /**
  31.          * 升级数据库,此处涉及3种改动:1.新建表 2.老表新增字段 3.删除表
  32.          * 注意该方法会被两个数据库依次触发,所以需要控制
  33.          * 1.新建表的处理思路:比较简单直接create即可
  34.          * 2.老表新增字段需要遍历db中的json表字段明细和当前app中的json明细
  35.          * @param db db
  36.          */
  37.      public void upgrade(SQLiteDatabase configdb,SupportSQLiteDatabase db){
  38.          SpeSqliteSettingModel newConfig = this.currentAppDBSetting();
  39.          SpeSqliteSettingModel localConfig = this.getAppLoclDBSetting(configdb);
  40.          //该处判断可以不要,但是加了后(daupdate.json的dbversion字段)效率更高
  41.          if(localConfig.dbVersion< newConfig.dbVersion){//通过dbversion直接判断是否要升级
  42.              //防止room数据未创建表,就alter
  43.              if(db != null){
  44.                  for(int i=0;i<localConfig.dbTables.size();i++) {
  45.                      SpeSqliteTableSettingModel _local = localConfig.dbTables.get(i);
  46.                      createTableSQL(db,_local);
  47.                  }
  48.              }
  49.              for(int j=0;j<newConfig.dbTables.size();j++){
  50.                  SpeSqliteTableSettingModel _new = newConfig.dbTables.get(j);
  51.                  for(int i=0;i<localConfig.dbTables.size();i++){
  52.                      SpeSqliteTableSettingModel _local = localConfig.dbTables.get(i);
  53.                      if(_local.tableName.equals(_new.tableName)){//找到,再判断字段是否有新增
  54.                  _local.indexed = true;//被比较过,该表不用删除
  55.                      if(_local.columns.size()<_new.columns.size()){
  56.                      //执行alert去新增字段 //
  57.                      alterCoulmns(db != null?db:configdb,_local,_new);
  58.                      }
  59.                      break;//只要匹配到就直接跳出该层循环
  60.                      }
  61.                  }
  62.                  //本地数据没找到这个表需要新增
  63.                  createTableSQL(db != null?db:configdb,_new);
  64.              }
  65.              //针对被废弃的表需要在本地库中删除
  66.              for(int i=0;i<localConfig.dbTables.size();i++){
  67.                  SpeSqliteTableSettingModel table = localConfig.dbTables.get(i);
  68.                  if(!table.indexed){
  69.                      dropTables(db != null?db:configdb,localConfig.dbTables.get(i));
  70.                  }
  71.              }
  72.              //只有当是SQLiteDatabase升级时才能本地数据配置
  73.              if(db == null){
  74.                  updateConfig2DB(configdb,newConfig);
  75.              }
  76.          }
  77.      }
  78.  
  79.      /**
  80.          * 移除老表
  81.          * @param db db
  82.          * @param table table
  83.          * @param <T> 范型(需考虑SQLiteOpenHelper和room)
  84.          */
  85.      private <T> void dropTables(T db,SpeSqliteTableSettingModel table){
  86.          String sql = " DROP TABLE IF EXISTS "+table.tableName;
  87.          executeSQL(db,sql);
  88.      }
  89.  
  90.      /**
  91.          * 老表新增字段
  92.          * @param db db
  93.          * @param _old 老表字段配置
  94.          * @param _new 表新字段配置
  95.          * @param <T> 范型(需考虑SQLiteOpenHelperroom
  96.          */
  97.      private <T> void alterCoulmns(T db,SpeSqliteTableSettingModel _old,SpeSqliteTableSettingModel _new){
  98.          for(int i=0;i<_new.columns.size();i++){
  99.              if(i>=_old.columns.size()){
  100.                  SpeSqliteColumnSettingModel column = _new.columns.get(i);
  101.                  String sql = " alter table "+_old.tableName+" add column ";
  102.                  sql+=column.key;
  103.                  sql+=" ";
  104.                  sql+= column.keyType;
  105.                  executeSQL(db,sql);
  106.              }
  107.          }
  108.      }
  109.  
  110.      /**
  111.          * 新增表
  112.          * @param db db
  113.          * @param table 表配置
  114.          * @param <T> 范型(需考虑SQLiteOpenHelper和room)
  115.          */
  116.      private <T> void createTableSQL(T db,SpeSqliteTableSettingModel table){
  117.          String sql = " create table if not exists "+table.tableName+" (";
  118.          for(int j=0;j<table.columns.size();j++){
  119.              SpeSqliteColumnSettingModel column = table.columns.get(j);
  120.              sql+=column.key+" ";
  121.              sql+=column.keyType;
  122.              if(j==table.columns.size()-1){
  123.                  sql+=")";
  124.              }else {
  125.                  sql+=",";
  126.              }
  127.          }
  128.          executeSQL(db,sql);
  129.      }

运行效果

android轻量级无侵入式管理数据库自动升级组件

项目仓库:gitee.com/hfqf1234/Sp…

以上就是android轻量级无侵入式管理数据库自动升级组件的详细内容,更多关于android数据库管理组件的资料请关注我们其它相关文章!

标签: 数据库