Room verwenden - No bullshit / TLDR
- 2 Minuten - 366 WörterLeider sind die meisten Tutorials oder Blog Posts für blutige Anfänger geschrieben und als Senior Developer muss man sich erst durch die langatmigen Einleitungen wühlen. Ich habe deswegen die Kategorie “No bullshit / TLDR” ins Leben gerufen. Hier erläutere ich kurz und knackig wie ein Feature oder eine Library verwendet wird.
Room Tutorial
Thema heute: Erweitere in diesem Tutorial deine Android App um eine Room Datenbank mit nur 6 Schritten.
Abhängigkeiten hinzufügen
implementation "androidx.room:room-runtime:2.1.0-rc01"
kapt "androidx.room:room-compiler:2.1.0-rc01"
Für testing:
testImplementation "androidx.room:room-testing:2.2.5"
Falls RxJava verwendet werden soll:
implementation "androidx.room:room-rxjava2:2.1.0-rc01"
Aktuelle Versionsnummer hier oder Quick-Fix in Android Studio verwenden.
DataModel erstellen
Annotierte data class (Kotlin):
@Entity(tableName = "workout")
data class WorkoutDataModel(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "workout_id", index = true) var workoutId: Int,
@ColumnInfo(name = "text") var text: String,
@ColumnInfo(name = "favorite") var favorite: Boolean
)
Eventuelle foreign-keys werden in der @Entity Annotation definiert. Beispiel: result ist einem workout zugeordnet:
@Entity(tableName = "result", foreignKeys =[ForeignKey(entity = WorkoutDataModel::class, parentColumns = ["workout_id"], childColumns = ["workout_id"], onDelete = ForeignKey.CASCADE)])
DAO
Ist ein simples Interface mit Annotationen
@Dao
interface WorkoutDao{
@Query("SELECT * FROM table")
fun getWorkoutList(): List<WorkoutDataModel>
@Insert(onConflict = OnConflictStrategy.ABORT)
fun insertWorkout(workoutDataModel: WorkoutDataModel)
@Query("SELECT * FROM workout WHERE workout_id = :workoutId")
fun getWorkoutById(workoutId: Int): WorkoutDataModel
@Update
fun updateWorkout(workoutDataModel: WorkoutDataModel)
@Delete
fun deleteWorkout(workoutDataModel: WorkoutDataModel)
}
Database Klasse
@Database(entities = [WorkoutDataModel::class, ResultDataModel::class], version = 1)
@TypeConverters(Converters::class)
abstract class AppDatabase : RoomDatabase() {
abstract fun workoutDao(): WorkoutDao
abstract fun resultDao(): ResultDao
companion object {
@Volatile private var INSTANCE: AppDatabase? = null
fun getInstance(context: Context): AppDatabase =
INSTANCE ?: synchronized(this) {
INSTANCE ?: buildDatabase(context).also { INSTANCE = it }
}
private fun buildDatabase(context: Context) =
Room.databaseBuilder(context.applicationContext,
AppDatabase::class.java, "workoutlog.db")
.addMigrations(MIGRATION_1_2)
.allowMainThreadQueries()
.build()
}
Wird dann über einen Context erzeugt.
Konvertierungen
Komplexe Datenklassen müssen auf primitive Typen heruntergebrochen werden. Beispiel: Date -> Long
class Converters {
@TypeConverter
fun fromTimestamp(value: Long?): Date? {
return value?.let { Date(it) }
}
@TypeConverter
fun dateToTimestamp(date: Date?): Long? {
return date?.time?.toLong()
}
}
Converters werden der Database Klasse über die Annotation @TypeConverters(Converters::class)
hinzugefügt.
Migrationen
Beim Erstellen der Datenbank werden Migrations
-Anweisungen hinzugefügt (siehe Database Klasse):
val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE workout ADD COLUMN favorite INTEGER DEFAULT 0 NOT NULL")
}
}
Viel Spaß mit Room!