在 Groovy Gradle 项目中添加 Exposed 依赖:模块化构建完整指南
发布时间:2026/9/25 14:19:48 作者:尧图编辑部 阅读量:1,286

ORM后端数据存储【免费下载链接】ExposedKotlin SQL Framework项目地址https://gitcode.com/gh_mirrors/ex/Exposed点击查看免费下载导读Exposed 是 Kotlin 生态中一款类型安全的 SQL 框架它按功能拆分成了exposed-core、exposed-jdbc、exposed-dao等多个独立模块允许开发者按需引入。本文以仓库中的 exposed-modules-groovy-gradle 示例项目为骨架系统讲解在 Groovy DSL 的 Gradle 工程中配置 Maven Central 仓库、声明最小依赖集、使用版本目录version catalog统一管理版本、选择传输层模块以及补充 JDBC 驱动与日志依赖的完整实操流程。读完本文你将能在自己的 Groovy Gradle 项目中以最精简且规范的方式接入 Exposed并理解每个依赖在框架中的真实作用。示例项目定位Groovy Gradle 下的 Exposed 依赖模板在 Exposed 官方文档仓库中snippets目录是一个包含多个可运行示例的多模块 Gradle 工程其中exposed-modules-groovy-gradle子项目专为 Groovy DSL 的 Gradle 构建脚本而生。它的定位非常明确它是一个自动生成的 Groovy Gradle 工程内部包含 Exposed 的核心依赖声明它的build.gradleGroovy DSL 写法被官方主题文档 Adding dependencies 以「按行引用」的方式直接嵌入展示作为 Groovy 语法的权威示例它的入口代码是一个最小可运行的 Kotlin 主函数用于验证依赖装配正确后整个工程能够正常编译与构建。该子项目在仓库中的实际结构如下documentation-website/Writerside/snippets/exposed-modules-groovy-gradle/ ├── README.md # 项目说明与构建命令 └── src/ └── main/ └── kotlin/ └── com/ └── example/ └── Main.kt # 最小 Kotlin 入口println(Hello World!)其中入口文件 Main.kt 的内容非常简洁package com.example fun main() { println(Hello World!) }这段代码本身不涉及任何 Exposed API它的作用是作为构建验证的载体——只要./gradlew :exposed-modules-groovy-gradle:build能成功就说明 Exposed 依赖已被正确解析并打进 classpath。同时exposed-modules-groovy-gradle被登记在 snippets 多模块工程的 settings.gradle.kts 中include(exposed-modules-groovy-gradle)因此它可以直接作为整个 Gradle 工程的一个子项目进行构建。构建与运行一条命令验证依赖装配根据 exposed-modules-groovy-gradle/README.md 的说明构建该示例的完整流程为打开终端进入snippets目录即documentation-website/Writerside/snippets执行以下命令./gradlew :exposed-modules-groovy-gradle:build其中:exposed-modules-groovy-gradle是 Gradle 对子项目的路径式任务定位语法。由于snippets是一个多模块工程settings.gradle.kts中通过include(...)注册了exposed-dao、exposed-dsl、exposed-modules-kotlin-gradle、exposed-modules-groovy-gradle等十余个子项目使用这种带项目路径前缀的写法可以精确指定只构建目标子项目而不会触发无关模块的构建。注意./gradlew是 Linux/macOS 下的 Gradle Wrapper 执行方式Windows 下请使用gradlew.bat。Wrapper 脚本与gradle/wrapper目录已随仓库提供无需本机预装 Gradle。此外整个 snippets 工程还支持run任务直接运行某个示例例如./gradlew :exposed-dao:run不过对于 Groovy 依赖模板而言build任务已经足够验证依赖的完整性与正确性。Exposed 模块全景从核心到扩展的依赖地图Adding-dependencies.md是理解该 Groovy 示例项目依赖声明的核心文档。它指出Exposed 被拆分为特定模块给你只引入所需模块的灵活性。所有模块可归为四类下面结合 Groovy 语法逐一说明。核心模块Core module任何 Exposed 应用都必须引入的模块只有一个模块功能exposed-core提供与数据库进行类型安全交互所需的基础组件与抽象包含领域特定语言DSLAPI从仓库源码结构可以印证这一点exposed-core是仓库中最大的模块其 src/main/kotlin 下包含 104 个 Kotlin 文件覆盖AbstractQuery、Table、Column、Query、SqlExpressionBuilder、Transaction等 DSL 核心构件同时api/exposed-core.api文件完整记录了该模块对外暴露的全部 API 签名。可以说exposed-core是 Exposed 的「地基」。传输模块Transport modules传输模块定义了 Exposed 与数据库通信的方式并且互斥——你只能二选一模块功能exposed-jdbc基于 Java JDBC API 的传输层实现提供 JDBC 支持exposed-r2dbc提供响应式关系数据库连接R2DBC支持官方文档明确强调只需要一个传输模块——要么exposed-jdbc要么exposed-r2dbc不要同时引入两者。这是因为它们对应两套完全不同的底层连接模型阻塞式 JDBC 与响应式 R2DBC同时引入会造成依赖冗余与运行时行为的不确定性。数据库访问模块Database access module在exposed-core之上Exposed 提供了一个可选的高层数据访问模块模块功能exposed-dao提供数据访问对象DAOAPI基于exposed-core构建提供更高级的数据抽象需要注意其约束exposed-dao要求exposed-jdbc作为传输层且与exposed-r2dbc不兼容。因此如果你计划使用 R2DBC 响应式方案就不能同时使用 DAO API而应回到 DSL 层。扩展模块Extension modules扩展模块为 Exposed 补充了数据类型、加密、日期时间等能力全部按需引入模块功能exposed-crypt提供加密列类型支持在客户端编解码数据库中的加密数据以及密码等单向哈希数据exposed-java-time基于 Java 8 Time API 的日期时间扩展exposed-jodatime基于 Joda-Time 库的日期时间扩展exposed-jsonJSON 与 JSONB 数据类型扩展exposed-kotlin-datetime基于kotlinx-datetime库的日期时间扩展exposed-money支持 JavaMoney API 的MonetaryAmount类型扩展exposed-spring-boot-starter面向 Spring Boot 3 的 starter将 Exposed 用作 ORMexposed-spring-boot4-starter面向 Spring Boot 4 的 starter将 Exposed 用作 ORMspring-transaction基于 Spring Framework 6 标准事务流程构建的事务管理器spring7-transaction基于 Spring Framework 7 标准事务流程构建的事务管理器exposed-migration-core数据库 schema 迁移的核心通用功能exposed-migration-jdbc依赖 JDBC 驱动的数据库 schema 迁移工具exposed-migration-r2dbc依赖 R2DBC 驱动的数据库 schema 迁移工具这些扩展模块在仓库中均有对应目录例如 exposed-json、exposed-java-time、exposed-money、exposed-migration-core 等每个模块都自带api/*.api文件记录公开 API供需要深度定制数据类型的读者继续查阅。Groovy Gradle 中的最小依赖集在Adding-dependencies.md的「Add dependencies」小节中官方为 Groovy DSL 给出了最小可行依赖集——一个 Exposed 应用至少需要「核心模块 恰好一个传输模块」dependencies { implementation org.jetbrains.exposed:exposed-core:%exposed_version% implementation org.jetbrains.exposed:exposed-jdbc:%exposed_version% implementation org.jetbrains.exposed:exposed-dao:%exposed_version% //optional }逐行解读exposed-core必选DSL 与类型安全抽象的基础exposed-jdbc必选传输层若走响应式路线则替换为exposed-r2dbcexposed-dao可选注释已标明//optional只有需要 DAO 高层 API 时才引入。%exposed_version%是文档中的版本占位符。在当前仓库中实际版本号定义在根目录 gradle.properties 中version1.5.0即本仓库对应的 Exposed 版本为1.5.0。在你的工程中应替换为实际使用的版本例如dependencies { implementation org.jetbrains.exposed:exposed-core:1.5.0 implementation org.jetbrains.exposed:exposed-jdbc:1.5.0 implementation org.jetbrains.exposed:exposed-dao:1.5.0 // 可选 }作为对照同一主题文档中还提供了 Kotlin DSL 与 Maven 两种写法。Kotlin DSL 写法为dependencies { implementation(org.jetbrains.exposed:exposed-core:%exposed_version%) implementation(org.jetbrains.exposed:exposed-jdbc:%exposed_version%) implementation(org.jetbrains.exposed:exposed-dao:%exposed_version%) // Optional }Maven 写法为pom.xml的dependencies段dependencies dependency groupIdorg.jetbrains.exposed/groupId artifactIdexposed-core/artifactId version%exposed_version%/version /dependency dependency groupIdorg.jetbrains.exposed/groupId artifactIdexposed-jdbc/artifactId version%exposed_version%/version /dependency dependency groupIdorg.jetbrains.exposed/groupId artifactIdexposed-dao/artifactId version%exposed_version%/version /dependency /dependencies三种构建系统的依赖坐标完全一致差异仅在语法Groovy 用implementation group:artifact:version引号字符串Kotlin DSL 用implementation(group:artifact:version)Maven 用artifactId标签。配置仓库源在声明依赖之前需要先确保构建能从 Maven Central 拉取 Exposed 构件。Adding-dependencies.md指出Exposed 模块发布在 Maven Central 仓库。Groovy DSL 的配置方式为repositories { mavenCentral() }对于 Maven 用户Maven Central 默认启用无需额外配置。Kotlin DSL 写法与 Groovy 相同mavenCentral()方法在两种 DSL 中同名。使用版本目录Version Catalog统一管理 Exposed 版本为了免去手写每个坐标和版本号的繁琐Exposed 官方发布了exposed-version-catalog——一个专为所有已发布 Exposed 模块设计的 Gradle 版本目录。仓库中的 exposed-version-catalog/README.md 对其用法给出了完整说明。在 settings 中导入目录在settings.gradle.kts或 Groovy 语法的settings.gradle的dependencyResolutionManagement块中创建目录dependencyResolutionManagement { repositories { mavenCentral() } versionCatalogs { create(exposedLibs) { from(org.jetbrains.exposed:exposed-version-catalog:%exposed_version%) } } }通过类型安全访问器引用模块导入后即可在构建脚本中用类型安全访问器引用各模块而无需硬编码坐标dependencies { implementation exposedLibs.core implementation exposedLibs.jdbc implementation exposedLibs.dao // Optional }访问器的命名规则是去掉exposed-前缀将其余部分按-拆分为嵌套访问器。例如模块访问器exposed-coreexposedLibs.coreexposed-jdbcexposedLibs.jdbcexposed-r2dbcexposedLibs.r2dbcexposed-kotlin-datetimeexposedLibs.kotlin.datetimespring7-transactionexposedLibs.spring7.transaction统一覆盖版本由于所有模块共享同一个exposed版本你可以在一处覆盖整个目录的 Exposed 版本versionCatalogs { create(exposedLibs) { from(org.jetbrains.exposed:exposed-version-catalog:%exposed_version%) version(exposed, %exposed_version%) } }当前仓库的实际示例版本为1.5.0参见 exposed-version-catalog/README.md 中的from(org.jetbrains.exposed:exposed-version-catalog:1.5.0)替换占位符后即为versionCatalogs { create(exposedLibs) { from(org.jetbrains.exposed:exposed-version-catalog:1.5.0) version(exposed, 1.5.0) } }为什么叫exposedLibs而不是exposed这是一个非常容易踩坑的细节。官方文档与 exposed-version-catalog/README.md 均明确指出Exposed Gradle 插件会注册一个名为exposed的项目扩展即exposed { migrations { } }DSL。而版本目录同样会以目录名作为项目扩展暴露出来因此若将目录命名为exposed会与插件扩展冲突报错Cannot add extension with name exposed。命名为exposedLibs可让两者在同一工程中共存。如果你不应用 Exposed Gradle 插件则可以自由地将目录命名为exposed并使用exposed.core这类访问器。此外还有两点补充约束版本目录是 Gradle 特性Maven 用户无法使用应如前文所示直接声明依赖坐标若同时使用 Exposed Gradle 插件exposed-gradle-plugin务必保留exposedLibs命名以避免冲突。补充 JDBC/R2DBC 驱动依赖Exposed 本身不包含任何数据库驱动你需要为所使用的数据库额外引入对应的 JDBC 或 R2DBC 驱动。以 H2 数据库为例Groovy DSL 写法为dependencies { implementation com.h2database:h2:%h2_db_version% }Kotlin DSL 写法为dependencies { implementation(com.h2database:h2:%h2_db_version%) }Maven 写法为dependencies dependency groupIdcom.h2database/groupId artifactIdh2/artifactId version2.4.240/version /dependency /dependencies官方文档提示受支持数据库及其对应驱动依赖的完整列表参见 Working with Database。在仓库中exposed-tests与exposed-jdbc等模块的实际测试配置使用了 H2 等数据库驱动进行集成验证见各模块build.gradle.kts中的 test 依赖这也印证了「驱动必须独立引入」的约定。补充日志依赖让 SQL 日志可见Exposed 的StdOutSqlLogger通过 SLF4J 输出 SQL 日志因此你需要一个 SLF4J 绑定实现否则可能遇到StaticLoggerBinder相关告警且看不到日志。官方给出了两种选择最小方案无输出——使用slf4j-nop静默丢弃日志dependencies { // Minimal logging (no output) implementation org.slf4j:slf4j-nop:%slf4j_version% }完整方案——使用 Logback 获得全功能日志输出dependencies { // Full-featured logging using Logback implementation ch.qos.logback:logback-classic:%logback_version% }关于为何需要日志依赖的详细解释官方文档指向了 SLF4J 官方文档的StaticLoggerBinder错误说明当 classpath 中没有任何 SLF4J 绑定实现时SLF4J 会报告Failed to load class org.slf4j.impl.StaticLoggerBinder此时日志将退化为无输出。仓库源码同样印证了这一依赖关系exposed-core中定义了 StdOutSqlLogger对应 API 文档org.jetbrains.exposed.v1.core.StdOutSqlLogger其实现基于 SLF4J 的LoggerFactory输出 SQL 语句。因此在实际项目中若希望看到 Exposed 生成的 SQLlogback-classic或slf4j-simple等其他绑定是必备项。常见问题与最佳实践小结围绕该 Groovy 示例工程与官方依赖指南汇总如下实践要点最小依赖恒等式exposed-core 恰好一个传输模块exposed-jdbc或exposed-r2dbc即可运行exposed-dao按需引入且仅兼容 JDBC 传输层。传输层二选一不要同时引入exposed-jdbc与exposed-r2dbc两者互斥。驱动必须自备Exposed 不捆绑任何数据库驱动H2、MySQL、PostgreSQL 等驱动的坐标需要自己声明。日志绑定不能少想看到 SQL 日志必须在 classpath 中放置至少一个 SLF4J 绑定推荐logback-classic。版本目录推荐使用通过org.jetbrains.exposed:exposed-version-catalog导入类型安全访问器并在settings中统一管理版本注意目录命名为exposedLibs以避免与 Exposed Gradle 插件的exposed扩展冲突。Groovy 与 Kotlin DSL 语法差异Groovy 使用implementation group:artifact:version与implementation exposedLibs.coreKotlin DSL 使用implementation(...)与implementation(exposedLibs.core)其余语义完全一致。版本号对齐当前仓库对应的 Exposed 版本为 1.5.0见 gradle.properties所有模块应使用同一版本。通过本文的配置你的 Groovy Gradle 工程即可获得一套完整、可运行、便于后续扩展的 Exposed 依赖体系。若需深入学习 DSL 与 DAO 的用法仓库中对应的可运行示例如 exposed-dsl、exposed-dao是下一步的最佳入口。赞分享ORM后端数据存储【免费下载链接】ExposedKotlin SQL Framework项目地址https://gitcode.com/gh_mirrors/ex/Exposed点击查看免费下载相关推荐Kubo 在 Windows 上从源码构建MSYS2、Cygwin 与 Minimal 三种方案完整指南Kubo 在 Windows 上从源码构建MSYS2、Cygwin 与 Minimal 三种方案完整指南 本篇技术指南以 docs/windows.md htORM后端数据存储Exposed 1.0 迁移之构建文件改造Gradle KTS / Groovy / Version Catalog / Maven 全模式指南Exposed 1.0 迁移之构建文件改造Gradle KTS / Groovy / Version Catalog / Maven 全模式指南 ExposeORM后端数据存储Android Topeka Gradle配置终极指南多模块构建与依赖管理完整教程Android Topeka Gradle配置终极指南多模块构建与依赖管理完整教程 Topeka是一个展示Android Material Design的趣味移动开发示例工程上一篇discord.js 官方指南apps/guide贡献指南Fumadocs 页面开发与写作规范实战下一篇EIP-7701 原生账户抽象Native Account Abstraction交易流程详解从 Simple Flow 到验证/执行两阶段模型创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考