• 记录每天学习的新知识: Room


    前言

    Jetpack 是一个丰富的组件库,它的组件库按类别分为 4 类,分别是架构(Architecture)、界面(UI)、 行为(behavior)和基础(foundation)。

    每个组件都可以单独使用,也可以配合在一起使-用。每个组件都给用户提供了一个标准, 能够帮助开发者遵循最佳做法,减少样板代码并编写可在各种 Android 版本和设备中一致运行的代码,让开发者能够集中精力编写重要的业务代码。

    在这里插入图片描述

    Room 基本使用

    在这里插入图片描述

    这里的使用是Room + RxJava的方式,需要引用依赖:

        implementation 'androidx.room:room-runtime:2.3.0'
        implementation 'androidx.room:room-rxjava2:2.3.0'
        annotationProcessor "androidx.room:room-compiler:2.3.0"
    
    • 1
    • 2
    • 3

    同时,需要添加:

        defaultConfig {
            javaCompileOptions {
                annotationProcessorOptions {
                    arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
                }
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    方便我们查看数据库架构信息。

    在这里插入图片描述
    如果项目中已经存在 javaCompileOptions 定义arguments 内容,可以写一起:

            javaCompileOptions {
                annotationProcessorOptions {
                    arguments = [AROUTER_MODULE_NAME: project.getName(),"room.schemaLocation": "$projectDir/schemas".toString()]
                }
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    Book 是我们需要的JavaBean
    BookDao 是对Book操作的封装(增删减查)
    AppDatabase 是数据库的创建和更新
    RoomActivity 是调用的地方

    Book - @Entity

    @Entity(tableName = "book_table")
    public class Book {
    
        public Book() {
        }
    
        @Ignore
        public Book(Long uid) {
            this.uid = uid;
        }
    
        @PrimaryKey(autoGenerate = true)
        @ColumnInfo(name = "uid")
        private Long uid;
    
        private String name;
        private String address;
    
        public Long getUid() {
            return uid;
        }
    
        public void setUid(Long uid) {
            this.uid = uid;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    BookDao - @Dao

    @Dao
    public interface BookDao {
    
        /**
         * 插入
         *
         * @param books 书籍
         * @return Id
         */
        @Insert(onConflict = OnConflictStrategy.REPLACE)
        Single<List<Long>> insert(Book... books);
    
    
        /**
         * 请求
         *
         * @return 所有 书
         */
        @Query("SELECT * from book_table")
        Single<List<Book>> queryAll();
    
    
        int QUERY_BOOK_LENGTH = 2;
    
        /**
         * 查询书籍 多少本 =  {@link QUERY_BOOK_LENGTH}
         *
         * @param start 开始位置
         * @return {@link QUERY_BOOK_LENGTH} 本书籍
         */
        @Query("SELECT * FROM book_table LIMIT :start," + QUERY_BOOK_LENGTH)
        Single<List<Book>> query2(int start);
    
    
        /**
         * 查询指定名字
         *
         * @param name 书籍名称
         * @return 查询到的所有书
         */
    
        @Query("select * from book_table where name =:name")
        Single<List<Book>> queryName(String name);
    
    
        /**
         * 更新
         *
         * @param books 书籍
         * @return 1是成功,0是失败
         */
        @Update
        Single<Integer> update(Book... books);
    
        /**
         * 通过主键删除某个
         *
         * @param books 书籍
         * @return 成功删除的数量
         */
        @Delete
        Single<Integer> delete(Book... books);
    
        /**
         * 从表中删除所有
         *
         * @return 成功删除的数量
         */
        @Query("DELETE FROM book_table")
        Single<Integer> deleteAll();
    
        /**
         * 删除指定名字
         *
         * @param name 书籍名称
         * @return 成功删除的数量
         */
    
        @Query("delete from book_table where name =:name")
        Single<Integer> deleteName(String name);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82

    AppDatabase - @Database

    @Database(entities = {Book.class}, version = 1)
    public abstract class AppDatabase extends RoomDatabase {
    
        public abstract BookDao bookDao();
    
        private static volatile AppDatabase database;
    
        public static AppDatabase getInstance(Context context) {
            if (database == null) {
                synchronized (AppDatabase.class) {
                    if (database == null) {
                        database = Room.databaseBuilder(context.getApplicationContext(), AppDatabase.class, "book.db").build();
                    }
                }
            }
            return database;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    RoomActivity - 调用

    @Route(path = "/main/RoomActivity")
    public class RoomActivity extends BaseActivity {
    
        int query_start = 0;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            setContentView(R.layout.activity_room);
    
            rxViewGcUtil.add(RxView.clicks(findViewById(R.id.btn_insert))
                    .throttleFirst(1, TimeUnit.SECONDS)
                    .subscribe(unit -> {
                        Book book = new Book();
                        book.setName("哈利波特");
    
                        Disposable disposable =
                                AppDatabase.getInstance(this).bookDao()
                                        .insert(book)
                                        .subscribeOn(Schedulers.io())
                                        .observeOn(AndroidSchedulers.mainThread())
                                        .subscribe(new Consumer<List<Long>>() {
                                            @Override
                                            public void accept(List<Long> longs) throws Exception {
                                                AppLogUtils.i(TAG, "insert longs==" + new Gson().toJson(longs));
                                            }
                                        });
    
                    }));
    
            rxViewGcUtil.add(RxView.clicks(findViewById(R.id.btn_query))
                    .throttleFirst(1, TimeUnit.SECONDS)
                    .subscribe(unit -> {
                        Disposable disposable =
                                AppDatabase.getInstance(this).bookDao()
                                        .queryAll()
                                        .subscribeOn(Schedulers.io())
                                        .observeOn(AndroidSchedulers.mainThread())
                                        .subscribe(new Consumer<List<Book>>() {
                                            @Override
                                            public void accept(List<Book> books) throws Exception {
                                                AppLogUtils.i(TAG, "queryAll books==" + new Gson().toJson(books));
                                            }
                                        });
    
                    }));
    
            rxViewGcUtil.add(RxView.clicks(findViewById(R.id.btn_query_2))
                    .throttleFirst(1, TimeUnit.SECONDS)
                    .subscribe(unit -> {
                        Disposable disposable =
                                AppDatabase.getInstance(this).bookDao()
                                        .query2(query_start)
                                        .subscribeOn(Schedulers.io())
                                        .observeOn(AndroidSchedulers.mainThread())
                                        .subscribe(new Consumer<List<Book>>() {
                                            @Override
                                            public void accept(List<Book> books) throws Exception {
                                                query_start = query_start + QUERY_BOOK_LENGTH;
                                                AppLogUtils.i(TAG, "queryAll books==" + new Gson().toJson(books));
                                            }
                                        });
    
                    }));
    
            rxViewGcUtil.add(RxView.clicks(findViewById(R.id.btn_query_name))
                    .throttleFirst(1, TimeUnit.SECONDS)
                    .subscribe(unit -> {
                        Disposable disposable =
                                AppDatabase.getInstance(this).bookDao()
                                        .queryName("哈利波特")
                                        .subscribeOn(Schedulers.io())
                                        .observeOn(AndroidSchedulers.mainThread())
                                        .subscribe(new Consumer<List<Book>>() {
                                            @Override
                                            public void accept(List<Book> books) throws Exception {
                                                AppLogUtils.i(TAG, "queryName books==" + new Gson().toJson(books));
                                            }
                                        });
                    }));
    
            rxViewGcUtil.add(RxView.clicks(findViewById(R.id.btn_update))
                    .throttleFirst(1, TimeUnit.SECONDS)
                    .subscribe(unit -> {
    
                        Book book = new Book();
                        book.setName("哈利波特2");
                        book.setUid(12L);
                        book.setAddress("美丽国是NC");
    
                        Disposable disposable =
                                AppDatabase.getInstance(this).bookDao()
                                        .update(book)
                                        .subscribeOn(Schedulers.io())
                                        .observeOn(AndroidSchedulers.mainThread())
                                        .subscribe(new Consumer<Integer>() {
                                            @Override
                                            public void accept(Integer integer) throws Exception {
                                                AppLogUtils.i(TAG, "update longs==" + new Gson().toJson(integer));
                                            }
                                        });
    
                    }));
    
            rxViewGcUtil.add(RxView.clicks(findViewById(R.id.btn_delete))
                    .throttleFirst(1, TimeUnit.SECONDS)
                    .subscribe(unit -> {
    
                        Book book = new Book();
                        book.setUid(1L);
    
                        Book[] books = new Book[]{new Book(102L),new Book(103L)};
    
                        Disposable disposable =
                                AppDatabase.getInstance(this).bookDao()
                                        .delete(books)
                                        .subscribeOn(Schedulers.io())
                                        .observeOn(AndroidSchedulers.mainThread())
                                        .subscribe(new Consumer<Integer>() {
                                            @Override
                                            public void accept(Integer integer) throws Exception {
                                                AppLogUtils.i(TAG, "delete longs==" + new Gson().toJson(integer));
                                            }
                                        });
    
                    }));
    
            rxViewGcUtil.add(RxView.clicks(findViewById(R.id.btn_delete_all))
                    .throttleFirst(1, TimeUnit.SECONDS)
                    .subscribe(unit -> {
    
                        Disposable disposable =
                                AppDatabase.getInstance(this).bookDao()
                                        .deleteAll()
                                        .subscribeOn(Schedulers.io())
                                        .observeOn(AndroidSchedulers.mainThread())
                                        .subscribe(new Consumer<Integer>() {
                                            @Override
                                            public void accept(Integer integer) throws Exception {
                                                AppLogUtils.i(TAG, "delete longs==" + new Gson().toJson(integer));
                                            }
                                        });
    
                    }));
    
            rxViewGcUtil.add(RxView.clicks(findViewById(R.id.btn_delete_name))
                    .throttleFirst(1, TimeUnit.SECONDS)
                    .subscribe(unit -> {
    
                        Disposable disposable =
                                AppDatabase.getInstance(this).bookDao()
                                        .deleteName("哈利波特")
                                        .subscribeOn(Schedulers.io())
                                        .observeOn(AndroidSchedulers.mainThread())
                                        .subscribe(new Consumer<Integer>() {
                                            @Override
                                            public void accept(Integer integer) throws Exception {
                                                AppLogUtils.i(TAG, "deleteName longs==" + new Gson().toJson(integer));
                                            }
                                        });
    
                    }));
    
    
        }
    
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169

    Room 相关API

    使用@Entity创建表(数据实体)

    • 设置表名
    @Entity(tableName = "table_book")
    
    • 1
    • 主键
        @NonNull    //主键不能为null
        @PrimaryKey(autoGenerate = true)    //主键是否自动增长,默认为false
        private int id;
    
    • 1
    • 2
    • 3

    设置增长后,默认uid会从1开始向上加,如果有最大值是99(人为插入),那么下一个默认值从100开始

    • 复合键
      如果你需要通过多个列的组合来唯一标识实体的实例,你可以通过在 @Entity 的 primaryKeys 属性中列出这些列来定义复合主键:
    @Entity(tableName = "users",primaryKeys = {"mName","mAge"})
    public class User {
        public String mName;
        public int mAge;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 字段重命名
        @ColumnInfo(name = "firstName")
        private int first;	
    
    • 1
    • 2

    可以通过设置name =xxx 的方式重新命名字段

    • 嵌套类
      这个注解可以将普通JavaBan中的字段也引入到对应的表中,查询结果会自动为对应的bean。使用此注解将实现嵌套类的直接存储。
    @Entity(tableName = "book_table")
    public class Book {
    
        public Book() {
        }
    
    
        @Embedded
        private Chapter chapter;
    
        public Chapter getChapter() {
            return chapter;
        }
    
        public void setChapter(Chapter chapter) {
            this.chapter = chapter;
        }
    
    	...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    Chapter 类不需要额外处理,只需要添加Set/get方法

    • 忽略构造函数 和 忽略字段

    对于构造函数来讲,每个表对应的JavaBean只能有一个主构造方法,若还有其它的构造方法则必须使用@Ignore注解进行标识

    @Entity(tableName = "book_table")
    public class Book {
    
        public Book() {
        }
    
        @Ignore
        public Book(Long uid) {
            this.uid = uid;
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    对于字段来讲,如果你想哪个字段不映射到数据库中存储起来,即可设置

        @Ignore
        private String age;
    
    • 1
    • 2

    使用@Dao,创建操作数据库的接口(数据访问对象)

    DAO 负责定义访问数据库的方法。使用 Room,我们不需要所有与 Cursor 相关的代码,只需使用 UserDao 类中的注释定义我们的查询即可。每个 DAO 都包含提供对应用程序数据库的抽象访问的方法。在编译时,Room 会自动生成您定义的 DAO 的实现。

    你可以将 DAO 定义为接口或抽象类。对于基本用例,通常应该使用接口。无论哪种情况,都必须使用 @Dao 注释你的 DAO。DAO 没有属性,但它们确实定义了一种或多种方法来与应用程序数据库中的数据进行交互。

    使用@Database,创建数据库

    存储位置

    数据库保存路径为应用的内部存储空间:/data/data/com.yoshin.tsp/databases/book.db

    在这里插入图片描述
    在这里插入图片描述

    升级

    • 数据库升级 填字段:
    @Database(entities = {Book.class}, version = 2)
    public abstract class AppDatabase extends RoomDatabase {
    
        public abstract BookDao bookDao();
    
        private static volatile AppDatabase database;
    
        public static AppDatabase getInstance(Context context) {
            if (database == null) {
                synchronized (AppDatabase.class) {
                    if (database == null) {
                        database = Room.databaseBuilder(context.getApplicationContext(), AppDatabase.class, "book.db")
                                .addMigrations(MIGRATION_1_2)
                                .build();
                    }
                }
            }
            return database;
        }
    
        /**
         * 数据库版本从1升至2,且在 book_table 表单中增添 issueTime、version 字段
         */
        static final Migration MIGRATION_1_2 = new Migration(1, 2) {
            @Override
            public void migrate(@NonNull SupportSQLiteDatabase database) {
                database.execSQL("ALTER TABLE  book_table  ADD COLUMN issueTime TEXT Default \"\" ");
                database.execSQL("ALTER TABLE book_table ADD COLUMN version INTEGER NOT NULL DEFAULT 0");
            }
        };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    向表中添加字段 issueTime 、version ,同时赋予默认值

    另外,向表中添加实体类的写法不会写,记录一下~,请大佬给指点下

    • 数据库升级 填新表:

    Entity:

    @Entity(tableName = "stationery_table")
    public class Stationery {
    
        @NonNull
        @PrimaryKey(autoGenerate = true)
        private int id;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        private String name;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    Dao:

    @Dao
    public interface StationeryDao {
    
        /**
         * 插入
         *
         * @param stationeries 文具
         * @return Id
         */
        @Insert(onConflict = OnConflictStrategy.REPLACE)
        Single<List<Long>> insert(Stationery... stationeries);
    
        /**
         * 请求
         *
         * @return 所有 书
         */
        @Query("SELECT * from stationery_table")
        Single<List<Stationery>> queryAll();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    Database:

    @Database(entities = {Book.class, Stationery.class}, version = 3)
    public abstract class AppDatabase extends RoomDatabase {
    
        public abstract BookDao bookDao();
    
        public abstract StationeryDao stationeryDao();
    
        private static volatile AppDatabase database;
    
        public static AppDatabase getInstance(Context context) {
            if (database == null) {
                synchronized (AppDatabase.class) {
                    if (database == null) {
                        database = Room.databaseBuilder(context.getApplicationContext(), AppDatabase.class, "book.db")
    //                            .addMigrations(MIGRATION_1_2)
                                .addMigrations(MIGRATION_1_2, MIGRATION_2_3)
                                .build();
                    }
                }
            }
            return database;
        }
    
        /**
         * 数据库版本从1升至2,且在 book_table 表单中增添 issueTime、version 字段
         */
        static final Migration MIGRATION_1_2 = new Migration(1, 2) {
            @Override
            public void migrate(@NonNull SupportSQLiteDatabase database) {
                database.execSQL("ALTER TABLE  book_table  ADD COLUMN issueTime TEXT Default \"\" ");
                database.execSQL("ALTER TABLE book_table ADD COLUMN version INTEGER NOT NULL DEFAULT 0");
            }
        };
    
        static final Migration MIGRATION_2_3 = new Migration(2, 3) {
            @Override
            public void migrate(SupportSQLiteDatabase database) {
                database.execSQL("CREATE TABLE stationery_table " +
                                "(id INTEGER PRIMARY KEY  NOT NULL," +
                                " name TEXT" +
                                ")"
                );
            }
        };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    调用:

            rxViewGcUtil.add(RxView.clicks(findViewById(R.id.btn_insert_c))
                    .throttleFirst(1, TimeUnit.SECONDS)
                    .subscribe(unit -> {
    
                        Stationery stationery = new Stationery();
                        stationery.setName("文具盒");
    
                        Disposable disposable =
                                AppDatabase.getInstance(this).stationeryDao()
                                        .insert(stationery)
                                        .subscribeOn(Schedulers.io())
                                        .observeOn(AndroidSchedulers.mainThread())
                                        .subscribe(new Consumer<List<Long>>() {
                                            @Override
                                            public void accept(List<Long> longs) throws Exception {
                                                AppLogUtils.i(TAG, "insert longs==" + new Gson().toJson(longs));
                                            }
                                        });
    
                    }));
    
            rxViewGcUtil.add(RxView.clicks(findViewById(R.id.btn_query_c))
                    .throttleFirst(1, TimeUnit.SECONDS)
                    .subscribe(unit -> {
                        Disposable disposable =
                                AppDatabase.getInstance(this).stationeryDao()
                                        .queryAll()
                                        .subscribeOn(Schedulers.io())
                                        .observeOn(AndroidSchedulers.mainThread())
                                        .subscribe(new Consumer<List<Stationery>>() {
                                            @Override
                                            public void accept(List<Stationery> stationeries) throws Exception {
                                                AppLogUtils.i(TAG, "queryAll stationeries==" + new Gson().toJson(stationeries));
                                            }
                                        });
    
                    }));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    扩展

    还有其他的依赖可以配合 room 使用,先记录

    
     
        // optional - Guava support for Room, including Optional and ListenableFuture
        implementation "android.arch.persistence.room:guava:$room_version"
     
        // Test helpers
        testImplementation "android.arch.persistence.room:testing:$room_version"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    参考地址

    转自 Android Jetpack架构全家桶,学完可从零搭建一个Android项目架构:http://px.sxjnk.cn/enjoy/advertorial/article_6

    Room数据库学习记录:https://blog.csdn.net/qq_52332769/article/details/122960808

    Android 数据存储(四)-Room
    :https://blog.csdn.net/g984160547/article/details/122825287

    Room官方文档(翻译)0.概览:https://juejin.cn/post/6844903987230015496

  • 相关阅读:
    适配器模式 ( Adapter Pattern )(6)
    postgresql:记录表膨胀引起的io问题的处理
    考研政治(一)马克思原理
    【vue-upload】表单中自定义头像上传,或手动上传
    Flutter和iOS混编详解
    环保行业智能供应商管理系统精细化管理助推环保企业创新发展
    Windows启用Hyper-V详细安装Centos7教程
    yml中无法解析类 ‘HikariDataSource‘
    VUE(5) : vue-element-admin[5] : 打包及nginx部署
    IO和进程day08(消息队列、共享内存、信号灯集)
  • 原文地址:https://blog.csdn.net/weixin_35691921/article/details/126108033