☰
在 Groovy Gradle 项目中添加 Exposed 依赖:模块化构建完整指南
2026/9/25 14:19:40 网站建设 项目流程
  • ORM
  • 后端
  • 数据存储

【免费下载链接】Exposed

Kotlin 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.gradle(Groovy 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 的说明,构建该示例的完整流程为:

  1. 打开终端,进入snippets目录(即documentation-website/Writerside/snippets);
  2. 执行以下命令:
./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提供与数据库进行类型安全交互所需的基础组件与抽象,包含领域特定语言(DSL)API

从仓库源码结构可以印证这一点: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提供数据访问对象(DAO)API,基于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 用作 ORM
exposed-spring-boot4-starter面向 Spring Boot 4 的 starter,将 Exposed 用作 ORM
spring-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-r2dbc);
  • exposed-dao:可选,注释已标明//optional,只有需要 DAO 高层 API 时才引入。

%exposed_version%是文档中的版本占位符。在当前仓库中,实际版本号定义在根目录 gradle.properties 中:version=1.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> <groupId>org.jetbrains.exposed</groupId> <artifactId>exposed-core</artifactId> <version>%exposed_version%</version> </dependency> <dependency> <groupId>org.jetbrains.exposed</groupId> <artifactId>exposed-jdbc</artifactId> <version>%exposed_version%</version> </dependency> <dependency> <groupId>org.jetbrains.exposed</groupId> <artifactId>exposed-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.core
exposed-jdbcexposedLibs.jdbc
exposed-r2dbcexposedLibs.r2dbc
exposed-kotlin-datetimeexposedLibs.kotlin.datetime
spring7-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> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>2.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 生成的 SQL,logback-classic(或slf4j-simple等其他绑定)是必备项。

常见问题与最佳实践小结

围绕该 Groovy 示例工程与官方依赖指南,汇总如下实践要点:

  1. 最小依赖恒等式:exposed-core+ 恰好一个传输模块(exposed-jdbc或exposed-r2dbc)即可运行;exposed-dao按需引入,且仅兼容 JDBC 传输层。
  2. 传输层二选一:不要同时引入exposed-jdbc与exposed-r2dbc,两者互斥。
  3. 驱动必须自备:Exposed 不捆绑任何数据库驱动,H2、MySQL、PostgreSQL 等驱动的坐标需要自己声明。
  4. 日志绑定不能少:想看到 SQL 日志,必须在 classpath 中放置至少一个 SLF4J 绑定(推荐logback-classic)。
  5. 版本目录推荐使用:通过org.jetbrains.exposed:exposed-version-catalog导入类型安全访问器,并在settings中统一管理版本;注意目录命名为exposedLibs以避免与 Exposed Gradle 插件的exposed扩展冲突。
  6. Groovy 与 Kotlin DSL 语法差异:Groovy 使用implementation "group:artifact:version"与implementation exposedLibs.core,Kotlin DSL 使用implementation("...")与implementation(exposedLibs.core),其余语义完全一致。
  7. 版本号对齐:当前仓库对应的 Exposed 版本为 1.5.0(见 gradle.properties),所有模块应使用同一版本。

通过本文的配置,你的 Groovy Gradle 工程即可获得一套完整、可运行、便于后续扩展的 Exposed 依赖体系。若需深入学习 DSL 与 DAO 的用法,仓库中对应的可运行示例(如 exposed-dsl、exposed-dao)是下一步的最佳入口。

  • ORM
  • 后端
  • 数据存储

【免费下载链接】Exposed

Kotlin SQL Framework

项目地址:https://gitcode.com/gh_mirrors/ex/Exposed
点击查看免费下载
上一篇:discord.js 官方指南(apps/guide)贡献指南:Fumadocs 页面开发与写作规范实战
下一篇:EIP-7701 原生账户抽象(Native Account Abstraction)交易流程详解:从 Simple Flow 到验证/执行两阶段模型

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询