美文网首页Android开发Android开发经验谈Android技术知识
Jetpack 全组件实战开发短视频应用App <三>

Jetpack 全组件实战开发短视频应用App <三>

作者: 程序员叁柒 | 来源:发表于2020-08-19 20:14 被阅读0次

    上一篇:Jetpack 全组件实战开发短视频应用App <二>

    前言

    项目地址
    这一篇我们主要介绍下Room数据库的创建以及简单使用

    Room介绍

    Room是Google为了简化SQLite推出的

    • 拥有SQLite所有的操作功能;
    • 使用简单,通过注解方式实现功能,类似Retrofit,编译时自动生成实现类
    • LiveData,LifeCycle,Paging天然融合

    Room使用

    添加依赖

     implementation "android.arch.persistence.room:runtime:1.1.1"
     annotationProcessor 'android.arch.persistence.room:compiler:1.1.1'
    
    

    使用

    我们先新建一个类CacheDatabase,同时继承RoomDatabase

    public class CacheDatabase extends RoomDatabase {
    }
    
    
    在这里插入图片描述

    这里我们看见AS提示我们需要实现RoomDatabase的一些方法,但是我们可以把这个类声明为abstract类型,为啥呢?因为我们刚才介绍过Room是通过注解实现功能,编译时用通过annotationProcessor来帮我们实现实现类,所以在我们编译的时候会生成CacheDatabase的实现类,这样我们就不用复写RoomDatabase几个默认的方法了

    public abstract class CacheDatabase extends RoomDatabase {
    
    }
    
    

    接着我们对我们这个Database进行初始化,我们还是在静态代码块中实现
    创建数据库有两种
    第一种:

     //创建一个内存数据库
     //但是这种数据库的数据只存在于内存中,也就是进程被杀之后,数据随之丢失
    Room.inMemoryDatabaseBuilder()
    
    

    这种我们一般不会使用,所以我们一般都是用下面这种方式

     Room.databaseBuilder(AppGlobals.getApplication(), CacheDatabase.class, "joke_video_cache")
    
    

    我们看下这个方法源码

     /**
         * Creates a RoomDatabase.Builder for a persistent database. Once a database is built, you
         * should keep a reference to it and re-use it.
         *
         * @param context The context for the database. This is usually the Application context.
         * @param klass   The abstract class which is annotated with {@link Database} and extends
         *                {@link RoomDatabase}.
         * @param name    The name of the database file.
         * @param <T>     The type of the database class.
         * @return A {@code RoomDatabaseBuilder<T>} which you can use to create the database.
         */
        @SuppressWarnings("WeakerAccess")
        @NonNull
        public static <T extends RoomDatabase> RoomDatabase.Builder<T> databaseBuilder(
                @NonNull Context context, @NonNull Class<T> klass, @NonNull String name) {
            //noinspection ConstantConditions
            if (name == null || name.trim().length() == 0) {
                throw new IllegalArgumentException("Cannot build a database with null or empty name."
                        + " If you are trying to create an in memory database, use Room"
                        + ".inMemoryDatabaseBuilder");
            }
            return new RoomDatabase.Builder<>(context, klass, name);
        }
    
    

    第一个参数是上下文;第二个参数是使用Database注解标记并且继承RoomDatabase的类;第三个是数据库名字
    所以我们还需要把我们这个类用Database标记下

    在这里插入图片描述

    我们需要配置三个属性,第一个就是我们要操作的类,可以是多个;第二个是数据库的版本号;第三个是存储展示数据库的结构信息,默认是true,如果设置为true,我们需要设置 Schema 的位置

    android {
        compileSdkVersion 29
        buildToolsVersion "29.0.3"
    
        defaultConfig {
           //......
            javaCompileOptions{
                annotationProcessorOptions{
                    arguments=["room.schemaLocation":"$projectDir/schemas".toString()]
                }
            }
        }
    
            //......
    }
    
    

    因为我们还没有Entity类,所以我们创建一个

    @Entity(tableName = "cache")
    public class Cache implements Serializable {
    
        @PrimaryKey(autoGenerate = false)
        public String key;
    
        @ColumnInfo(name = "data")
        public byte[] data;
    }
    
    

    这里需要使用Entity注解标记,可以给他指定表名,也可以使用默认;PrimaryKey注解的变量为主键,autoGenerate表示主键的值是否由Room自动生成,默认false;ColumnInfo表示数据控存这个属性的名字,同时我们给它指定两个属性keydata,key是我们以后查询缓存要使用的,data表示我们要缓存的数据,因为我们不确定缓存什么类型,所以统一使用二进制数组

    接着我们回到我们刚才的CacheDatabase,我们完善下它头部的注解

    @Database(entities = {Cache.class},version = 1,exportSchema = true)
    public abstract class CacheDatabase extends RoomDatabase {
    }
    
    

    我们通过Room.databaseBuilder创建出一个RoomDatabase.Builder对象,接下来我们就简单说下它的配置

         Room.databaseBuilder(AppGlobals.getApplication(), CacheDatabase.class, "joke_video_cache")
                    //是否允许在主线程进行查询
                    //.allowMainThreadQueries()
                    //数据库创建和打开后的回调
                    //.addCallback()
                    //设置查询的线程池
                    //.setQueryExecutor()
                    //.openHelperFactory()
                    //room的日志模式
                    //.setJournalMode()
                    //数据库升级异常之后的回滚
                    //.fallbackToDestructiveMigration()
                    //数据库升级异常后根据指定版本进行回滚
                    //.fallbackToDestructiveMigrationFrom()
    
    

    数据库升级

    如果我们需要进行数据库的升级,需要在配置数据库的时候调用addMigrations方法,我们先看下源码

     /**
             * Adds a migration to the builder.
             * <p>
             * Each Migration has a start and end versions and Room runs these migrations to bring the
             * database to the latest version.
             * <p>
             * If a migration item is missing between current version and the latest version, Room
             * will clear the database and recreate so even if you have no changes between 2 versions,
             * you should still provide a Migration object to the builder.
             * <p>
             * A migration can handle more than 1 version (e.g. if you have a faster path to choose when
             * going version 3 to 5 without going to version 4). If Room opens a database at version
             * 3 and latest version is &gt;= 5, Room will use the migration object that can migrate from
             * 3 to 5 instead of 3 to 4 and 4 to 5.
             *
             * @param migrations The migration object that can modify the database and to the necessary
             *                   changes.
             * @return this
             */
            @NonNull
            public Builder<T> addMigrations(@NonNull  Migration... migrations) {
                if (mMigrationStartAndEndVersions == null) {
                    mMigrationStartAndEndVersions = new HashSet<>();
                }
                for (Migration migration: migrations) {
                    mMigrationStartAndEndVersions.add(migration.startVersion);
                    mMigrationStartAndEndVersions.add(migration.endVersion);
                }
    
                mMigrationContainer.addMigrations(migrations);
                return this;
            }
    
    

    入参是多个Migration对象,我们看下Migration的构造方法

    在这里插入图片描述

    也就是说我们指定多个版本升级的操作,例如


    在这里插入图片描述

    数据库操作

    数据库操作我们需要使用Dao这个注解,这里我们新建一个CacheDao类,同时实现增,删,改,查方法,因为只有查比较麻烦,所以我们可以写一个基类BaseDao,里面含有增,删,改方法,然后我们的CacheDao,继承BaseDao

    @Dao
    public interface BaseDao<T> {
    
        @Insert(onConflict = OnConflictStrategy.REPLACE)
        void insertItem(T item);//插入单条数据
    
        @Insert(onConflict = OnConflictStrategy.REPLACE)
        void insertItems(List<T> items);//插入list数据
    
        @Delete
        void deleteItem(T item);//删除item
    
        @Update(onConflict = OnConflictStrategy.REPLACE)
        void updateItem(T item);//更新item
    }
    
    
    @Dao
    public interface CacheDao extends BaseDao<Cache>{
    
        //如果是一对多,这里可以写List<Cache>
        @Query("select *from cache where `key`=:key")
        Cache getCache(String key);
    }
    

    日行一善,多多点赞哟!微信公众号《程序猿养成中心》,关注点击更多资料,免费领取690页Android基础+架构+源码知识点汇总PDF和Android面试大纲

    相关文章

      网友评论

        本文标题:Jetpack 全组件实战开发短视频应用App <三>

        本文链接:https://www.haomeiwen.com/subject/bhfljktx.html