diff --git a/documentation-website/Writerside/snippets/exposed-dsl/README.md b/documentation-website/Writerside/snippets/exposed-dsl/README.md
index a0d437fbbe..2b72959174 100644
--- a/documentation-website/Writerside/snippets/exposed-dsl/README.md
+++ b/documentation-website/Writerside/snippets/exposed-dsl/README.md
@@ -1,8 +1,30 @@
# Exposed DSL API examples
A Gradle application that shows how to work with Exposed DSL API.
-The files are referenced in the DSL's [CRUD operations](../../topics/DSL-CRUD-operations.topic) and
-[Table types](../../topics/DSL-Table-Types.topic) topics.
+The files are referenced in the DSL's [CRUD operations](../../topics/DSL-CRUD-operations.topic),
+[Querying Data](../../topics/DSL-Querying-data.topic), [Joining tables](../../topics/DSL-Joining-tables.topic),
+and [Table types](../../topics/DSL-Table-Types.topic) topics.
+
+## Prerequisites
+
+The project contains examples that run against H2, SQLite, and MySQL databases. While H2 and SQLite make use of
+in-memory storage, in order to run queries against MySQL, you must first install MySQL and create a local database.
+
+To learn how to install MySQL, see the [installation guide](https://dev.mysql.com/doc/refman/8.4/en/installing.html).
+
+## Database configuration
+
+All database connections are configured within the `App.kt` file located in `src/main/kotlin/org/example/`.
+You might want to adjust the MySQL database configuration to match your local setup.
+
+```kotlin
+val mysqlDb = Database.connect(
+ "jdbc:mysql://localhost:3306/test",
+ driver = "com.mysql.cj.jdbc.Driver",
+ user = "root",
+ password = "password"
+ )
+```
## Build
diff --git a/documentation-website/Writerside/snippets/exposed-dsl/build.gradle.kts b/documentation-website/Writerside/snippets/exposed-dsl/build.gradle.kts
index 1f9cea56a8..301fb02a11 100644
--- a/documentation-website/Writerside/snippets/exposed-dsl/build.gradle.kts
+++ b/documentation-website/Writerside/snippets/exposed-dsl/build.gradle.kts
@@ -26,6 +26,8 @@ dependencies {
implementation(libs.exposed.jdbc)
implementation(libs.exposed.kotlin.datetime)
implementation("com.h2database:h2:2.2.224")
+ implementation("org.xerial:sqlite-jdbc:3.44.1.0")
+ implementation("mysql:mysql-connector-java:8.0.33")
}
// Apply a specific Java toolchain to ease working on different environments.
diff --git a/documentation-website/Writerside/snippets/exposed-dsl/src/main/kotlin/org/example/App.kt b/documentation-website/Writerside/snippets/exposed-dsl/src/main/kotlin/org/example/App.kt
index abfe5e0f84..b7e9ec3c58 100644
--- a/documentation-website/Writerside/snippets/exposed-dsl/src/main/kotlin/org/example/App.kt
+++ b/documentation-website/Writerside/snippets/exposed-dsl/src/main/kotlin/org/example/App.kt
@@ -1,7 +1,7 @@
package org.example
-import CreateExamples
import org.example.examples.AliasExamples
+import org.example.examples.CreateExamples
import org.example.examples.CustomSelectExamples
import org.example.examples.DeleteExamples
import org.example.examples.QueryingExamples
@@ -16,13 +16,26 @@ import org.jetbrains.exposed.sql.addLogger
import org.jetbrains.exposed.sql.transactions.transaction
fun main() {
- Database.connect(
+ val h2Db = Database.connect(
"jdbc:h2:mem:test",
"org.h2.Driver",
databaseConfig = DatabaseConfig { useNestedTransactions = true }
)
- transaction {
+ val sqliteDb = Database.connect(
+ "jdbc:sqlite:file:test?mode=memory&cache=shared",
+ "org.sqlite.JDBC",
+ databaseConfig = DatabaseConfig { useNestedTransactions = true }
+ )
+
+ val mysqlDb = Database.connect(
+ "jdbc:mysql://localhost:3306/test",
+ driver = "com.mysql.cj.jdbc.Driver",
+ user = "root",
+ password = "password",
+ )
+
+ transaction(h2Db) {
addLogger(StdOutSqlLogger)
createTables()
runCreateExamples()
@@ -30,9 +43,26 @@ fun main() {
runUpdateExamples()
runQueryingExamples()
runAliasExamples()
- runCustomSelectExamples()
runDeleteExamples()
}
+
+ transaction(sqliteDb) {
+ addLogger(StdOutSqlLogger)
+ SchemaUtils.create(StarWarsFilmsIntIdTable)
+ // run examples for insertIgnore and insertIgnoreAndGetId
+ CreateExamples().insertIgnoreRecords()
+ }
+
+ transaction(mysqlDb) {
+ addLogger(StdOutSqlLogger)
+ SchemaUtils.create(StarWarsFilmsIntIdTable)
+ SchemaUtils.create(ActorsIntIdTable)
+ runCustomSelectExamples()
+ // run examples for deleteIgnoreWhere
+ DeleteExamples().deleteIgnore()
+ // run examples for joinDelete and joinUpdate
+ DeleteExamples().joinDelete()
+ }
}
fun createTables() {
@@ -72,7 +102,6 @@ fun runUpdateExamples() {
fun runDeleteExamples() {
val deleteExamples = DeleteExamples()
deleteExamples.delete()
- deleteExamples.joinDelete()
deleteExamples.deleteAll()
}
diff --git a/documentation-website/Writerside/snippets/exposed-dsl/src/main/kotlin/org/example/examples/CreateExamples.kt b/documentation-website/Writerside/snippets/exposed-dsl/src/main/kotlin/org/example/examples/CreateExamples.kt
index fc8f57a1c6..63afe03f4f 100644
--- a/documentation-website/Writerside/snippets/exposed-dsl/src/main/kotlin/org/example/examples/CreateExamples.kt
+++ b/documentation-website/Writerside/snippets/exposed-dsl/src/main/kotlin/org/example/examples/CreateExamples.kt
@@ -1,17 +1,21 @@
+package org.example.examples
+
import org.example.tables.CitiesTable
import org.example.tables.StarWarsFilmsIntIdTable
import org.example.tables.StarWarsFilmsTable
import org.jetbrains.exposed.sql.*
/*
- Important: The SQL statements in this file are referenced by line number in `DSL-CRUD-Operations.topic`.
+ Important: The contents of this file are referenced by line number in `DSL-CRUD-Operations.topic`.
If you add, remove, or modify any lines, ensure you update the corresponding
line numbers in the `code-block` element of the referenced file.
*/
private const val MOVIE_ORIGINAL_ID = 4
-private const val MOVIE_SEQUEL_ID = 5
-private const val MOVIE_SEQUEL_2_ID = 6
+private const val MOVIE_ORIGINAL_2_ID = 5
+private const val MOVIE_ORIGINAL_3_ID = 6
+private const val MOVIE_SEQUEL_ID = 7
+private const val MOVIE_SEQUEL_2_ID = 8
class CreateExamples {
fun createFilmRecords() {
@@ -42,13 +46,13 @@ class CreateExamples {
}
fun insertIgnoreRecords() {
- StarWarsFilmsTable.insert {
+ StarWarsFilmsIntIdTable.insert {
it[sequelId] = MOVIE_SEQUEL_2_ID // column pre-defined with a unique index
it[name] = "The Last Jedi"
it[director] = "Rian Johnson"
}
- StarWarsFilmsTable.insertIgnore {
+ StarWarsFilmsIntIdTable.insertIgnore {
it[sequelId] = MOVIE_SEQUEL_2_ID
it[name] = "The Last Jedi"
it[director] = "Rian Johnson"
@@ -79,9 +83,9 @@ class CreateExamples {
data class SWFilmData(val sequelId: Int, val name: String, val director: String)
val films = listOf(
- SWFilmData(MOVIE_SEQUEL_ID, "The Empire Strikes Back", "Irvin Kershner"),
SWFilmData(MOVIE_ORIGINAL_ID, "A New Hope", "George Lucas"),
- SWFilmData(MOVIE_SEQUEL_2_ID, "Return of the Jedi", "Richard Marquand")
+ SWFilmData(MOVIE_ORIGINAL_2_ID, "The Empire Strikes Back", "Irvin Kershner"),
+ SWFilmData(MOVIE_ORIGINAL_3_ID, "Return of the Jedi", "Richard Marquand")
)
StarWarsFilmsTable.batchInsert(films) { (id, name, director) ->
diff --git a/documentation-website/Writerside/snippets/exposed-dsl/src/main/kotlin/org/example/examples/CustomSelectExamples.kt b/documentation-website/Writerside/snippets/exposed-dsl/src/main/kotlin/org/example/examples/CustomSelectExamples.kt
index e22427da4b..34f8517735 100644
--- a/documentation-website/Writerside/snippets/exposed-dsl/src/main/kotlin/org/example/examples/CustomSelectExamples.kt
+++ b/documentation-website/Writerside/snippets/exposed-dsl/src/main/kotlin/org/example/examples/CustomSelectExamples.kt
@@ -1,6 +1,6 @@
package org.example.examples
-import org.example.tables.StarWarsFilmsTable
+import org.example.tables.StarWarsFilmsIntIdTable
import org.jetbrains.exposed.sql.Query
import org.jetbrains.exposed.sql.QueryBuilder
import org.jetbrains.exposed.sql.Table
@@ -40,15 +40,21 @@ class IndexHintQuery(
class CustomSelectExamples {
fun useCustomQueryWithHint() {
- transaction {
- val originalQuery = StarWarsFilmsTable
- .selectAll()
- .withDistinct()
- .where { StarWarsFilmsTable.sequelId less MOVIE_SEQUEL_ID }
- .groupBy(StarWarsFilmsTable.id)
-
- originalQuery.indexHint("FORCE INDEX (PRIMARY)")
- .orderBy(StarWarsFilmsTable.sequelId)
- }
+ val originalQuery = StarWarsFilmsIntIdTable
+ .selectAll()
+ .withDistinct()
+ .where { StarWarsFilmsIntIdTable.sequelId less MOVIE_SEQUEL_ID }
+ .groupBy(StarWarsFilmsIntIdTable.id)
+
+ /*
+ SELECT DISTINCT star_wars_films_table.id, star_wars_films_table.sequel_id, star_wars_films_table.`name`, star_wars_films_table.director
+ FROM star_wars_films_table
+ FORCE INDEX (PRIMARY) WHERE star_wars_films_table.sequel_id < 8
+ GROUP BY star_wars_films_table.id
+ ORDER BY star_wars_films_table.sequel_id ASC
+ */
+ originalQuery.indexHint("FORCE INDEX (PRIMARY)")
+ .orderBy(StarWarsFilmsIntIdTable.sequelId)
+ .forEach { println(it[StarWarsFilmsIntIdTable.name]) }
}
}
diff --git a/documentation-website/Writerside/snippets/exposed-dsl/src/main/kotlin/org/example/examples/DeleteExamples.kt b/documentation-website/Writerside/snippets/exposed-dsl/src/main/kotlin/org/example/examples/DeleteExamples.kt
index daa1443dd0..867305319b 100644
--- a/documentation-website/Writerside/snippets/exposed-dsl/src/main/kotlin/org/example/examples/DeleteExamples.kt
+++ b/documentation-website/Writerside/snippets/exposed-dsl/src/main/kotlin/org/example/examples/DeleteExamples.kt
@@ -1,16 +1,12 @@
package org.example.examples
-import org.example.tables.ActorsTable
+import org.example.tables.ActorsIntIdTable
+import org.example.tables.StarWarsFilmsIntIdTable
import org.example.tables.StarWarsFilmsTable
-import org.jetbrains.exposed.sql.JoinType
+import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
-import org.jetbrains.exposed.sql.delete
-import org.jetbrains.exposed.sql.deleteAll
-import org.jetbrains.exposed.sql.deleteIgnoreWhere
-import org.jetbrains.exposed.sql.deleteWhere
-private const val MOVIE_SEQUEL_ID = 6
-private const val MOVIE_SEQUEL_2_ID = 7
+private const val MOVIE_SEQUEL_ID = 7
private const val ACTORS_SEQUEL_ID = 2
class DeleteExamples {
@@ -24,7 +20,7 @@ class DeleteExamples {
}
fun deleteIgnore() {
- val deleteIgnoreRowsCount = StarWarsFilmsTable.deleteIgnoreWhere { StarWarsFilmsTable.sequelId eq MOVIE_SEQUEL_2_ID }
+ val deleteIgnoreRowsCount = StarWarsFilmsIntIdTable.deleteIgnoreWhere { StarWarsFilmsIntIdTable.sequelId eq MOVIE_SEQUEL_ID }
println(deleteIgnoreRowsCount)
}
@@ -35,16 +31,27 @@ class DeleteExamples {
fun joinDelete() {
/*
- MERGE INTO ACTORS USING STAR_WARS_FILMS_TABLE
- ON STAR_WARS_FILMS_TABLE.ID = ACTORS.SEQUEL_ID
- WHEN MATCHED AND ACTORS.SEQUEL_ID > 2
- THEN DELETE
+ DELETE actors
+ FROM star_wars_films_table INNER JOIN actors
+ ON star_wars_films_table.id = actors.sequel_id
+ WHERE actors.sequel_id > 2
*/
+ StarWarsFilmsIntIdTable.insertIgnore {
+ it[sequelId] = MOVIE_SEQUEL_ID
+ it[name] = "The Force Awakens"
+ it[director] = "J.J. Abrams"
+ }
+
+ ActorsIntIdTable.insertIgnore {
+ it[id] = ACTORS_SEQUEL_ID
+ it[name] = "Harrison Ford"
+ it[sequelId] = MOVIE_SEQUEL_ID
+ }
// val simpleJoin = StarWarsFilmsTable innerJoin ActorsTable
- val join = StarWarsFilmsTable.join(ActorsTable, JoinType.INNER, StarWarsFilmsTable.id, ActorsTable.sequelId)
+ val join = StarWarsFilmsIntIdTable.join(ActorsIntIdTable, JoinType.INNER, StarWarsFilmsIntIdTable.id, ActorsIntIdTable.sequelId)
- val deletedActorsCount = join.delete(ActorsTable) { ActorsTable.sequelId greater ACTORS_SEQUEL_ID }
+ val deletedActorsCount = join.delete(ActorsIntIdTable) { ActorsIntIdTable.sequelId greater ACTORS_SEQUEL_ID }
println(deletedActorsCount)
}
}
diff --git a/documentation-website/Writerside/topics/DAO-Entity-definition.topic b/documentation-website/Writerside/topics/DAO-Entity-definition.topic
index 303c9a9a1e..aadc3e3dd3 100644
--- a/documentation-website/Writerside/topics/DAO-Entity-definition.topic
+++ b/documentation-website/Writerside/topics/DAO-Entity-definition.topic
@@ -22,11 +22,11 @@
StarWarsFilmsTable
:
The example corresponds to the following SQL statement:
- If insert
was used instead of insertIgnore
, this would throw a constraint violation exception
- Instead, this new row is ignored and discarded.
+ If insert
was used instead of insertIgnore
, this would throw a constraint
+ violation exception. Instead, this new row is ignored and discarded.
insertIgnoreAndGetId
Supported on: MySQL, PostgreSQL, and SQLite
-Table types: IntIdTable()
Supported on: MySQL, MariaDB, PostgreSQL, and SQLite
+Table types: IdTable()
@@ -87,7 +87,7 @@
include-symbol="rowId"/>
The following example uses a simple list:
Here is an example that uses a list of data class instances:
batchInsert
function will still create multiple INSERT
statements when
interacting with your database.
diff --git a/documentation-website/Writerside/topics/DSL-Querying-data.topic b/documentation-website/Writerside/topics/DSL-Querying-data.topic
index 8a22e8d725..7f0c481969 100644
--- a/documentation-website/Writerside/topics/DSL-Querying-data.topic
+++ b/documentation-website/Writerside/topics/DSL-Querying-data.topic
@@ -316,6 +316,6 @@
include-lines="4-6,9,18-39"/>