Jetpack之Room - Qi-Ming/Read GitHub Wiki

Room

Room组成

  • Entity
  • Dao
  • Database

Entity

使用 Room 持久性库时,可以将相关字段集定义为实体。对于每个实体,系统会在关联的 Database 对象中创建一个表来存储这些项。您必须通过 Database 类中的 entities 数组引用实体类。

 @Entity(primaryKeys= {"installID, data"})
 public class UserData {
     public String installID;
     public Date date;
}

可以使用 @ForeignKey 注释定义该实体与实体的关系,如以下代码段所示:

@Entity (foreignKeys = @ForeignKey(entity = UserData.class,parentColumns = "date",childColumns = "trackDate"))
public class TrackActivity {
    public String activityName;
    public long durationTime;
    public Date trackDate;
}

使用 @Embedded 注释表示要解构到表中其子字段的对象。然后可以像查询其他各个列一样查询嵌套字段。

public class Address {
        public String street;
        public String state;
        public String city;

        @ColumnInfo(name = "post_code") public int postCode;
    }

    @Entity
    public class User {
        @PrimaryKey public int id;

        public String firstName;

        @Embedded public Address address;
    }

定义多对多的关系 要构建这种关系的模型,您需要创建下面三个对象:

  1. 播放列表的实体类。
  2. 歌曲的实体类。
  3. 用于保存每个播放列表中的歌曲相关信息的中间类。 您可以将实体类定义为独立单元:
 @Entity
    public class Playlist {
        @PrimaryKey public int id;

        public String name;
        public String description;
    }

    @Entity
    public class Song {
        @PrimaryKey public int id;

        public String songName;
        public String artistName;
    }

将中间类定义为包含对 Song 和 Playlist 的外键引用的实体:

 @Entity(tableName = "playlist_song_join",
            primaryKeys = { "playlistId", "songId" },
            foreignKeys = {
                    @ForeignKey(entity = Playlist.class,
                                parentColumns = "id",
                                childColumns = "playlistId"),
                    @ForeignKey(entity = Song.class,
                                parentColumns = "id",
                                childColumns = "songId")
                    })
    public class PlaylistSongJoin {
        public int playlistId;
        public int songId;
    }

DAO

DAO 既可以是接口,也可以是抽象类。如果是抽象类,则该 DAO 可以选择有一个以 RoomDatabase 为唯一参数的构造函数。Room 会在编译时创建每个 DAO 实现。通过使用 DAO 类(而不是查询构建器或直接查询)访问数据库,可以拆分数据库架构的不同组件。此外,借助 DAO,可以在测试应用时轻松模拟数据库访问。

public interface MyDAO {

    @Insert
    void insertActicitt(TrackActivity activity);

    @Update
    void updateActivity(TrackActivity activity);

    @Delete
    void deleteActivity(TrackActivity activity);

    @Query("SELECT * FROM TrackActivity")
    TrackActivity queryActivity();
}

Database

数据库的定义同样通过注解完成,开发人员需要定义一个继承自RoomDatabase的抽象类,并为其添加@Database注解,数据库实例化很费资源,所以选择单例模式

@Database(entities = {TrackActivity.class, UserData.class}, version = 1, exportSchema = false)
public abstract class UserDatabase extends RoomDatabase {
    private static UserDatabase INSTANCE;
    
    public abstract  MyDAO getMyDAO();
    public static UserDatabase getInstance(Context context) {
        if (INSTANCE == null) {
            synchronized (INSTANCE) {
                if (INSTANCE == null) {
                    INSTANCE = Room.databaseBuilder(context.getApplicationContext(), UserDatabase.class,"UserDataBase").build();
                }
            }
        }
        return INSTANCE;
    }
}