Sobes.tech
Middle

Come creeresti un database per un'applicazione mobile?

sobes.tech AI

Risposta dell'AI

Per creare un database locale su Android, userei Room Persistence Library.

È un'astrazione su SQLite che semplifica il lavoro con il database, fornendo un'API annotata per creare schemi, query e gestire le migrazioni.

Passaggi principali:

  1. Aggiungere le dipendenze:

    // In build.gradle (livello app)
    dependencies {
        implementation("androidx.room:room-runtime:2.6.1")
        annotationProcessor("androidx.room:room-compiler:2.6.1") // Per Java
        kapt("androidx.room:room-compiler:2.6.1") // Per Kotlin
        implementation("androidx.room:room-ktx:2.6.1") // Per le coroutine
    }
    
  2. Creare entità (Entities): POJO (Plain Old Java Object) o classi di dati che rappresentano le tabelle nel database. Le annotazioni @Entity, @PrimaryKey, @ColumnInfo sono usate per definire la struttura.

    @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. Creare DAO (Data Access Object): Interfacce che definiscono i metodi di accesso ai dati (inserimento, eliminazione, aggiornamento, query). Le annotazioni @Dao, @Insert, @Delete, @Update, @Query sono usate.

    @Dao
    interface UserDao {
        @Query("SELECT * FROM users")
        fun getAll(): List<User>
    
        @Insert
        fun insertAll(vararg users: User)
    
        @Delete
        fun delete(user: User)
    }
    
  4. Creare la classe Database: Classe astratta che estende RoomDatabase, che fornisce l'accesso al DAO e definisce lo schema del database. L'annotazione @Database indica le entità e la versione.

    @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. Lavorare con il database: Ottenere l'istanza e eseguire operazioni tramite il DAO.

    val db = AppDatabase.getDatabase(applicationContext)
    val userDao = db.userDao()
    
    // Inserimento dati (di solito in un thread di background)
    GlobalScope.launch {
        userDao.insertAll(User(firstName = "John", lastName = "Doe"))
    }
    
    // Ottenere dati
    GlobalScope.launch {
        val users = userDao.getAll()
    }
    

Vantaggi di Room:

  • Verifica delle query in fase di compilazione: Le query SQL vengono verificate durante la compilazione, riducendo gli errori a runtime.
  • Lavoro semplice con i thread: L'integrazione con le coroutine o LiveData semplifica il lavoro con i dati in background.
  • Migrazione più semplice: Fornisce strumenti per gestire le modifiche dello schema.
  • Meno codice boilerplate rispetto a SQLite nativo.

Se i requisiti sono molto specifici o piccoli, si può considerare l'uso di Shared Preferences per semplici coppie chiave-valore, ma per dati strutturati e query, Room è preferibile. Per scenari più complessi con necessità di sincronizzazione o accesso da diverse fonti (ad esempio, web), si può considerare l'uso di database cloud come Firebase Realtime Database o Firestore, ma per l'archiviazione locale, Room è la soluzione standard e raccomandata.