Room peristence
suggest changeRoom require four parts: Database class, DAO classes, Entity classes and Migration classes (now you may use only DDL methods):
Entity classes
// Set custom table name, add indexes @Entity(tableName = "videos", indices = {@Index("title")} ) public final class VideoItem { @PrimaryKey // required public long articleId; public String title; public String url; } // Use ForeignKey for setup table relation @Entity(tableName = "tags", indices = {@Index("score"), @Index("videoId"), @Index("value")}, foreignKeys = @ForeignKey(entity = VideoItem.class, parentColumns = "articleId", childColumns = "videoId", onDelete = ForeignKey.CASCADE) ) public final class VideoTag { @PrimaryKey public long id; public long videoId; public String displayName; public String value; public double score; }
DAO classes
@Dao public interface VideoDao { // Create insert with custom conflict strategy @Insert(onConflict = OnConflictStrategy.REPLACE) void saveVideos(List<VideoItem> videos); // Simple update @Update void updateVideos(VideoItem... videos); @Query("DELETE FROM tags WHERE videoId = :videoId") void deleteTagsByVideoId(long videoId); // Custom query, you may use select/delete here @Query("SELECT v.* FROM tags t LEFT JOIN videos v ON v.articleId = t.videoId WHERE t.value = :tag ORDER BY updatedAt DESC LIMIT :limit") LiveData<List<VideoItem>> getVideosByTag(String tag, int limit); }
Database class
// register your entities and DAOs @Database(entities = {VideoItem.class, VideoTag.class}, version = 2) public abstract class ContentDatabase extends RoomDatabase { public abstract VideoDao videoDao(); }
Migrations
public final class Migrations { private static final Migration MIGRATION_1_2 = new Migration(1, 2) { @Override public void migrate(SupportSQLiteDatabase database) { final String[] sqlQueries = { "CREATE TABLE IF NOT EXISTS `tags` (`id` INTEGER PRIMARY KEY AUTOINCREMENT," + " `videoId` INTEGER, `displayName` TEXT, `value` TEXT, `score` REAL," + " FOREIGN KEY(`videoId`) REFERENCES `videos`(`articleId`)" + " ON UPDATE NO ACTION ON DELETE CASCADE )", "CREATE INDEX `index_tags_score` ON `tags` (`score`)", "CREATE INDEX `index_tags_videoId` ON `tags` (`videoId`)"}; for (String query : sqlQueries) { database.execSQL(query); } } }; public static final Migration[] ALL = {MIGRATION_1_2}; private Migrations() { } }
Use in Application class or provide via Dagger
ContentDatabase provideContentDatabase() { return Room.databaseBuilder(context, ContentDatabase.class, "data.db") .addMigrations(Migrations.ALL).build(); }
Write your repository:
public final class ContentRepository { private final ContentDatabase db; private final VideoDao videoDao; public ContentRepository(ContentDatabase contentDatabase, VideoDao videoDao) { this.db = contentDatabase; this.videoDao = videoDao; } public LiveData<List<VideoItem>> getVideoByTag(@Nullable String tag, int limit) { // you may fetch from network, save to database .... return videoDao.getVideosByTag(tag, limit); } }
Use in ViewModel:
ContentRepository contentRepository = ...; contentRepository.getVideoByTag(tag, limit);
Found a mistake? Have a question or improvement idea?
Let me know.
Table Of Contents