Sobes.tech
Junior

Na czym polega różnica między Room a SQLite?

sobes.tech AI

Odpowiedź od AI

SQLite to lekka relacyjna baza danych osadzona w Androidzie. Room to biblioteka abstrakcji nad SQLite, zapewniająca wyższopoziadowe API do pracy z bazą danych, upraszczającą interakcję i zmniejszającą prawdopodobieństwo błędów.

Główne różnice:

  • ORM: Room jest ORM (Object-Relational Mapper), pozwalającym pracować z danymi w formie klas POJO, zamiast bezpośrednio z tabelami i kolumnami.
  • Sprawdzanie podczas kompilacji: Room wykonuje sprawdzenia zapytań do bazy danych podczas kompilacji, wykrywając błędy składniowe i niezgodności typów danych przed uruchomieniem aplikacji.
  • Uproszczenie kodu: Room generuje kod boilerplate do pracy z bazą danych (np. do konwersji POJO na wiersze tabeli i odwrotnie), co znacznie zmniejsza ilość ręcznego kodu.
  • Wsparcie dla LiveData i Flow: Room integruje się z komponentami Android Architecture Components, takimi jak LiveData i Flow, upraszczając pracę z operacjami asynchronicznymi i obserwację zmian danych.
  • Migracje: Room zapewnia wygodny mechanizm do wykonywania migracji bazy danych przy zmianie schematu.

Przykład użycia Room:

// Encja
@Entity
data class User(
    @PrimaryKey val userId: Int,
    val name: String,
    val age: Int
)

// DAO (Data Access Object)
@Dao
interface UserDao {
    @Query("SELECT * FROM user")
    fun getAllUsers(): List<User>

    @Insert
    fun insertUser(user: User)
}

// Baza danych
@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

Przykład bezpośredniego użycia SQLite z SQLiteOpenHelper:

// Helper do bazy danych
class DbHelper(context: Context) : SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {

    override fun onCreate(db: SQLiteDatabase) {
        val createTableQuery = """
            CREATE TABLE users (
                _id INTEGER PRIMARY KEY AUTOINCREMENT,
                name TEXT,
                age INTEGER
            )
        """.trimIndent()
        db.execSQL(createTableQuery)
    }

    override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
        db.execSQL("DROP TABLE IF EXISTS users")
        onCreate(db)
    }

    companion object {
        private const val DATABASE_NAME = "mydatabase.db"
        private const val DATABASE_VERSION = 1
    }
}

// Przykład wstawiania danych
val dbHelper = DbHelper(context)
val db = dbHelper.writableDatabase
val values = ContentValues().apply {
    put("name", "Alice")
    put("age", 30)
}
db.insert("users", null, values)
db.close()
Charakterystyka Room SQLite (bezpośrednio)
Typ ORM (biblioteka abstrakcji) Relacyjna baza danych
Praca z danymi Obiekty (POJO) Wiersze i kolumny
Sprawdzanie Podczas kompilacji Głównie w czasie działania
Kod boilerplate Automatycznie generowany Wymaga ręcznego pisania
Integracja z AAC Tak (LiveData, Flow) Nie
Migracje Wygodny API Wymaga ręcznej implementacji
Łatwość użycia Wysoka Niższa, bardziej podatna na błędy

Użycie Room jest preferowane w większości przypadków dla nowego rozwoju, ponieważ znacznie upraszcza pracę z bazą danych, zwiększa niezawodność kodu i zmniejsza liczbę błędów. Bezpośrednie użycie SQLite może być uzasadnione w bardzo prostych przypadkach lub przy specyficznych wymaganiach, których Room nie może spełnić.