Thanks to visit codestin.com
Credit goes to github.com

Skip to content

🚀 A modern ORM framework designed for Kotlin based on the compiler plugin, which is suitable for both backend and mobile applications, support multi-database. Powerful, high performance, easy to use.

Notifications You must be signed in to change notification settings

Kronos-orm/Kronos-orm

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

933 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

logo


Kronos-ORM

English | 简体中文

A modern ORM framework designed for Kotlin.

Kronos is a modern ORM framework designed for Kotlin based on the compiler plugin, which is suitable for both backend and mobile applications, support multi-database. Powerful, high performance, easy to use.

Based on the KCP implementation of expression tree parsing and concatenation, Kronos has powerful performance, expressiveness, and a concise, semantic writing style, make the operation of the database has become more simple.

Kotlin Awesome Kotlin Badge License

Codacy Badge Coverage Coverage Coverage

CI CI CI CI CI

Maven Central Maven Central Snapshots

Official Website | Documentation | Getting Started (Repo) | Discord | QQ群


Re-define KotlinORM

❓ Why Kronos?

  • Leverages the full JVM ecosystem (drivers, logging, pools) and is designed with future Kotlin Multiplatform in mind.
  • Compiler-plugin powered and coroutine-friendly. Absolutely no reflection at runtime for core operations, enabling high performance and low GC overhead.
  • Concise, expressive Kotlin-first DSL using native operators ==, >, <, in, etc. (not .eq, .gt, .lt). Strong static typing everywhere.
  • Rich features out of the box: transactions, cross-database queries, schema create/sync (tables/indexes/comments), serialization/deserialization, and powerful cascading without FKs (one-to-one / one-to-many / many-to-many).
  • Built-ins: logical deletion, optimistic lock, create/update timestamps; all customizable.
  • Easy to integrate with any stack (Spring, Ktor, Vert.x, Solon, Android). See example projects below.
  • Native SQL with named parameters when you need full control.
  • Compile-time mappers to/from Map and meta APIs for KPojo with near-zero overhead.

Developer Docs

  • Looking for architecture diagrams, module internals, and deep‑dive guides? See the Developer Docs.
  • Who should read this:
    • Contributors and maintainers extending or modifying Kronos.
    • Advanced users who want to understand internals and design trade‑offs.
    • Integrators and plugin authors building logging/JDBC/codegen extensions or embedding Kronos into your platform.

Simple Example

Here are some of the simplest examples showing how to use Kronos-ORM for database operations.

// Define a data class extending KPojo
data class User(
    @PrimaryKey(identity = true) val id: Long? = null,
    val username: String? = null,
    val age: Int? = null
) : KPojo

// We can use dataSource.table.createTable<User>() to create the table,
// or dataSource.table.syncTable<User>() to synchronize the table structure.
dataSource.table.createTable<User>()

// Insert a record into table `user` (username = "test", age = 18), and get the id of the inserted record
// we can use List<User>.insert().execute() to batch insert
val id = User(username = "test", age = 18).insert().execute().lastInsertId

// Query records from table `user` where `age` is 18
val listOfUser = User(age = 18).select().queryList()

// Update records in table `user` where `id` is lastInsertId, set `age` to 19
User(id = id, age = 19).update().by { it.id }.execute()

// Delete records from table `user` where `id` is lastInsertId
User(id = id).delete().execute()

🖥 JDK、Kotlin and Build Tools

  • JDK 8+
  • Kotlin 2.1.0+
  • Maven 3.6.3+ or Gradle 6.8.3+

Please make sure your kotlin plugin for ide supports kotlin 2.1.0 or higher.

If you built failed in Intellij IDEA and build with Maven, please try to enable the following setting: Settings / Build, Execution, Deployment / Build Tools / Maven / Runner / Delegate IDE build/run actions to Maven.


📦 Installation

Gradle(kts)

Details
plugins {
  id("com.kotlinorm.kronos-gradle-plugin") version "0.0.5"
}

