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

目录
  • SpeSqliteManager4Android
    • 改动日志
    • 介绍
    • 核心设计思想
    • 架构设计
    • 关配置项json:
    • 集成步骤
    • 核心代码
    • 运行效果

SpeSqliteManager4Android

改动日志

2023.2.14 完成SQLiteOpenHelper
2023.2.23 完成room
2023.2.25 完成架构重构
2023.2.26 新增架构设计图说明

介绍

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

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

核心设计思想

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

架构设计

关配置项json:

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

集成步骤

1.导入依赖库

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

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

3.SQLiteOpenHelper的调用方法

    //1.直接创建SQLiteOpenHelper
    SpeSqliteOpenHelperService.getInstance(this);
    //2.创建SQLiteOpenHelper且需要监听db
    SpeSqliteOpenHelperService.getInstance(this, new SpeSqliteBaseInterface() {
      @Override
      public <T> void onCreate(T db, RoomDatabase room) {

      }
      @Override
      public <T> void onOpen(T db, RoomDatabase room) {

      }
      @Override
      public <T> void onUpgrade(T db, int oldVersion, int newVersion, RoomDatabase room) {

       }
    });

4.Room的调用方法

    //3.直接创建room
        SpeSqliteRoomService.getInstance(this,AppDatabase.class);
    //4.创建room,且需要监听db
        SpeSqliteRoomService.getInstance(this,AppDatabase.class,new SpeSqliteBaseInterface() {
            @Override
            public <T> void onCreate(T db, RoomDatabase room) {
                //TODO  删除测试插入代码
                if(room != null){
                    ServerModel model = new ServerModel();
                    model.setId("1");
                    model.setHost("1");
                    model.setLang("1");
                    model.setName("1");
                    model.setVersion("1");
                    insert(room,model);
                }

            }
            @Override
            public <T> void onOpen(T db, RoomDatabase room) {

            }

            @Override
            public <T> void onUpgrade(T db, int oldVersion, int newVersion, RoomDatabase room) {

            }
        });

核心代码

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

  /**
     * 数据库第一次创建时的调用函数
     * @param db db
     */
    public void create(SQLiteDatabase db){
        SpeSqliteSettingModel currentDBModel = SpeSqliteUpdateManager.getInstance().currentAppDBSetting();
        for(int i=0;i<currentDBModel.dbTables.size();i++){
            SpeSqliteTableSettingModel table = currentDBModel.dbTables.get(i);
            String sql = " create table if not exists "+table.tableName+" (";
            for(int j=0;j<table.columns.size();j++){
                SpeSqliteColumnSettingModel column = table.columns.get(j);
                sql+=column.key+" ";
                sql+=column.keyType;
                if(j==table.columns.size()-1){
                    sql+=" ";
                }else {
                    sql+=",";
                }
            }
            sql+=")";
            executeSQL(db,sql);
        }
        //SQLiteDatabase数据库才需要升级本地数据配置
        if(db instanceof SQLiteDatabase){
            SQLiteDatabase _db = (SQLiteDatabase)db;
            updateConfig2DB(_db,currentDBModel);
        }
    }

    /**
     * 升级数据库,此处涉及3种改动:1.新建表 2.老表新增字段 3.删除表
     * 注意该方法会被两个数据库依次触发,所以需要控制
     * 1.新建表的处理思路:比较简单直接create即可
     * 2.老表新增字段需要遍历db中的json表字段明细和当前app中的json明细
     * @param db db
     */
    public  void upgrade(SQLiteDatabase configdb,SupportSQLiteDatabase db){
        SpeSqliteSettingModel newConfig = this.currentAppDBSetting();
        SpeSqliteSettingModel localConfig = this.getAppLoclDBSetting(configdb);
        //该处判断可以不要,但是加了后(daupdate.json的dbversion字段)效率更高
        if(localConfig.dbVersion< newConfig.dbVersion){//通过dbversion直接判断是否要升级
            //防止room数据未创建表,就alter
            if(db != null){
                for(int i=0;i<localConfig.dbTables.size();i++) {
                    SpeSqliteTableSettingModel _local = localConfig.dbTables.get(i);
                    createTableSQL(db,_local);
                }
            }
            for(int j=0;j<newConfig.dbTables.size();j++){
                SpeSqliteTableSettingModel _new = newConfig.dbTables.get(j);
                for(int i=0;i<localConfig.dbTables.size();i++){
                    SpeSqliteTableSettingModel _local = localConfig.dbTables.get(i);
                    if(_local.tableName.equals(_new.tableName)){//找到,再判断字段是否有新增
                        _local.indexed = true;//被比较过,该表不用删除
                        if(_local.columns.size()<_new.columns.size()){
                            //执行alert去新增字段 //
                            alterCoulmns(db != null?db:configdb,_local,_new);
                        }
                        break;//只要匹配到就直接跳出该层循环
                    }
                }
                //本地数据没找到这个表需要新增
                createTableSQL(db != null?db:configdb,_new);
            }
            //针对被废弃的表需要在本地库中删除
            for(int i=0;i<localConfig.dbTables.size();i++){
                SpeSqliteTableSettingModel table = localConfig.dbTables.get(i);
                if(!table.indexed){
                    dropTables(db != null?db:configdb,localConfig.dbTables.get(i));
                }
            }
            //只有当是SQLiteDatabase升级时才能本地数据配置
            if(db == null){
                updateConfig2DB(configdb,newConfig);
            }
        }
    }

    /**
     * 移除老表
     * @param db db
     * @param table table
     * @param <T> 范型(需考虑SQLiteOpenHelper和room)
     */
    private <T> void dropTables(T db,SpeSqliteTableSettingModel table){
        String sql = " DROP TABLE IF EXISTS "+table.tableName;
        executeSQL(db,sql);
    }

    /**
     * 老表新增字段
     * @param db db
     * @param _old 老表字段配置
     * @param _new 表新字段配置
     * @param <T> 范型(需考虑SQLiteOpenHelper和room)
     */
    private <T> void alterCoulmns(T db,SpeSqliteTableSettingModel _old,SpeSqliteTableSettingModel _new){
        for(int i=0;i<_new.columns.size();i++){
            if(i>=_old.columns.size()){
                SpeSqliteColumnSettingModel column = _new.columns.get(i);
                String sql = " alter table "+_old.tableName+" add column ";
                sql+=column.key;
                sql+=" ";
                sql+= column.keyType;
                executeSQL(db,sql);
            }
        }
    }

    /**
     * 新增表
     * @param db db
     * @param table 表配置
     * @param <T> 范型(需考虑SQLiteOpenHelper和room)
     */
    private <T> void createTableSQL(T db,SpeSqliteTableSettingModel table){
        String sql = " create table if not exists "+table.tableName+" (";
        for(int j=0;j<table.columns.size();j++){
            SpeSqliteColumnSettingModel column = table.columns.get(j);
            sql+=column.key+" ";
            sql+=column.keyType;
            if(j==table.columns.size()-1){
                sql+=")";
            }else {
                sql+=",";
            }
        }
        executeSQL(db,sql);
    }

