2.4 KiB
| type | status | owner | date | last_update |
|---|---|---|---|---|
| Guide | DRAFT | Backend Developer | 2026-02-02 | 2026-03-15 |
Database Best Practices & Exposed 1.0.0
Dieser Guide beschreibt den korrekten Umgang mit der Datenbank-Schicht in unseren Backend-Services, basierend auf JetBrains Exposed 1.0.0.
1. Architektur-Prinzipien
- Trennung: Datenbank-Zugriffe gehören ausschließlich in die
infrastructure/persistenceSchicht. Services nutzen Repositories (Interfaces), keine direkten Exposed-Aufrufe. - Transaktionen: Jede geschäftliche Operation sollte in einer Transaktion laufen. Nutze dafür die Helper aus
DatabaseUtils.kt.
2. Nutzung von DatabaseUtils
Wir haben zentrale Wrapper für Transaktionen, um Fehlerbehandlung und Logging zu vereinheitlichen.
2.1 Transaktionen starten
Nutze immer transactionResult (oder die Aliase readTransaction / writeTransaction), um Exposed-Code auszuführen.
fun findUser(id: UUID): Result<User> = readTransaction {
// 'this' ist hier eine JdbcTransaction
UserTable.select { UserTable.id eq id }
.map { /* row -> User(...) */ }
.singleOrNull()
}
Wichtig: Der Lambda-Receiver ist JdbcTransaction. Das ermöglicht Zugriff auf Low-Level JDBC Funktionen, falls nötig.
2.2 Low-Level SQL (exec, executeUpdate)
Vermeide rohes SQL, wo immer möglich. Wenn es sein muss (z.B. für Performance-Optimierungen oder spezielle Postgres-Features), beachte folgende Regeln für Exposed 1.0.0:
exec: Nutze immerexplicitStatementType.this.exec("SELECT 1", explicitStatementType = StatementType.SELECT) { rs -> /* handle ResultSet */ }executeUpdate: Nutze die Helper-MethodeDatabaseUtils.executeUpdate, da sie sich um das korrekte Schließen von Statements kümmert (ExposedPreparedStatementApiist nichtAutoCloseable).
3. Exposed 1.0.0 Besonderheiten
- UUIDs: Nutze
Table.javaUUID()fürjava.util.UUIDSpalten.Table.uuid()ist fürkotlin.uuid.Uuidreserviert. - JSONB: Bei SQLite wird JSON automatisch gewrappt. Prüfe
castToJsonFormatFlag.
4. Fehlerbehandlung
DatabaseUtils fängt SQLException ab und mappt sie auf unsere Domain-Fehler (ErrorDto):
- Duplicate Key ->
ErrorCodes.DUPLICATE_ENTRY - Foreign Key ->
ErrorCodes.FOREIGN_KEY_VIOLATION - Timeout ->
ErrorCodes.DATABASE_TIMEOUT
Wirf keine rohen Exceptions aus Repositories.