dependencies {
    implementation("com.kotlinorm:kronos-core:0.0.5")
}

Gradle(groovy)

Details
plugins {
  id 'com.kotlinorm.kronos-gradle-plugin' version '0.0.5'
}

dependencies {
    implementation 'com.kotlinorm:kronos-core:0.0.5'
}

Maven

Details
<project>
    <dependencies>
        <dependency>
            <groupId>com.kotlinorm</groupId>
            <artifactId>kronos-core</artifactId>
            <version>0.0.5</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.jetbrains.kotlin</groupId>
                <artifactId>kotlin-maven-plugin</artifactId>
                <extensions>true</extensions>
                <configuration>
                    <compilerPlugins>
                        <plugin>kronos-maven-plugin</plugin>
                    </compilerPlugins>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>com.kotlinorm</groupId>
                        <artifactId>kronos-maven-plugin</artifactId>
                        <version>0.0.5</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>
</project>

🗄️ Supported Databases

Kronos-ORM supports multiple databases:

  • MySQL
  • PostgreSQL
  • SQLite
  • Oracle
  • Microsoft SQL Server
  • DB2
  • Sybase
  • H2
  • OceanBase
  • DM8
  • GaussDB

Notes:

  • Feature breadth may vary slightly by dialect. The core DSL and upsert/lock syntax provide cross-database compatibility where possible.
  • The integration test module currently focuses on MySQL and PostgreSQL for CI examples.

🚀 Quick Start

🔗 Connect to Database

You can set default data source by:

Kronos.init {
    dataSource = { KronosBasicWrapper(SomeDataSource()) }
    // for example:
    //dataSource = { KronosBasicWrapper(MysqlDataSource("jdbc:mysql://localhost:3306/test", "root", "***")) }
    //dataSource = { KronosBasicWrapper(HikariDataSource().apply { jdbcUrl = "jdbc:mysql://localhost:3306/test" ... }) }
    //dataSource = { KronosBasicWrapper(BasicDataSource().apply { url = "jdbc:sqlite:path/to/db" ... }) }
}

More details about connecting to the database and use dynamic data source or multiple data sources, please refer to the docs.

🎨 Table Model Definition(Annotation Style)

@Table(name = "tb_movie")
@TableIndex("idx_name", ["name"], Mysql.KIndexType.UNIQUE, Mysql.KIndexMethod.BTREE)
data class Movie(
    @PrimaryKey(identity = true)
    val id: Long? = null, // primary key and auto increment
    @Necessary val name: String? = null, // movie name
    val directorId: Long? = null, // director id
    @Cascade(["directorId"], ["id"])
    val director: Director? = null, // cascade table & one-to-many
    val relations: List<MovieActorRelation>? = null, // reference list & many-to-many
    @Serialize
    val type: List<String>? = null, // deserialize from string
    @Column("movie_summary")
    val summary: String? = null, // summary with column name
    @Version val version: Long? = null, // version for optimistic lock
    @LogicDelete val deleted: Boolean? = null, // logic delete
    @DateTimeFormat("yyyy-MM-dd HH:mm:ss")
    @UpdateTime val updateTime: String? = null, // update time and date format
    @CreateTime val createTime: LocalDateTime? = null // create time
) : KPojo { // KPojo is a marker interface
    var actors: List<Actor>? by manyToMany(::relations) // many-to-many
}

🎨 Table Model Definition(Dsl Style)

Coming soon... #10


🔨 Table Operation

//is table exists
dataSource.table.exists<Movie>()

// create table
dataSource.table.createTable<Movie>()

// drop table
dataSource.table.dropTable<Movie>()
// or
dataSource.table.dropTable("tb_movie")

//sync table structure
dataSource.table.syncTable<Movie>()

📜 Query

// single query
val listOfUser: List<User> = User()
    .select { it.id + it.username }
    .where { it.id < 10 && it.age >= 18 }
    .distinct()
    .groupBy { it.id }
    .orderBy { it.username.desc() }
    .queryList()

