Skip to content

Latest commit

 

History

History
204 lines (161 loc) · 5.69 KB

File metadata and controls

204 lines (161 loc) · 5.69 KB

Module bluetape4k-exposed-fastjson2

English | 한국어

A module for serializing and deserializing Exposed JSON/JSONB columns using Fastjson2.

Overview

bluetape4k-exposed-fastjson2 provides serialization and deserialization of JetBrains Exposed JSON/JSONB column types using Alibaba Fastjson2. It is well-suited for environments that require high-performance JSON processing.

Key Features

  • Fastjson column types: JSON/JSONB column mapping
  • ResultRow extensions: Utilities for reading JSON column values
  • JSON functions/conditions: Helpers for building database-specific JSON query conditions

Dependency

dependencies {
    implementation("io.github.bluetape4k:bluetape4k-exposed-fastjson2:${version}")
    implementation("io.github.bluetape4k:bluetape4k-fastjson2:${version}")
}

Basic Usage

1. Defining JSON Columns

import io.bluetape4k.exposed.core.fastjson2.fastjson
import io.bluetape4k.exposed.core.fastjson2.fastjsonb
import org.jetbrains.exposed.v1.core.dao.id.IdTable

// Data class
data class ProductMetadata(
    val brand: String = "",
    val tags: List<String> = emptyList(),
    val attributes: Map<String, String> = emptyMap()
)

// Table definition
object Products: IdTable<Long>("products") {
    val name = varchar("name", 255)

    // JSON column (string-based)
    val metadata = fastjson<ProductMetadata>("metadata")

    // JSONB column (binary format, PostgreSQL)
    val extraData = fastjsonb<Map<String, Any>>("extra_data")
}

2. Using JSON Columns

// Insert
Products.insert {
    it[name] = "Product A"
    it[metadata] = ProductMetadata(
        brand = "BrandX",
        tags = listOf("electronics", "sale"),
        attributes = mapOf("color" to "red")
    )
}

// Query
val product = Products.selectAll().where { Products.id eq 1L }.single()
val metadata: ProductMetadata = product[Products.metadata]
val tags = metadata.tags  // ["electronics", "sale"]

3. JSON Condition Expressions

import io.bluetape4k.exposed.core.fastjson2.*

// Search by JSON path
val query = Products.selectAll()
    .where { Products.metadata.jsonPath<String>("$.brand") eq "BrandX" }

// Search by JSON containment
val query2 = Products.selectAll()
    .where { Products.metadata.jsonContains("tags", "sale") }

4. ResultRow Extensions

import io.bluetape4k.exposed.core.fastjson2.*

val metadata: ProductMetadata = resultRow.getFastjson(Products.metadata)
val extraData: Map<String, Any>? = resultRow.getFastjsonOrNull(Products.extraData)

Key Files / Classes

File Description
FastjsonColumnType.kt JSON column type (string-based)
FastjsonBColumnType.kt JSONB column type (binary format)
JsonFunctions.kt JSON function extensions
JsonConditions.kt JSON condition expression extensions
ResultRowExtensions.kt ResultRow JSON read extensions

Jackson vs Fastjson2 Selection Guide

Feature Jackson Fastjson2
Performance Good Very fast
Stability High Moderate
Features Rich Basic
Recommended for General use High-performance scenarios

Testing

./gradlew :bluetape4k-exposed-fastjson2:test

Architecture Diagram

Column Type Structure (Summary)

classDiagram
    direction LR
    class Fastjson2ColumnType~T~ {
        <<ColumnType>>
        +valueFromDB(value): T
        +valueToDB(value): Any
    }
    class Fastjson2BColumnType~T~ {
        <<ColumnTypeJSONB>>
        +valueToDB(value): PGobject
    }
    class TableExtensions {
        <<extensionFunctions>>
        +Table.fastjson2~T~(name): Column~T~
        +Table.fastjson2b~T~(name): Column~T~
    }
    Fastjson2ColumnType <|-- Fastjson2BColumnType

Loading

JSON Column Type Class Structure

classDiagram
    class ColumnType {
        <<Exposed base abstract>>
        +sqlType(): String
        +valueFromDB(value): T
        +notNullValueToDB(value): Any
    }
    class FastjsonColumnType~T~ {
        -objectMapper: ObjectMapper
        +sqlType(): String
        +valueFromDB(value): T
        +notNullValueToDB(value): String
    }
    class FastjsonBColumnType~T~ {
        -objectMapper: ObjectMapper
        +sqlType(): String
        +valueFromDB(value): T
        +notNullValueToDB(value): ByteArray
    }
    class JsonFunctions {
        +Column.jsonPath(path): Expression
        +Column.jsonContains(field, value): Op
    }
    class ResultRowExtensions {
        +ResultRow.getFastjson(col): T
        +ResultRow.getFastjsonOrNull(col): T?
    }

    ColumnType <|-- FastjsonColumnType
    ColumnType <|-- FastjsonBColumnType
    FastjsonColumnType --> JsonFunctions : integrates
    FastjsonBColumnType --> JsonFunctions : integrates
    ResultRowExtensions --> FastjsonColumnType : uses
    ResultRowExtensions --> FastjsonBColumnType : uses
Loading

JSON Column Data Flow

flowchart LR
    A[Kotlin Object] -->|Fastjson2 serialize| B[JSON String / ByteArray]
    B -->|Store to DB| C[(Database)]
    C -->|Read from DB| D[JSON String / ByteArray]
    D -->|Fastjson2 deserialize| E[Kotlin Object]

    subgraph JSON Column Types
        F["fastjson~T~ → TEXT"]
        G["fastjsonb~T~ → JSONB/BLOB"]
    end
Loading

References