Skip to content

Table mapping

This step allows describing how to map a table to a class (aka Entity).

Table of content

Mapping of the database model

Entities = simple Kotlin classes

Kotlin's data classes are great for entities because their main purpose is to hold data.
These are 2 simple entities that we will use :

kotlin
data class Role(
        val label: String,
        val id: UUID = UUID.randomUUID()
)

data class User(
        val firstname: String,
        val lastname: String,
        val isAdmin: Boolean,
        val roleId: UUID,
        val messageCount: Int = 0,
        val alias: String? = null,
        val id: Int? = null
)

Mapping entities to database tables

This is the ORM (object-relational mapping) step. Define all mappings rules between your entities and the database tables

  • columns
  • primary and foreign keys
  • indexes
  • identity (for auto-generated number columns)

This DSL is based on type and nullability of the fields of your entities.

kotlin
object Roles : H2Table<Role>("roles") {
    val id = uuid(Role::id)
            .primaryKey()
    val label = varchar(Role::label)
}

object Users : H2Table<User>("users") {
    val id = autoIncrementInteger(User::id)
        .primaryKey("PK_users")
    val firstname = varchar(User::firstname, "fname")
    val lastname = varchar(User::lastname, "lname")
    val isAdmin = boolean(User::isAdmin)
    val roleId = uuid(User::roleId)
            .foreignKey(Roles.id, "FK_users_roles")
    val messageCount = integer(User::messageCount)
    val alias = varchar(User::alias)
}

private val tables = tables().h2(Roles, Users)

TIP

auto-incremented and identity entity fields (see below) can be either nullable, with a null default value, or non-null with a default value of 0 or negative.

Declare your indexes

In Kotysa, indexes are part of the table mapping. Just add unique on a column, or create an index from several columns of a table.

kotlin
object Roles : H2Table<Role>("roles") {
    val id = uuid(Role::id)
        .primaryKey()
    val label = varchar(Role::label)
        .unique() // unique index on label column
}

object Users : H2Table<User>("users") {
    // ...
    val firstname = varchar(User::firstname, "fname")
    val lastname = varchar(User::lastname, "lname")
    // ...
    init {
        // creates an index on the firstname, lastname column pair
        index(setOf(firstname, lastname), indexName = "full_name_index")
    }
}

Identity

In Kotysa, identity is part of the table mapping. Simply declare auto-generated Int and Long columns as identity

TIP

Identity is available for PostgreSQL, Oracle, MSSQL and H2

kotlin
object OracleEntities : OracleTable<OracleEntity>() {
    val id = number(OracleEntity::id)
        .identity()
        .primaryKey()
}

Generic table mapping

In order to make integration tests of your repositories easier, Kotysa offers GenericTable

  • extend GenericTable in this case instead of the DB specific one
  • tables() DSL for H2, PostgreSQL and MSSQL accept a combination of DB specific tables OR GenericTable
kotlin
object Roles : GenericTable<Role>("roles") {
    val id = uuid(Role::id)
        .primaryKey()
    val label = varchar(Role::label)
}

// in your main code, use PostgreSQL for example
private val mainTables = tables().postgresql(Roles)

// in your test code, use H2
private val testTables = tables().h2(Roles)

Data types

Tables below list all the data types that are supported by Kotysa for each database provider.

TIP

Kotysa uses Java 8+ java.time.* and kotlinx-datetime corresponding types for dates.

PostgreSQL

Kotlin typeDescriptionSQL type
StringRepresents a variable-length character string, maximum length fixedvarchar
Represents a variable-length character string, unlimited lengthtext
java.time.LocalDate or kotlinx.datetime.LocalDateRepresents a date without time part and without timezonedate
java.time.LocalDateTime or kotlinx.datetime.LocalDateTimeRepresents a date+time without timezonetimestamp
java.time.OffsetDateTimeRepresents a date+time with timezone.
PostgreSQL uses UTC timezone to store TIMESTAMP WITH TIME ZONE, so you may have to override equals to use Instant based "isEqual" method on java.time.OffsetDateTime fields
timestampWithTimeZone
java.time.LocalTime or kotlinx.datetime.LocalTimeRepresents a time without a date part and without timezonetime
BooleanRepresents a boolean stateboolean
java.util.UUIDUniversally unique identifier (128 bit value)uuid
IntRepresents an integerinteger
Represents an auto-incremented integerserial
LongRepresents a longbigInt
Represents an auto-incremented longbigSerial
FloatRepresents a single precision floating point numberreal
DoubleRepresents a double precision floating point numberdoublePrecision
BigDecimalRepresents a exact decimal number with fixed precision and scaledecimal
numeric
ByteArrayBinary object stored as bytesbytea

MySQL

Kotlin typeDescriptionSQL type
StringRepresents a variable-length character string, maximum length fixed (size is mandatory in MySQL). Default size = 255varchar
Represents a variable-length character string, max length = 255tinytext
Represents a variable-length character string, max length = 65_535text
Represents a variable-length character string, max length = 16_777_215mediumtext
Represents a variable-length character string, max length = 4_294_967_295longtext
java.time.LocalDate or kotlinx.datetime.LocalDateRepresents a date without time part and without timezonedate
java.time.LocalDateTime or kotlinx.datetime.LocalDateTimeRepresents a date+time without timezonedatetime
java.time.LocalTime or kotlinx.datetime.LocalTimeRepresents a time without a date part and without timezonetime
BooleanRepresents a boolean stateboolean
IntRepresents an integerinteger
Represents an auto-incremented integerautoIncrementInteger
LongRepresents a longbigInt
Represents an auto-incremented longautoIncrementBigInt
FloatRepresents a single precision floating point numberfloat
DoubleRepresents a double precision floating point numberdoublePrecision
BigDecimalRepresents a exact decimal number with fixed precision and scaledecimal
numeric
ByteArrayBinary object stored as bytesbinary
Large binary object stored as bytes
=> only supported with jdbc
blob

