Exposed Documentation

repository·main·Indexed 27 days ago

https://github.com/jetbrains/exposed

A lightweight SQL library for Kotlin providing a typesafe DSL and a DAO API. It supports both JDBC and R2DBC drivers, enabling seamless database engine switching. The library includes integration with Spring Boot via ExposedAutoConfiguration and a Gradle plugin for generating migration scripts.

Tokens
32.7K
Snippets
101
Records
199
Agent score
93%

What's inside Exposed

  1. Overview of Exposed ORM

    main

    Exposed is a lightweight SQL library for Kotlin that provides two distinct approaches for database access:

    1. DSL (Domain-Specific Language): A typesafe SQL-wrapping API.
    2. DAO (Data Access Object): A lightweight API for working with objects.

    It supports both JDBC and R2DBC (reactive) drivers, allowing you to switch between different database engines with minimal changes.

  2. Project structure of Exposed-Ktor-R2DBC

    main

    This project implements a project-issue tracker using Domain-Driven Design (DDD) to separate the following domains: User, Project, Issue, and Comment.

    Key components for the Issue domain include:

    • IssuesTable.kt: Defines the Exposed table object and converters.
    • IssueRepository.kt: Contains the Exposed database operations.
    • IssueService.kt: Handles service-level logic.
    • IssueRoutes.kt: Manages Ktor route handlers.

    Database connection and schema setup are configured in plugins/Database.kt.

  3. Explore Exposed usage samples

    main

    Exposed provides several sample projects demonstrating different integration patterns and use cases:

    • Ktor Integration:
      • exposed-ktor: A backend application implementing CRUD (Create, Read, Update, Delete) endpoints using Ktor and Exposed.
      • exposed-ktor-r2dbc: A backend application using Ktor, Exposed, and PostgreSQL R2DBC.
    • Spring Boot Integration:
      • exposed-spring: A Spring Boot 3 based project demonstrating CRUD operations.
    • Database Migrations:
      • exposed-migration: An application illustrating how to generate migration scripts using Exposed.
      • exposed-gradle-plugin-sample: A project demonstrating the use of the Exposed Gradle plugin and its generateMigrations task.
  4. Understand the Exposed-Ktor sample architecture

    main

    The Exposed-Ktor sample project demonstrates how to integrate Exposed with a Ktor backend for CRUD operations. The core logic is split into two main components:

    • Schema Definition: UsersSchema.kt defines the database structure using Exposed's DSL.
    • CRUD Operations: Databases.kt implements the backend logic and provides various endpoints to perform Create, Read, Update, and Delete operations.
  5. Use `exec()` and `execQuery()` with v1.0.0 changes

    main

    In version 1.0.0, the exec() method now accepts a BlockingExecutable instead of a Statement.

    Handling Query Results:

    • If you use exec(query), the lambda argument is wrapped in a ResultApi. To access the underlying java.sql.ResultSet, you must cast it: (it as JdbcResult).result.
    • To avoid casting and continue using java.sql.ResultSet directly, use execQuery(query) instead. This is recommended for explain() or DML functions like .insertReturning().
    // Option 1: Using exec() with manual casting
    transaction {
        val query = TableA.select(TableA.amount).where { TableA.amount greater 100 }
        val result = exec(query) {
            val rs = (it as JdbcResult).result
            // process rs
        }
    }
    
    // Option 2: Using execQuery() to get ResultSet directly (Recommended)
    transaction {
        val query = TableA.select(TableA.amount).where { TableA.amount greater 100 }
        val result = execQuery(query) {
            val amounts = mutableListOf<Int>()
            while (it.next()) {
                amounts += it.getInt("amount")
            }
            amounts
        }
    }
  6. Reference Exposed modules in build.gradle.kts

    main

    Once the catalog is imported, you can reference Exposed modules in your dependencies block using type-safe accessors. The accessor is generated by removing the exposed- prefix and converting dashes into nested accessors.

    dependencies {
        implementation(exposedLibs.core)
        implementation(exposedLibs.jdbc)
        implementation(exposedLibs.kotlin.datetime)
    }
  7. Run Exposed Migration sample tasks

    main

    The sample project provides Gradle tasks to automate the migration workflow:

    1. Generate the migration script: Run ./gradlew generateMigrationScript from the repository root.
    2. Apply the migration and run the project: Run ./gradlew run from the repository root.
    ./gradlew generateMigrationScript
    ./gradlew run
  8. Migrate Spring Boot dependencies for Spring Boot 4

    main

    Exposed version 1.0.0 maintains compatibility with Spring Boot 3 via exposed-spring-boot-starter.

    If you are migrating to Spring Boot 4 (Spring Framework 7), you must replace exposed-spring-boot-starter with exposed-spring-boot4-starter. This also requires updating the import path for ExposedAutoConfiguration to the v1.spring.boot4 package.

    // For Spring Boot 4 migration
    dependencies {
        implementation("org.jetbrains.exposed:exposed-spring-boot4-starter:1.0.0")
    }
    
    // Updated imports for Spring Boot 4
    import org.jetbrains.exposed.v1.spring.boot4.autoconfigure.ExposedAutoConfiguration
    import org.springframework.boot.autoconfigure.ImportAutoConfiguration
    import org.springframework.boot.autoconfigure.SpringBootApplication
    
    @SpringBootApplication
    @ImportAutoConfiguration(ExposedAutoConfiguration::class)
    class SpringApplication
  9. Update `SqlExpressionBuilder` imports

    main

    The SqlExpressionBuilder object is deprecated in version 1.0.0. Most expression builder methods have been moved to top-level functions.

    To resolve errors in lambda blocks (like those in update or where), you must now explicitly import the required top-level functions (e.g., import org.jetbrains.exposed.v1.core.and, import org.jetbrains.exposed.v1.core.eq, etc.) or use a wildcard import like import org.jetbrains.exposed.v1.core.*.

  10. Exposed System Requirements

    main

    Kotlin Version

    • Requires Kotlin 2.2.+

    JDK Requirements

    • JDK 17 or newer is required for:
      • spring-transaction (Spring Framework 6)
      • spring7-transaction (Spring Framework 7)
      • exposed-spring-boot-starter (Spring Boot 3)
      • exposed-spring-boot4-starter (Spring Boot 4)
      • exposed-crypt (Spring Security 7)
    • JDK 11 or newer is required for:
      • exposed-r2dbc
      • exposed-migration-r2dbc
    • JDK 8 or newer is required for all other modules.
  11. Add Exposed Spring Boot dependencies

    main

    Depending on your Spring Boot version, add the corresponding starter to your build script:

    • Spring Boot 4: Use org.jetbrains.exposed:exposed-spring-boot4-starter. This includes the latest Exposed version, SpringTransactionManager, and spring-boot-starter-jdbc.
    • Spring Boot 3: Use org.jetbrains.exposed:exposed-spring-boot-starter.

    Note: Support for Spring Boot 3 will be removed in the next major Exposed release.