Sobes.tech
Middle

Jak utworzyłbyś bazę danych dla aplikacji mobilnej?

sobes.tech AI

Odpowiedź od AI

Aby utworzyć lokalną bazę danych na Androidzie, użyłbym Room Persistence Library.

Jest to abstrakcja nad SQLite, która upraszcza pracę z bazą danych, zapewniając opatrzone adnotacjami API do tworzenia schematów, zapytań i zarządzania migracjami.

Główne kroki:

  1. Dodanie zależności:

    // W build.gradle (na poziomie aplikacji)
    dependencies {
        implementation("androidx.room:room-runtime:2.6.1")
        annotationProcessor("androidx.room:room-compiler:2.6.1") // Dla Java
        kapt("androidx.room:room-compiler:2.6.1") // Dla Kotlin
        implementation("androidx.room:room-ktx:2.6.1") // Dla korutyn
    }
    
  2. Tworzenie encji (Entities): POJO (Plain Old Java Object) lub klasy danych reprezentujące tabele w bazie danych. Adnotacje @Entity, @PrimaryKey, @ColumnInfo służą do określenia struktury.

    @Entity(tableName = "users")
    data class User(
        @PrimaryKey(autoGenerate = true) val id: Int = 0,
        @ColumnInfo(name = "first_name") val firstName: String?,
        @ColumnInfo(name = "last_name") val lastName: String?
    )
    
  3. Tworzenie DAO (Data Access Objects): Interfejsy określające metody dostępu do danych (wstawianie, usuwanie, aktualizacja, zapytania). Adnotacje @Dao, @Insert, @Delete, @Update, @Query są używane.

    @Dao
    interface UserDao {
        @Query("SELECT * FROM users")
        fun getAll(): List<User>
    
        @Insert
        fun insertAll(vararg users: User)
    
        @Delete
        fun delete(user: User)
    }
    
  4. Tworzenie klasy bazy danych: Klasa abstrakcyjna dziedzicząca po RoomDatabase, zapewniająca dostęp do DAO i określająca schemat bazy danych. Adnotacja @Database wskazuje encje i wersję.

    @Database(entities = [User::class], version = 1)
    abstract class AppDatabase : RoomDatabase() {
        abstract fun userDao(): UserDao
    
        companion object {
            @Volatile
            private var INSTANCE: AppDatabase? = null
    
            fun getDatabase(context: Context): AppDatabase {
                return INSTANCE ?: synchronized(this) {
                    val instance = Room.databaseBuilder(
                        context.applicationContext,
                        AppDatabase::class.java,
                        "app_database"
                    ).build()
                    INSTANCE = instance
                    instance
                }
            }
        }
    }
    
  5. Praca z bazą danych: Uzyskanie instancji i wykonywanie operacji przez DAO.

    val db = AppDatabase.getDatabase(applicationContext)
    val userDao = db.userDao()
    
    // Wstawianie danych (zwykle w tle)
    GlobalScope.launch {
        userDao.insertAll(User(firstName = "John", lastName = "Doe"))
    }
    
    // Pobieranie danych
    GlobalScope.launch {
        val users = userDao.getAll()
    }
    

Zalety Room:

  • Weryfikacja zapytań podczas kompilacji: Zapytania SQL są sprawdzane podczas kompilacji, co zmniejsza liczbę błędów w czasie działania.
  • Łatwa praca z wątkami: Integracja z korutynami lub LiveData upraszcza pracę z danymi w tle.
  • Łatwiejsza migracja: Dostarcza narzędzi do zarządzania zmianami schematu.
  • Mniej kodu szablonowego w porównaniu do natywnego SQLite.

Jeśli wymagania są bardzo specyficzne lub małe, można rozważyć użycie Shared Preferences dla prostych par klucz-wartość, ale dla danych strukturalnych i zapytań Room jest preferowany. Dla bardziej złożonych scenariuszy z potrzebą synchronizacji lub dostępem z różnych źródeł (np. web), można rozważyć użycie baz danych w chmurze, takich jak Firebase Realtime Database lub Firestore, ale dla lokalnego przechowywania Room jest standardowym i zalecanym rozwiązaniem.