H2

Kotlin typeDescriptionSQL type
StringRepresents a variable-length character string, maximum length fixedvarchar
java.time.LocalDate or kotlinx.datetime.LocalDateRepresents a date without time part and without timezonedate
java.time.LocalDateTime or kotlinx.datetime.LocalDateTimeRepresents a date+time without timezonetimestamp
datetime
java.time.OffsetDateTimeRepresents a date+time with timezonetimestampWithTimeZone
java.time.LocalTime or kotlinx.datetime.LocalTimeRepresents a time without a date part and without timezonetime
BooleanRepresents a boolean stateboolean
java.util.UUIDUniversally unique identifier (128 bit value)uuid
IntRepresents an integerinteger
Represents an auto-incremented integerautoIncrementInteger
LongRepresents a longbigInt
Represents an auto-incremented longautoIncrementBigInt
FloatRepresents a single precision floating point numberreal
DoubleRepresents a double precision floating point numberdoublePrecision
BigDecimalRepresents a exact decimal number with fixed precision and scaledecimal
numeric
ByteArrayBinary object stored as bytesbinary
Large binary object stored as bytes
=> only supported with jdbc
blob

MSSQL

Kotlin typeDescriptionSQL type
StringRepresents a variable-length character string, maximum length fixedvarchar
java.time.LocalDate or kotlinx.datetime.LocalDateRepresents a date without time part and without timezonedate
java.time.LocalDateTime or kotlinx.datetime.LocalDateTimeRepresents a date+time without timezonedatetime
java.time.OffsetDateTimeRepresents a date+time with timezone.
MSSQL uses UTC timezone to store DATETIMEOFFSET, so you may have to override equals to use Instant based "isEqual" method on java.time.OffsetDateTime fields
dateTimeOffset
java.time.LocalTime or kotlinx.datetime.LocalTimeRepresents a time without a date part and without timezonetime
BooleanRepresents a boolean statebit
java.util.UUIDUniversally unique identifier (128 bit value)uniqueIdentifier
IntRepresents an integerinteger
LongRepresents a longbigInt
FloatRepresents a single precision floating point numberreal
DoubleRepresents a double precision floating point numberfloat
BigDecimalRepresents a exact decimal number with fixed precision and scaledecimal
numeric
ByteArrayBinary object stored as bytesbinary

MariaDB

Kotlin typeDescriptionSQL type
StringRepresents a variable-length character string, maximum length fixed (size is mandatory in MariaDB). Default size = 255varchar
Represents a variable-length character string, max length = 255tinytext
Represents a variable-length character string, max length = 65_535text
Represents a variable-length character string, max length = 16_777_215mediumtext
Represents a variable-length character string, max length = 4_294_967_295longtext
java.time.LocalDate or kotlinx.datetime.LocalDateRepresents a date without time part and without timezonedate
java.time.LocalDateTime or kotlinx.datetime.LocalDateTimeRepresents a date+time without timezonedatetime
java.time.LocalTime or kotlinx.datetime.LocalTimeRepresents a time without a date part and without timezonetime
BooleanRepresents a boolean stateboolean
IntRepresents an integerinteger
Represents an auto-incremented integerautoIncrementInteger
LongRepresents a longbigInt
Represents an auto-incremented longautoIncrementBigInt
FloatRepresents a single precision floating point numberfloat
DoubleRepresents a double precision floating point numberdoublePrecision
BigDecimalRepresents a exact decimal number with fixed precision and scaledecimal
numeric
ByteArrayBinary object stored as bytesbinary
Large binary object stored as bytes
=> only supported with jdbc
blob

Oracle

Kotlin typeDescriptionSQL type
StringRepresents a variable-length character string, maximum length fixedvarchar2
java.time.LocalDate or kotlinx.datetime.LocalDateRepresents a date without time part and without timezonedate
java.time.LocalDateTime or kotlinx.datetime.LocalDateTimeRepresents a date+time without timezonetimestamp
java.time.OffsetDateTimeRepresents a date+time with timezonetimestampWithTimeZone
BooleanRepresents a boolean statenumber
IntRepresents an integer
LongRepresents a long
BigDecimalRepresents a exact decimal number with fixed precision and scale
FloatRepresents a single precision floating point numberbinaryFloat
DoubleRepresents a double precision floating point numberbinaryDouble
ByteArrayBinary object stored as bytesraw

SqLite

Kotlin typeDescriptionSQL type
StringRepresents a variable-length character string, maximum length fixedtext
java.time.LocalDate or kotlinx.datetime.LocalDateRepresents a date without time part and without timezone
java.time.LocalDateTime or kotlinx.datetime.LocalDateTimeRepresents a date+time without timezone
java.time.OffsetDateTimeRepresents a date+time with timezone
java.time.LocalTime or kotlinx.datetime.LocalTimeRepresents a time without a date part and without timezone
BooleanRepresents a boolean stateinteger
IntRepresents an integer
Represents an auto-incremented integerautoIncrementInteger
LongRepresents a longinteger
Represents an auto-incremented longautoIncrementInteger
FloatRepresents a single precision floating point numberreal
DoubleRepresents a double precision floating point number
ByteArrayBinary object stored as bytesblob

Released under The Unlicense.