Библиотеки

implementation("org.jetbrains.exposed:exposed-core:$eV")
implementation("org.jetbrains.exposed:exposed-dao:$ed")
implementation("org.jetbrains.exposed:exposed-jdbc:$eV")
implementation("org.jetbrains.exposed:exposed-java-time:$eV")
implementation("com.h2database:h2:$h2Version")
implementation("ch.qos.logback:logback-classic:1.4.6")

Данные

data class Student(
    val name: String,
    val group: String,
    val id: UUID? = null
)

object StudentTable : IdTable<UUID>("students") {
    override val id: Column<EntityID<UUID>> = 
      uuid("id").entityId().uniqueIndex()
    val name: Column<String> = varchar("name", 512)
    val group: Column<String?> = varchar("group", 10).nullable()
}

Подключение

Database.connect(
  "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1", 
  driver = "org.h2.Driver"
)
transaction {
  addLogger(StdOutSqlLogger)
  SchemaUtils.create(StudentTable)
}

Создание и обновление объектов

abstract class UpdateBuilder<out T>(
  type: StatementType, 
  targets: List<Table>
) : Statement<T>(type, targets) {
  ...
  open operator fun < S> set(column: Column<S>, value: S) {
    ...
  }
}

Создание и обновление студентов

fun UpdateBuilder<Number>.save(student: Student) {
    this[StudentTable.id] = student.id ?: UUID.randomUUID()
    this[StudentTable.name] = student.name
    this[StudentTable.group] = student.group
}

Create

val students = listOf("Penny", "Amy")
  .map { Student(it, "Girls") } + listOf("Sheldon", "Leonard", 
  "Howard", "Raj").map { Student(it, "Boys") }
students.map { student ->
  StudentTable.insert { 
    // this: StudentTable, it: InsertStatement<Number>
    it.save(student) } } 

INSERT INTO STUDENTS ("GROUP", ID, "NAME") 
  VALUES ('Girls', 'c0079885-17ff-4608-ae7f-4f9da400d2e2', 'Penny')
...

Результат запроса

fun ResultRow.toStudent(): Student = Student(
    id = this[StudentTable.id].value,
    name = this[StudentTable.name],
    group = this[StudentTable.group] ?: ""
)

Read

val allQuery: Query = StudentTable.selectAll()
println("Students: ${allQuery.map { it.toStudent() }}")

SELECT STUDENTS.ID, STUDENTS."NAME", STUDENTS."GROUP" 
  FROM STUDENTS
[Penny г. Girls (c0079885-17ff-4608-ae7f-4f9da400d2e2), ...]

Read

val boysQuery = StudentTable.select {
  // this: SqlExpressionBuilder
  StudentTable.group eq "Boys"
}
println("Boys: ${boysQuery.map { it.toStudent() }}")

SELECT STUDENTS.ID, STUDENTS."NAME", STUDENTS."GROUP" 
  FROM STUDENTS WHERE STUDENTS."GROUP" = 'Boys'
[Sheldon г. Boys (e0c96001-60af-4c51-9c5f-7df79ce93acf), ...

Update

val amy = StudentTable.select {
  StudentTable.name eq "Amy"
}.first().toStudent()

StudentTable.update({
  StudentTable.name eq "Amy"
}) {
  it.save(amy.copy(name = "Amy Farrah Fowler"))
}

UPDATE STUDENTS SET "NAME"='Amy Farrah Fowler' 
  WHERE ID = 'e05e4540-2a94-42b9-9a3d-ef7bd53496d6'

Delete

StudentTable.deleteWhere {
  group eq "Boys"
}

DELETE FROM STUDENTS WHERE STUDENTS."GROUP" = 'Boys'