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