Welcome to our guide on how to utilize Krush, a lightweight persistence layer designed specifically for Kotlin developers. Leveraging the power of the Exposed SQL DSL, Krush simplifies persistent data management by enabling type-safe SQL queries while minimizing boilerplate code. In this guide, we will walk you through the installation process, provide examples, and troubleshoot common issues that may arise along the way.
What is Krush?
Krush serves as a bridge between your Kotlin data classes and database tables, generating type-safe mappings at compile-time through JPA annotation processing. This allows developers to focus on their domain logic without getting bogged down by intricate database details.
Why Use Krush?
- Type-Safe SQL DSL: No need to rely on string parsing. You can write SQL-like queries in a type-safe manner.
- Minimal Changes to Domain Model: Simply annotate your existing data classes, and Krush will handle the rest.
- Explicit Data Fetching: Control exactly which data is loaded from the database.
- No Runtime Magic: Avoid pitfalls of lazy loading or proxies; just simple data classes containing fetched data.
Installation
This section covers how to integrate Krush with your project depending on your build tool.
Using Gradle (Groovy)
repositories {
mavenCentral()
}
apply plugin: kotlin-kapt
dependencies {
api 'pl.touk.krush:krush-annotation-processor:$krushVersion'
kapt 'pl.touk.krush:krush-annotation-processor:$krushVersion'
api 'pl.touk.krush:krush-runtime:$krushVersion'
}
Using Gradle (Kotlin)
repositories {
mavenCentral()
}
plugins {
kotlin("kapt") version "$kotlinVersion"
}
dependencies {
api("pl.touk.krush:krush-annotation-processor:$krushVersion")
kapt("pl.touk.krush:krush-annotation-processor:$krushVersion")
api("pl.touk.krush:krush-runtime:$krushVersion")
}
Using Maven
<dependencies>
<dependency>
<groupId>pl.touk.krush</groupId>
<artifactId>krush-runtime</artifactId>
<version>$krush.version</version>
</dependency>
...
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<executions>
<execution>
<id>kapt</id>
<goals>
<goal>kapt</goal>
</goals>
<configuration>
...
<annotationProcessorPaths>
<annotationProcessorPath>
<groupId>pl.touk.krush</groupId>
<artifactId>krush-annotation-processor</artifactId>
<version>$krush.version</version>
</annotationProcessorPath>
</annotationProcessorPaths>
</configuration>
</execution>
</executions>
</plugin>
</dependencies>
Example of Defining Entities
Let’s take the analogy of a book (your data) stored on a shelf (your database). When you want to read a book, you need to know its precise location, which translates into storing its metadata in your database.
Here’s how you can define a Book entity that can be persisted using Krush:
@Entity
data class Book(
@Id @GeneratedValue
val id: Long? = null,
val isbn: String,
val title: String,
val author: String,
val publishDate: LocalDate
)
By annotating your data class with @Entity
and @Id
, Krush will automatically generate the necessary mappings to create a corresponding table in your database.
Persisting Data
Now that you have your Book entity defined, you can use Krush to persist it like so:
val book = Book(
isbn = "1449373321",
publishDate = LocalDate.of(2017, Month.APRIL, 11),
title = "Designing Data-Intensive Applications",
author = "Martin Kleppmann"
)
val persistedBook = BookTable.insert(book)
assertThat(persistedBook.id).isNotNull()
This code snippet effectively stores a new book record in your database.
Querying Data
With Krush, you can easily perform queries to fetch data back from your database:
val bookId = book.id ?: throw IllegalArgumentException()
val fetchedBook = BookTable
.select { BookTable.id eq bookId }
.singleOrNull()?.toBook()
assertThat(fetchedBook).isEqualTo(book)
Troubleshooting
If you encounter issues during setup or usage, consider the following troubleshooting steps:
- Ensure you’ve added all required dependencies to your build configuration.
- If you see errors related to missing annotations, double-check the placement of your JPA annotations.
- Review your data class definitions to ensure they adhere to Kotlin’s data class structure.
For more insights, updates, or to collaborate on AI development projects, stay connected with fxis.ai.
Conclusion
At fxis.ai, we believe that such advancements are crucial for the future of AI, as they enable more comprehensive and effective solutions. Our team is continually exploring new methodologies to push the envelope in artificial intelligence, ensuring that our clients benefit from the latest technological innovations.