// with Pagination
val (total, list) = User()
    .select { it.id + it.username }
    .where { it.id < 10 && it.username like "a%" }
    .distinct()
    .groupBy { it.id }
    .orderBy { it.username.desc() }
    .page(1, 10)
    .withTotal()
    .queryList()

// multi-table query
val listOfMap = User().join(UserRelation(), UserRole()) { user, relation, role ->
    on { user.id == relation.userId && user.id == role.userId }
    select {
        user.id + user.username + relation.id.as_("relationId") + 
                role.role + f.count(1).as_("count")
    }
    where { user.id < 10 }
}.query()

// Using Native SQL Queries with Named Parameters
val result: Map<String, Any> = dataSource.query("select * from tb_user where id = :id", mapOf("id" to 1))

➕ Insert

// single insert
user.insert().execute()

// batch insert
listOfUser.insert().execute()

✏️ Update

// update by some conditions use `set`
user.update()
    .set {
        it.username = "123"
        it.score += 10
    }
    .by { it.id }
    .execute()

// update by some conditions, data from record
user.update { it.username + it.gender }
    .by { it.id }
    .execute()

🔄 Upsert

// upsert on some columns
user.upsert { it.username }
    .on { it.id }
//  .lock(PessimisticLock.X) // You can specify the type of lock, and pessimistic lock is used by default
    .execute()

// upsert on duplicate key
user.upsert { it.username }
    .onConflict() // Cross-database compatible upsert syntax
    .execute()

🗑 Delete

// delete rows by some conditions
user.delete()
    .where { it.id == 1 }
    .execute()

📝 Create KPojo Instance & Transform between KPojo and Map & Get Meta Information

  • Kronos provides KPojo with the ability to dynamically create instances based on type parameters through compile-time operations so that instances can be easily created.
  • Kronos provides functions to easily convert between KPojo and Map.
  • Kronos provides classes inheriting the KPojo interface with a number of functions including kronosTable and kronosColumns for obtaining meta information such as table names and columns.
val instance = Movie::class.newInstance() // -> Movie() ,dynamic create KPojo instance by reference, NO REFLECTION used
fun <T: KPojo> dynamic(kClass: KClass<T>): T = kClass.newInstance() // dynamic create KPojo instance by reference, NO REFLECTION used

val movie = Movie(1)
val dataMap: Map<String, Any?> = movie.toDataMap() // Map("id" = 1), NO REFLECTION used
val movie2: Movie = dataMap.mapperTo<Movie>() // or dataMap.mapperTo(Movie::class), NO REFLECTION used

val tableName = movie.kronosTable() // "tb_movie", NO REFLECTION used
val columns = movie.kronosColumns() // [Field(id), Field(name), ...], NO REFLECTION used
// We actually provide more functions such as getting the table creation time, update time, logical deletion of field settings and so on

instance["fieldName"] // get field value by field name, NO REFLECTION used
instance["fieldName"] = "value" // set field value by field name, NO REFLECTION used

🛠️ Working with Spring or Other Frameworks

Please refer to the following example projects for more information:

📚 Documentation

For more information, please visit the official website or the documentation.

📜 License

Kronos-ORM is released under the Apache 2.0 license.

🤝 Contributing

Please refer to the CONTRIBUTING.md for more.

Contributors

We would like to express our gratitude to all the individuals who have already contributed to Kronos-ORM!

contributors

If you are interested in Kronos-ORM, please join our community and chat with us!

discord

QQ群

QRCode

If you like Kronos-ORM, please give us a star ⭐️, thank you!

About

🚀 A modern ORM framework designed for Kotlin based on the compiler plugin, which is suitable for both backend and mobile applications, support multi-database. Powerful, high performance, easy to use.

Resources

Code of conduct

Contributing

Stars

Watchers

Forks

Packages

No packages published

Contributors 7

Languages