运行效果

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

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

(0)

相关推荐

  • Android SQLite数据库版本升级的管理实现

    Android SQLite数据库版本升级的管理实现 我们知道在SQLiteOpenHelper的构造方法: super(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) 中最后一个参数表示数据库的版本号.当新的版本号大于当前的version时会调用方法: onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 所以我们

  • Android 通过SQLite数据库实现数据存储管理

    0 实验环境 在Android Studio中进行有关代码的编写和界面效果展示. SQLite数据库的图形化工具SQLiteStudio 下载网址:SQLiteStudio官网 1 界面展示 2 功能说明 (1)需实现一个应用可供用户进行数据的录入存储 (2)能实现基础CRUD操作,对数据进行的删.查.改等操作 (3)同时要有输入栏和结果的展示. 3 设计原理 SQLiteOpenHelper 是Android 提供的一个抽象工具类,负责管理数据库的创建.升级工作.如果我们想创建数据库,就需要自

  • Android硬件解码组件MediaCodec使用教程

    目录 1.MediaCodec 是什么 2.创建MediaCodec的方式 2.1按照格式创建 2.2按照名字创建 3.MediaCode硬件解码并进行播放实例 4.MediaCodec 异步解码进行播放 1.MediaCodec 是什么 MediaCodec类可以访问底层媒体编解码器框架(StageFright 或 OpenMAX),即编解码组件.是Android 的低层多媒体基础设施的一部分(通常与MediaExtractor.MediaSync.MediaMuxer.Image.Surfa

  • Android利用Badge组件实现未读消息小红点

    目录 前言 Badge 组件 实例 总结 前言 在 App 的运营中,活跃度是一个重要的指标,日活/月活……为了提高活跃度,就发明了小红点,然后让强迫症用户“没法活”. 小红点虽然很讨厌,但是为了 KPI,程序员也不得不屈从运营同学的逼迫(讨好),得想办法实现.这一篇,来介绍一个徽标(Badge)组件,能够快速搞定应用内的小红点. Badge 组件 Badge 组件被 Flutter 官方推荐,利用它让小红点的实现非常轻松,只需要2个步骤就能搞定. 1.引入依赖 在 pubspec.yaml文件

  • Node.js 实现简单的无侵入式缓存框架的方法

    前言 python 的flask.ext.cache 通过注解这样对方法返回结果进行缓存: @cache.cached(timeout=300, key_prefix='view_%s', unless=None) def hello(name=None): print 'view hello called' return render_template('hello.html', name=name) 这类实现方式对业务逻辑没有丝毫的侵入性,非常之优雅. 最近在做 Node.js 地项目,然而

  • 浅谈webpack下的AOP式无侵入注入

    说起来, 面向切面编程(AOP)自从诞生之日起,一直都是计算机科学领域十分热门的话题,但是很奇怪的是,在前端圈子里,探讨AOP的文章似乎并不是多,而且多数拘泥在给出理论,然后实现个片段的定式)难免陷入了形而上学的尴尬境地,本文列举了两个生产环境的实际例子论述webpack和AOP预编译处理的结合,意在抛砖引玉.当然,笔者能力有限,如果有觉得不妥之处,还请大家积极的反馈出来, 共同进步哈. 重要的概念 AOP: 面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术. Joi

  • Android帧式布局实现自动切换颜色

    本文实例为大家分享了Android帧式布局实现自动切换颜色的具体代码,供大家参考,具体内容如下 效果: 实现: activity_main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:tools="http://s

  • Python的Flask框架中使用Flask-SQLAlchemy管理数据库的教程

    使用Flask-SQLAlchemy管理数据库 Flask-SQLAlchemy是一个Flask扩展,它简化了在Flask应用程序中对SQLAlchemy的使用.SQLAlchemy是一个强大的关系数据库框架,支持一些数据库后端.提供高级的ORM和底层访问数据库的本地SQL功能. 和其他扩展一样,通过pip安装Flask-SQLAlchemy: (venv) $ pip install flask-sqlalchemy 在Flask-SQLAlchemy,数据库被指定为URL.表格列出三个最受欢

  • Android编程操作嵌入式关系型SQLite数据库实例详解

    本文实例分析了Android编程操作嵌入式关系型SQLite数据库的方法.分享给大家供大家参考,具体如下: SQLite特点 1.Android平台中嵌入了一个关系型数据库SQLite,和其他数据库不同的是SQLite存储数据时不区分类型 例如一个字段声明为Integer类型,我们也可以将一个字符串存入,一个字段声明为布尔型,我们也可以存入浮点数. 除非是主键被定义为Integer,这时只能存储64位整数 2.创建数据库的表时可以不指定数据类型,例如: 复制代码 代码如下: CREATE TAB

  • Entity Framework使用Code First模式管理数据库

    一.管理数据库连接 1.使用配置文件管理连接之约定 在数据库上下文类中,如果我们只继承了无参数的DbContext,并且在配置文件中创建了和数据库上下文类同名的连接字符串,那么EF会使用该连接字符串自动计算出数据库的位置和数据库名.比如,我们的数据库上下文定义如下: using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Text; usin

  • Android 实现无网络传输文件的示例代码

    最近的项目需要实现一个 Android 手机之间无网络传输文件的功能,就发现了 Wifi P2P(Wifi点对点)这么一个功能,最后也实现了通过 Wifi 隔空传输文件 的功能,这里我也来整理下代码,分享给大家. Wifi P2P 是在 Android 4.0 以及更高版本系统中加入的功能,通过 Wifi P2P 可以在不连接网络的情况下,直接与配对的设备进行数据交换.相对于蓝牙,Wifi P2P 的搜索速度和传输速度更快,传输距离更远 实现的效果如下所示: 客户端.png 服务器端.png 一

  • SQL SERVER 2012数据库自动备份的方法

    为了防止数据丢失,这里给大家介绍SQL SERVER2012数据自动备份的方法: 一.打开SQL SERVER 2012,如图所示: 服务器类型:数据库引擎: 服务器名称:127.0.0.1(本地),也可以选择远程连接; 身份验证:包含Windows身份验证和 SQL Server身份验证,此处选择Windows 身份验证; 二.如图,选择[管理]-->[维护计划]-->[维护计划向导]: 三.在[SQL SERVER 维护计划向导]界面,点击[下一步]: 四.填写如图所示:名称和说明,点击[

  • Android隐藏和沉浸式虚拟按键NavigationBar的实现方法

    有的时候我们在做全屏显示或者视频全屏播放时候,有些手机有底部的虚拟按键,如下图所示: 在开发中我们会遇到需要隐藏虚拟按键或者沉浸式虚拟按键的需求. 上图为沉浸式虚拟按键效果. 上图为隐藏虚拟按键效果. 那我们先说如何隐藏虚拟按键: public static void hideNavKey(Context context) { if (Build.VERSION.SDK_INT > 11 && Build.VERSION.SDK_INT < 19) { View v = ((A

  • android studio数据存储建立SQLite数据库实现增删查改

    实验目的: 分别使用sqlite3工具和Android代码的方式建立SQLite数据库.在完成建立数据库的工作后,编程实现基本的数据库操作功能,包括数据的添加.删除和更新. 实验要求: 1.创建一个学生管理的应用,基本信息包含学生姓名,班级,学号.采用数据库存储这些信息. 2.应用应该至少包含信息录入和删除功能. 3.数据显示考虑采用ListView. 实验效果: 工程结构: 源代码: DBAdapter.java package com.example.shiyan6_sqlite; impo

随机推荐