SQLDelight Kotlin : guide complet avec exemples concrets

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

SQLDelight pour Kotlin : guide complet avec exemples concrets

1. Qu'est-ce que SQLDelight et pourquoi l'utiliser ?

SQLDelight est une bibliothèque Kotlin qui génère du code Kotlin type-safe à partir de requêtes SQL. Développée par Cash App (Square), elle prend en charge Kotlin Multiplatform (KMP), ce qui permet d'utiliser le même code pour interagir avec des bases de données sur Android, iOS, JVM, JS et les plateformes natives.

Le principe fondamental de SQLDelight est simple : vous écrivez vos requêtes SQL dans des fichiers .sq, et la bibliothèque génère automatiquement des classes, interfaces et fonctions Kotlin qui correspondent parfaitement à vos requêtes. Cela élimine le besoin d'écrire du code répétitif pour mapper les résultats de requêtes en objets et prévient les injections SQL dès la compilation.

Pourquoi adopter SQLDelight ? Premièrement, elle garantit une vérification complète des types à la compilation : si vous modifiez la structure d'une table, le compilateur vous signalera immédiatement tous les endroits où les requêtes doivent être mises à jour. Deuxièmement, elle gère les migrations, les transactions, les requêtes asynchrones et le multi-plateforme. Troisièmement, elle s'intègre avec des frameworks populaires comme Ktor, Koin, Dagger/Hilt, etc.

2. Installation

SQLDelight s'installe via le système de build Gradle. Pour Kotlin Multiplatform, ajoutez le plugin suivant dans le fichier racine build.gradle.kts :

// build.gradle.kts racine
plugins {
    id("app.cash.sqldelight") version "2.0.2" apply false
}

// Dans le module (ex : :shared)
plugins {
    id("app.cash.sqldelight")
}

sqldelight {
    databases {
        create("MaBase") {
            packageName.set("com.exemple.db")
        }
    }
}

dependencies {
    implementation("app.cash.sqldelight:coroutines-extensions:2.0.2")
    implementation("app.cash.sqldelight:runtime:2.0.2")
    // Pour Android
    implementation("app.cash.sqldelight:android-driver:2.0.2")
    // Pour iOS
    implementation("app.cash.sqldelight:native-driver:2.0.2")
    // Pour JVM
    implementation("app.cash.sqldelight:sqlite-driver:2.0.2")
}

Après la synchronisation Gradle, créez le fichier src/commonMain/sqldelight/com/exemple/db/MaBase.sq (le chemin doit correspondre au packageName).

3. Démarrage rapide — exemple minimal fonctionnel

Créez le fichier MaBase.sq :

-- MaBase.sq
CREATE TABLE Personne (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    nom TEXT NOT NULL,
    age INTEGER NOT NULL
);

selectAll:
SELECT * FROM Personne;

insertPersonne:
INSERT INTO Personne(nom, age) VALUES (?, ?);

Maintenant, dans le code Kotlin :

import com.exemple.db.MaBase
import app.cash.sqldelight.db.SqlDriver
import app.cash.sqldelight.driver.jdbc.sqlite.JdbcSqliteDriver

fun main() {
    val driver: SqlDriver = JdbcSqliteDriver("jdbc:sqlite:test.db")
    MaBase.Schema.create(driver)
    
    val database = MaBase(driver)
    val queries = database.maBaseQueries
    
    // Insertion
    queries.insertPersonne("Alice", 30)
    queries.insertPersonne("Bob", 25)
    
    // Sélection
    val personnes = queries.selectAll().executeAsList()
    personnes.forEach { personne ->
        println("${personne.nom} a ${personne.age} ans")
    }
}

Ce code crée la table, insère deux enregistrements et les affiche.

4. Méthodes et classes principales

4.1 executeAsList()

Signature : fun <T> executeAsList(): List<T>

Fonctionnement : Exécute une requête SELECT et retourne toutes les lignes du résultat sous forme d'une liste d'objets du type généré.

val toutesLesPersonnes: List<Personne> = queries.selectAll().executeAsList()

4.2 executeAsOne()

Signature : fun <T> executeAsOne(): T

Fonctionnement : Exécute une requête SELECT et retourne exactement une ligne. Lève une exception si le résultat ne contient pas exactement une ligne.

val premierePersonne: Personne = queries.selectFirst().executeAsOne()

4.3 executeAsOneOrNull()

Signature : fun <T> executeAsOneOrNull(): T?

Fonctionnement : Similaire à executeAsOne(), mais retourne null si aucune ligne n'est trouvée.

val personne: Personne? = queries.selectById(42).executeAsOneOrNull()

4.4 executeAsCount()

Signature : fun executeAsCount(): Long

Fonctionnement : Exécute une requête et retourne le nombre de lignes affectées (utile pour les requêtes INSERT, UPDATE, DELETE).

val nbLignesModifiees = queries.updateAge(35, "Alice").executeAsCount()

4.5 Transactions

Fonctionnement : SQLDelight supporte les transactions via les fonctions transaction et transactionWithResult.

database.transaction {
    queries.insertPersonne("Charlie", 28)
    queries.insertPersonne("Diana", 32)
    // La transaction est automatiquement validée si aucune exception n'est levée
}

5. Conclusion

SQLDelight est un outil puissant pour tout développeur Kotlin travaillant avec des bases de données. Sa capacité à générer du code type-safe, sa prise en charge multiplateforme et son intégration transparente avec les frameworks modernes en font un choix idéal pour les projets Android, iOS et backend. En écrivant du SQL pur et en bénéficiant de la sécurité des types Kotlin, vous réduisez les bugs et accélérez le développement.

Recommendations