1
mirror of https://github.com/CarmJos/EasySQL.git synced 2026-06-05 09:01:26 +08:00

Compare commits

...

72 Commits

Author SHA1 Message Date
carm 479c23f985 feat: 提交进度 [ci skip] 2023-03-15 23:06:08 +08:00
carm f606fd4efc chore(sql): 尝试分离async部分 2022-12-22 09:49:57 +08:00
carm 81f065a85a chore(sql): 尝试分离async部分 2022-12-22 09:35:02 +08:00
carm b6871b1000 chore(sql): 提供当前事务实现思路 2022-12-21 21:21:01 +08:00
carm 934f9d841e chore(sql): 提供当前事务实现思路 2022-10-17 23:43:49 +08:00
carm a88843f768 feat(sql): 预备支持事务(v0.5.0) 2022-10-16 23:49:53 +08:00
dependabot[bot] a9a7543e65 chore(deps): bump log4j.version from 2.18.0 to 2.19.0 (#65)
Bumps `log4j.version` from 2.18.0 to 2.19.0.

Updates `log4j-api` from 2.18.0 to 2.19.0

Updates `log4j-core` from 2.18.0 to 2.19.0

Updates `log4j-slf4j-impl` from 2.18.0 to 2.19.0

---
updated-dependencies:
- dependency-name: org.apache.logging.log4j:log4j-api
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: org.apache.logging.log4j:log4j-core
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: org.apache.logging.log4j:log4j-slf4j-impl
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-20 00:05:30 +08:00
dependabot[bot] bb3aaafdd3 chore(deps): bump maven-jar-plugin from 3.2.2 to 3.3.0 (#64)
Bumps [maven-jar-plugin](https://github.com/apache/maven-jar-plugin) from 3.2.2 to 3.3.0.
- [Release notes](https://github.com/apache/maven-jar-plugin/releases)
- [Commits](https://github.com/apache/maven-jar-plugin/compare/maven-jar-plugin-3.2.2...maven-jar-plugin-3.3.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-jar-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-16 22:33:52 +08:00
dependabot[bot] 0167470fc3 chore(deps): bump maven-shade-plugin from 3.3.0 to 3.4.0 (#63)
Bumps [maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.3.0 to 3.4.0.
- [Release notes](https://github.com/apache/maven-shade-plugin/releases)
- [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.3.0...maven-shade-plugin-3.4.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-shade-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-15 22:01:26 +08:00
carm 274b54b8d3 test(metadata): 添加Metadata读取操作的测试 2022-08-17 03:17:05 +08:00
carm fc0a3e9754 feat(metadata): 新增数个常用Metadata读取操作方法。 2022-08-17 03:16:49 +08:00
carm 5e41e21385 chore(demo): 提供方便高效的metadata读取操作方法示例。
close #59 , #60
2022-08-17 02:38:46 +08:00
carm 0230c77bb2 Merge remote-tracking branch 'origin/master' 2022-08-17 02:31:22 +08:00
carm 10ed084ad9 feat(metadata): 提供方便高效的metadata读取操作方法
mention #59 , #60
2022-08-17 02:31:09 +08:00
carm 104d4b5476 feat(metadata): 提供方便高效的metadata读取操作方法
mention #59 , #60
2022-08-17 02:31:00 +08:00
dependabot[bot] a36554391e chore(deps): bump maven-javadoc-plugin from 3.4.0 to 3.4.1 (#58)
Bumps [maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.4.0 to 3.4.1.
- [Release notes](https://github.com/apache/maven-javadoc-plugin/releases)
- [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.4.0...maven-javadoc-plugin-3.4.1)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-javadoc-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-15 19:50:25 +08:00
carm d92a752239 feat(future): 提供更方便的executeFuture使用方法。 2022-08-10 20:16:48 +08:00
dependabot[bot] ce088a72a7 chore(deps): bump beecp from 3.3.7 to 3.3.8 (#56)
Bumps [beecp](https://github.com/Chris2018998/BeeCP) from 3.3.7 to 3.3.8.
- [Release notes](https://github.com/Chris2018998/BeeCP/releases)
- [Commits](https://github.com/Chris2018998/BeeCP/compare/3.3.7...BeeCP-3.3.8)

---
updated-dependencies:
- dependency-name: com.github.chris2018998:beecp
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-09 04:11:31 +08:00
carm 26ab19ec75 feat(execute): 提供Future类型的操作支持。 2022-08-05 17:55:44 +08:00
dependabot[bot] 198a800196 chore(deps): bump beecp from 3.3.6 to 3.3.7 (#53)
Bumps [beecp](https://github.com/Chris2018998/Beecp) from 3.3.6 to 3.3.7.
- [Release notes](https://github.com/Chris2018998/Beecp/releases)
- [Commits](https://github.com/Chris2018998/Beecp/compare/3.3.6...3.3.7)

---
updated-dependencies:
- dependency-name: com.github.chris2018998:beecp
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-11 20:26:15 +08:00
carm 2ea8f3cfa7 Merge remote-tracking branch 'origin/master' 2022-07-10 06:50:48 +08:00
carm 2061dc13bf fix(table): 修复 SQLTable#createReplace 方法递归调用异常 2022-07-10 06:50:33 +08:00
carm 760235fae8 chore(deps): bump log4j.version from 2.17.2 to 2.18.0
Merge pull request #52 from CarmJos/dependabot/maven/log4j.version-2.18.0
2022-07-04 17:44:13 +08:00
dependabot[bot] d3036ffe4d chore(deps): bump log4j.version from 2.17.2 to 2.18.0
Bumps `log4j.version` from 2.17.2 to 2.18.0.

Updates `log4j-api` from 2.17.2 to 2.18.0

Updates `log4j-core` from 2.17.2 to 2.18.0

Updates `log4j-slf4j-impl` from 2.17.2 to 2.18.0

---
updated-dependencies:
- dependency-name: org.apache.logging.log4j:log4j-api
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: org.apache.logging.log4j:log4j-core
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: org.apache.logging.log4j:log4j-slf4j-impl
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-04 08:50:30 +00:00
carm 960989990b [ci skip] docs(usage): 修改用词。 2022-07-01 22:26:05 +08:00
carm b6026cb9f4 [ci skip] docs(usage): 修改用词。 2022-07-01 22:25:36 +08:00
carm 0d74b684e3 feat(table): 针对 SQLTable 进行重构与文档补充
[4.0.2] 针对 SQLTable 进行重构与文档补充
2022-07-01 22:22:38 +08:00
carm 07e47c2220 [ci skip] docs(usage): 添加文档 在小项目中推荐使用的数据库表实现方案 。 2022-07-01 22:19:26 +08:00
carm f795e6b421 [ci skip] docs(usage): 添加文档 在小项目中推荐使用的数据库表实现方案 。 2022-07-01 22:18:45 +08:00
carm c79d833d04 [ci skip] docs(usage): 添加文档 在小项目中推荐使用的数据库表实现方案 。 2022-07-01 22:18:35 +08:00
carm daa430cb14 [0.4.2] feat(table): 令 SQLTable 变为接口,额外添加 NamedSQLTable 抽象类用于简单实现 SQLTable。
BREAKING-CHANGE: SQLTable的类型已转变,以往的代码可能失效。
2022-07-01 22:14:37 +08:00
carm 248a6d6f34 fix(async): 尝试修复 #49 中提到的问题
fix(async): 尝试修复 #49 中提到的问题
2022-06-22 20:48:00 +08:00
carm 0495928e49 fix(async): 尝试修复 #49 中提到的问题 2022-06-22 20:42:08 +08:00
carm 421fe9f454 Merge pull request #48 from CarmJos/dependabot/maven/com.h2database-h2-2.1.214
Bump h2 from 2.1.212 to 2.1.214
2022-06-15 23:18:40 +08:00
dependabot[bot] f7745a2afe Bump h2 from 2.1.212 to 2.1.214
Bumps [h2](https://github.com/h2database/h2database) from 2.1.212 to 2.1.214.
- [Release notes](https://github.com/h2database/h2database/releases)
- [Commits](https://github.com/h2database/h2database/compare/version-2.1.212...version-2.1.214)

---
updated-dependencies:
- dependency-name: com.h2database:h2
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-15 08:30:05 +00:00
carm 7d17324763 [0.4.0] 版本更新 2022-06-09 13:25:18 +08:00
carm 4be85f5481 feat(function): 添加 andThen 与 compose 方法
2022-06-09 13:24:23 +08:00
carm 298a5c4e81 feat(keys): 现在可以自定义返回的自增主键类型。
现在可以通过 returnGeneratedKey(Class<T> numberClass) 方法要求返回指定类型的自增主键。

BREAKING CHANGE: 移除了对于“是否返回主键”的选择,一旦定义了主键类型,就代表action将返回该类型的主键。
2022-06-09 12:12:11 +08:00
carm 9b4460f97a fix(debug): 修复debug消息中耗时计算异常的问题 2022-06-06 18:18:26 +08:00
carm f16b5f22e1 ci(deploy): 添加repo分支的相关介绍。 2022-06-03 03:24:01 +08:00
carm 1a4b5c245a ci(deploy): 修改部署配置 2022-06-03 03:17:37 +08:00
carm 91d9891532 ci(deploy): 修改部署配置 2022-06-03 03:04:22 +08:00
carm fdb7af541c chore: 修改项目结构与部署方式 2022-06-02 21:53:12 +08:00
carm b467743c2a docs(repo): 修改依赖库地址介绍 2022-06-02 21:51:43 +08:00
carm 3979c6d50c test(query): 添加SuppressWarnings标识 2022-06-02 21:42:34 +08:00
carm 9bac83f739 chore(project): 修改项目文件结构 2022-06-02 21:41:09 +08:00
carm 96ccc604ed ci(reploy): 添加 local-deploy 配置 2022-05-30 04:37:02 +08:00
carm 90db463f1d Merge remote-tracking branch 'origin/master' 2022-05-30 04:36:24 +08:00
carm 9248783a16 ci(reploy): 添加 local-deploy 配置 2022-05-30 04:36:10 +08:00
carm 75e8f02228 Merge pull request #47 from CarmJos/dependabot/maven/com.github.chris2018998-beecp-3.3.6
Bump beecp from 3.3.5 to 3.3.6
2022-05-02 21:13:11 +08:00
dependabot[bot] 02b8d561a8 Bump beecp from 3.3.5 to 3.3.6
Bumps [beecp](https://github.com/Chris2018998/BeeCP) from 3.3.5 to 3.3.6.
- [Release notes](https://github.com/Chris2018998/BeeCP/releases)
- [Commits](https://github.com/Chris2018998/BeeCP/compare/3.3.5...3.3.6)

---
updated-dependencies:
- dependency-name: com.github.chris2018998:beecp
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-02 08:31:36 +00:00
carm 19490d7508 Merge remote-tracking branch 'origin/master' 2022-04-27 02:09:07 +08:00
carm e8a01169d2 [0.3.16] 支持 IS NULL 判断(即设定queryValue为null)。 2022-04-27 02:08:58 +08:00
carm 2e1df7c7f6 Merge pull request #46 from CarmJos/dependabot/maven/org.apache.maven.plugins-maven-javadoc-plugin-3.4.0
Bump maven-javadoc-plugin from 3.3.2 to 3.4.0
2022-04-21 17:04:02 +08:00
dependabot[bot] 1812db3a16 Bump maven-javadoc-plugin from 3.3.2 to 3.4.0
Bumps [maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.3.2 to 3.4.0.
- [Release notes](https://github.com/apache/maven-javadoc-plugin/releases)
- [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.3.2...maven-javadoc-plugin-3.4.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-javadoc-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-21 08:31:13 +00:00
carm deb5de35a8 移除api与impl的shaded 2022-04-17 17:23:49 +08:00
carm e9ce0a769c [0.3.15] 版本修复
- `[F]` 修复上一版本中 SQLDebugHandler 的处理出现空指针异常。
2022-04-13 08:04:30 +08:00
carm e98e9586ef [0.3.14] 版本修复
- `[F]` 修复上一版本中 SQLDebugHandler 的处理出现空指针异常。
2022-04-13 07:52:06 +08:00
carm 6cd080210f [0.3.14] 版本修复
- `[F]` 修复上一版本中 SQLDebugHandler 的处理出现空指针异常。
2022-04-13 07:51:56 +08:00
carm 20ac8f3908 [0.3.13] 版本修复
- `[R]` 修复上一版本中 SQLDebugHandler 的处理出现空指针异常。
2022-04-13 07:12:07 +08:00
carm c079c98e3e [0.3.12] 版本更新 (破坏性)
- `[R]` 采用 slf4j-api 替代Java原生的Logger库。
- `[A]` 新增 SQLDebugHandler 用于更好的处理调试消息。
2022-04-13 06:37:19 +08:00
carm 18dd618c21 [0.3.12] 版本更新 (破坏性)
- `[R]` 采用 slf4j-api 替代Java原生的Logger库。
- `[A]` 新增 SQLDebugHandler 用于更好的处理调试消息。
2022-04-13 06:30:20 +08:00
carm 03e157d3d9 [0.3.11] (破坏性更新) 令SQLUpdateAction返回的值为 Long 以适配自增主键大小范围。 2022-04-12 16:46:42 +08:00
carm a2d972621d [0.3.11] (破坏性更新) 令SQLUpdateAction返回的值为 Long 以适配自增主键大小范围。 2022-04-12 16:43:38 +08:00
carm 903f3a5f93 [0.3.11] (破坏性更新) 令SQLUpdateAction返回的值为 Long 以适配自增主键大小范围。 2022-04-12 16:14:35 +08:00
carm 44f9392e81 [0.3.11] (破坏性更新) 令SQLUpdateAction返回的值为 Long 以适配自增主键大小范围。 2022-04-12 16:09:51 +08:00
carm 1ad196f04b Merge remote-tracking branch 'origin/master' 2022-04-12 16:08:43 +08:00
carm fd0a4e48ef [0.3.11] (破坏性更新) 令SQLUpdateAction返回的值为 Long 以适配自增主键大小范围。 2022-04-12 16:08:29 +08:00
carm 14ee6ca1f2 Merge pull request #43 from CarmJos/dependabot/maven/com.h2database-h2-2.1.212
Bump h2 from 2.1.210 to 2.1.212
2022-04-12 03:42:33 +08:00
carm 6ba58b540f [0.3.10] 新增 SQLTable 用于快速创建与该表相关的操作。 2022-04-12 03:36:53 +08:00
dependabot[bot] db33e5e830 Bump h2 from 2.1.210 to 2.1.212
Bumps [h2](https://github.com/h2database/h2database) from 2.1.210 to 2.1.212.
- [Release notes](https://github.com/h2database/h2database/releases)
- [Commits](https://github.com/h2database/h2database/compare/version-2.1.210...version-2.1.212)

---
updated-dependencies:
- dependency-name: com.h2database:h2
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-11 09:50:42 +00:00
carm 3fbc58acf7 移除不必要的异常构造。 2022-04-09 03:26:53 +08:00
99 changed files with 3022 additions and 1127 deletions
+10 -1
View File
@@ -5,10 +5,19 @@
## 目录
- [Bob的EasySQL之旅(HikariCP)](USAGE-HIKARI.md) `@Ghost-Chu`
### 文章
- [Bob的EasySQL之旅(HikariCP)](USAGE-HIKARI.md) `by @Ghost-Chu`
- [在**小项目中**推荐使用的**数据库表**实现方案](USAGE-TABLE.md) `by @CarmJos`
### 视频
- [EasySql快速操作Mysql数据库:我的世界插件开发](https://www.bilibili.com/video/BV1w34y1p7Xs) `by @Shinyoki`
## 实例项目
以下是一些实例项目,可供各位参考。
- UltraDepository 超级仓库插件 `@CarmJos`
- [storage/MySQLStorage](https://github.com/CarmJos/UltraDepository/blob/master/src/main/java/cc/carm/plugin/ultradepository/storage/impl/MySQLStorage.java)
- QuickShop-Hikari 快速商店插件 `@Ghost-Chu`
- [database/](https://github.com/Ghost-chu/QuickShop-Hikari/tree/hikari/quickshop-bukkit/src/main/java/com/ghostchu/quickshop/database)
+2 -2
View File
@@ -1,6 +1,6 @@
> 本文档由 GitHub 用户 @Ghost-chu 创建。
> 本文撰写于 2022/02/09,适配 EasySQL 版本 `v0.3.6`。
> 本文基于 `EasySQL-HikariPool` 版本编写。
> 本文撰写于 2022/02/09,适配 EasySQL 版本 `v0.3.6` **(部分接口已变更)**
> 本文基于 `EasySQL-Hikari` 版本编写。
# EasySQL - HikariPool 使用指南
+161
View File
@@ -0,0 +1,161 @@
> 本文档由 GitHub 用户 @CarmJos 创建。
> 本文撰写于 2022/07/01,基于 EasySQL 版本 `0.4.2` 。
# 在**小项目中**推荐使用的**数据库表**实现方案
## 简介
在小型项目中,我们常常需要编写数据库的表结构,并需要在开发中不断地参考、维护该结构。
在 EasySQL 中,我们提供了一个简单快捷的数据库表创建工具 `TableCreateBuilder`
基于该工具,又在后续版本中提供了 `SQLTable` 类用于快速针对指定表创建不同的数据库操作。
_SQLTable同时提供了有SQLManager参数与无参的操作方法,其中无参方法将自动调用初始化时使用的SQLManager进行操作。_
以下内容是我在许多项目中的使用方法,由于其 `便捷``易于管理``支持引用查询` ,我十分推荐您参考我的方案,并应用到自己的项目中。
### 实例项目:
- [QuickShop-Hikari (DataTables)](https://github.com/Ghost-chu/QuickShop-Hikari/blob/hikari/quickshop-bukkit/src/main/java/com/ghostchu/quickshop/database/DataTables.java)
## 利用 NamedSQLTable 快速创建枚举类以管理
这种方案的优势在于无需复制大量代码,仅需使用EasySQL已经提供的 `NamedSQLTable` 类快捷进行数据库操作。
首先,我们需要创建一个枚举类,[示例代码](../demo/src/main/java/DataTables1.java)如下所示:
```java
import enums.cc.carm.lib.easysql.api.IndexType;
import enums.cc.carm.lib.easysql.api.NumberType;
import table.cc.carm.lib.easysql.api.NamedSQLTable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.sql.SQLException;
public enum DataTables {
DATA(SQLTable.of("data", (table) -> {
table.addAutoIncrementColumn("id", true);
table.addColumn("user", "INT UNSIGNED NOT NULL");
table.addColumn("content", "TEXT NOT NULL");
table.addColumn("time", "DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP");
})),
USER(SQLTable.of("user", (table) -> {
table.addAutoIncrementColumn("id", NumberType.INT, true, true);
table.addColumn("uuid", "VARCHAR(32) NOT NULL UNIQUE KEY");
table.addColumn("username", "VARCHAR(16) NOT NULL");
table.addColumn("age", "TINYINT NOT NULL DEFAULT 1");
table.addColumn("email", "VARCHAR(32)");
table.addColumn("phone", "VARCHAR(16)");
table.addColumn("registerTime", "DATETIME NOT NULL");
table.setIndex("username", IndexType.UNIQUE_KEY); // 添加唯一索引
table.setIndex(IndexType.INDEX, "contact", "email", "phone"); //添加联合索引 (示例)
}));
private final NamedSQLTable table;
DataTables(NamedSQLTable table) {
this.table = table;
}
public NamedSQLTable get() {
return this.table;
}
public static void initialize(@NotNull SQLManager manager, @Nullable String tablePrefix) {
for (DataTables value : values()) {
try {
value.get().create(manager, tablePrefix);
} catch (SQLException e) {
// 提示异常
}
}
}
}
```
随后,我们便可以在数据库初始化时调用 `DataTables#initialize(manager,tablePrefix)` 方法快捷的进行表的初始化。
初始化后,我们便可以通过 `DataTables#get()` 方法获取对应表的 `NamedSQLTable` 实例,以进行 `createQuery()` 等操作。
## 利用枚举类实现 SQLTable 进行操作
这种方法相较于前者代码量稍多些,但无需在每次调用先通过 `DataTables#get()` 方法获取 NamedSQLTable 实例,代码上更为简洁。
且可以通过重写 `getTableName()` 方法来自行规定表前缀。
_该方法为本人最常用,也是最推荐的方法。_
[示例代码](../demo/src/main/java/DataTables2.java)如下:
```java
import builder.cc.carm.lib.easysql.api.TableCreateBuilder;
import enums.cc.carm.lib.easysql.api.IndexType;
import enums.cc.carm.lib.easysql.api.NumberType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.sql.SQLException;
import java.util.function.Consumer;
public enum DataTables implements SQLTable {
USER((table) -> {
table.addAutoIncrementColumn("id", NumberType.INT, true, true);
table.addColumn("uuid", "VARCHAR(32) NOT NULL UNIQUE KEY");
table.addColumn("username", "VARCHAR(16) NOT NULL");
table.addColumn("age", "TINYINT NOT NULL DEFAULT 1");
table.addColumn("email", "VARCHAR(32)");
table.addColumn("phone", "VARCHAR(16)");
table.addColumn("registerTime", "DATETIME NOT NULL");
table.setIndex("username", IndexType.UNIQUE_KEY); // 添加唯一索引
table.setIndex(IndexType.INDEX, "contact", "email", "phone"); //添加联合索引 (示例)
});
private final Consumer<TableCreateBuilder> builder;
private @Nullable String tablePrefix;
private @Nullable SQLManager manager;
DataTables(Consumer<TableCreateBuilder> builder) {
this.builder = builder;
}
@Override
public @Nullable SQLManager getSQLManager() {
return this.manager;
}
@Override
public @NotNull String getTableName() {
// 这里直接选择用枚举的名称作为table的主名称
return (tablePrefix != null ? tablePrefix : "") + name().toLowerCase();
}
@Override
public boolean create(SQLManager sqlManager) throws SQLException {
return create(sqlManager, null);
}
public boolean create(@NotNull SQLManager sqlManager, @Nullable String tablePrefix) throws SQLException {
if (this.manager == null) this.manager = sqlManager;
this.tablePrefix = tablePrefix;
TableCreateBuilder tableBuilder = sqlManager.createTable(getTableName());
if (builder != null) builder.accept(tableBuilder);
return tableBuilder.build().executeFunction(l -> l > 0, false);
}
public static void initialize(@NotNull SQLManager manager, @Nullable String tablePrefix) {
for (DataTables value : values()) {
try {
value.create(manager, tablePrefix);
} catch (SQLException e) {
// 提示异常
}
}
}
}
```
+27
View File
@@ -0,0 +1,27 @@
# EasySQL Repository
采用github的repo分支进行依赖,随项目发布而自动更新。
其他依赖方式见主页介绍。
## 依赖方式
### Maven
```xml
<repositories>
<repository>
<id>EasySQL</id>
<name>GitHub Branch Repository</name>
<url>https://github.com/CarmJos/EasySQL/blob/repo/</url>
</repository>
</repositories>
```
### Gradle
```groovy
repositories {
maven { url 'https://github.com/CarmJos/EasySQL/blob/repo/' }
}
```
+82 -52
View File
@@ -11,10 +11,9 @@ on:
types: [ published ]
jobs:
gh-deploy:
name: "Publish Project (GitHub)"
packages-deploy:
name: "Publish Project (GitHub Packages)"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: "Set up JDK"
@@ -29,63 +28,16 @@ jobs:
gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} # Value of the GPG private key to import
gpg-passphrase: MAVEN_GPG_PASSPHRASE # env variable for GPG private key passphrase
- name: "Maven Deploy With Javadoc"
- name: "Packages Deploy"
run: mvn -B -Pgithub deploy --file pom.xml -DskipTests
env:
MAVEN_USERNAME: ${{ github.repository_owner }}
MAVEN_TOKEN: ${{secrets.GITHUB_TOKEN}}
MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }}
- name: "Copy Javadoc to Location"
run: |
rm -rf docs
mkdir -vp docs
cp -vrf api/target/apidocs/* docs/
cp -vrf .documentation/JAVADOC-README.md docs/README.md
- name: "Generate the Javadoc sitemap"
id: sitemap
uses: cicirello/generate-sitemap@v1
with:
base-url-path: https://carmjos.github.io/EasySQL
path-to-root: docs
- name: "Output stats"
run: |
echo "sitemap-path = ${{ steps.sitemap.outputs.sitemap-path }}"
echo "url-count = ${{ steps.sitemap.outputs.url-count }}"
echo "excluded-count = ${{ steps.sitemap.outputs.excluded-count }}"
- name: "Configure Git"
env:
DEPLOY_PRI: ${{secrets.DEPLOY_PRI}}
run: |
sudo timedatectl set-timezone "Asia/Shanghai"
mkdir -p ~/.ssh/
echo "$DEPLOY_PRI" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan github.com >> ~/.ssh/known_hosts
git config --global user.name 'CarmJos'
git config --global user.email 'carm@carm.cc'
- name: "Commit documentations"
run: |
cd docs
git init
git remote add origin git@github.com:CarmJos/EasySQL.git
git checkout -b gh-pages
git add -A
git commit -m "API Document generated."
- name: "Push javadocs"
run: |
cd docs
git push origin HEAD:gh-pages --force
central-deploy:
name: "Deploy Project (Central Repository)"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: "Set up JDK"
@@ -105,4 +57,82 @@ jobs:
env:
MAVEN_USERNAME: ${{ secrets.OSSRH_USER }}
MAVEN_PASSWORD: ${{ secrets.OSSRH_PASS }}
MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }}
MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }}
github-deploy:
name: "Deploy Project (GitHub Repository)"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: "Set up JDK"
uses: actions/setup-java@v2
with:
java-version: '11'
distribution: 'adopt'
cache: maven
gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} # Value of the GPG private key to import
gpg-passphrase: MAVEN_GPG_PASSPHRASE # env variable for GPG private key passphrase
- name: "Maven Deploy"
run: mvn -B -Plocal deploy --file pom.xml -DskipTests
env:
MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }}
- name: "Copy artifacts"
run: |
rm -rf deploy
mkdir -vp deploy
cp -vrf $HOME/local-deploy/* deploy/
cp -vrf .documentation/repository/README.md deploy/README.md
- name: "Copy Javadoc"
run: |
rm -rf docs
mkdir -vp docs
cp -vrf api/target/apidocs/* docs/
cp -vrf .documentation/javadoc/README.md docs/README.md
- name: "Generate the Javadoc sitemap"
id: sitemap
uses: cicirello/generate-sitemap@v1
with:
base-url-path: https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}
path-to-root: docs
- name: "Output stats"
run: |
echo "sitemap-path = ${{ steps.sitemap.outputs.sitemap-path }}"
echo "url-count = ${{ steps.sitemap.outputs.url-count }}"
echo "excluded-count = ${{ steps.sitemap.outputs.excluded-count }}"
- name: "Configure Git"
env:
DEPLOY_PRI: ${{secrets.DEPLOY_PRI}}
run: |
sudo timedatectl set-timezone "Asia/Shanghai"
mkdir -p ~/.ssh/
echo "$DEPLOY_PRI" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan github.com >> ~/.ssh/known_hosts
git config --global user.name '${{ github.repository_owner }}'
git config --global user.email '${{ github.repository_owner }}@users.noreply.github.com'
- name: "Commit&Push repository files"
run: |
cd deploy
git init
git remote add origin git@github.com:${{ github.repository_owner }}/${{ github.event.repository.name }}.git
git checkout -b repo
git add -A
git commit -m "Maven project deployment."
git push origin HEAD:repo --force
- name: "Commit&Push documentations"
run: |
cd docs
git init
git remote add origin git@github.com:${{ github.repository_owner }}/${{ github.event.repository.name }}.git
git checkout -b gh-pages
git add -A
git commit -m "API documentation deployment."
git push origin HEAD:gh-pages --force
+20 -10
View File
@@ -10,7 +10,7 @@
# EasySQL
[![version](https://img.shields.io/github/v/release/CarmJos/EasySQL)](https://github.com/CarmJos/EasySQL/releases)
[![License](https://img.shields.io/github/license/CarmJos/EasySQL)](https://opensource.org/licenses/GPL-3.0)
[![License](https://img.shields.io/github/license/CarmJos/EasySQL)](https://opensource.org/licenses/MIT)
[![workflow](https://github.com/CarmJos/EasySQL/actions/workflows/maven.yml/badge.svg?branch=master)](https://github.com/CarmJos/EasySQL/actions/workflows/maven.yml)
[![CodeFactor](https://www.codefactor.io/repository/github/carmjos/easysql/badge)](https://www.codefactor.io/repository/github/carmjos/easysql)
![CodeSize](https://img.shields.io/github/languages/code-size/CarmJos/EasySQL)
@@ -18,7 +18,7 @@
简单便捷的数据库操作工具,可自定义连接池来源。
随项目分别提供 [BeeCP](https://github.com/Chris2018998/BeeCP) 与 [Hikari](https://github.com/brettwooldridge/HikariCP~~~~)
随项目分别提供 [BeeCP](https://github.com/Chris2018998/BeeCP) 与 [Hikari](https://github.com/brettwooldridge/HikariCP)
两个连接池的版本。
## 优势
@@ -35,7 +35,7 @@
### 示例代码
您可以 [点击这里](example/easysql-demo/src/main/java/EasySQLDemo.java) 查看部分代码演示,更多演示详见 [开发介绍](.documentation/README.md) 。
您可以 [点击这里](demo/src/main/java/EasySQLDemo.java) 查看部分代码演示,更多演示详见 [开发介绍](.documentation/README.md) 。
### 依赖方式
@@ -55,9 +55,16 @@
<name>Maven Central</name>
<url>https://repo1.maven.org/maven2</url>
</repository>
<repository>
<!--采用github依赖,实时更新,但需要配置 (推荐) -->
<!--采用github的repo分支依赖,实时更新 (推荐)-->
<id>EasySQL</id>
<name>GitHub Branch Repository</name>
<url>https://github.com/CarmJos/EasySQL/blob/repo/</url>
</repository>
<repository>
<!--采用github packages依赖库,安全稳定,但需要配置 -->
<id>EasySQL</id>
<name>GitHub Packages</name>
<url>https://maven.pkg.github.com/CarmJos/EasySQL</url>
@@ -141,8 +148,11 @@ repositories {
// 采用Maven中心库,安全稳定,但版本更新需要等待同步
mavenCentral()
// 采用github依赖,实时更新,但需要配置 (推荐)
// 采用github的repo分支依赖,实时更新 (推荐)
maven { url 'https://github.com/CarmJos/EasySQL/blob/repo/' }
// 采用github依赖库,安全稳定,但需要配置
maven { url 'https://maven.pkg.github.com/CarmJos/EasySQL' }
// 采用我的私人依赖库,简单方便,但可能因为变故而无法使用
@@ -190,11 +200,11 @@ dependencies {
## 支持与捐赠
若您觉得本插件做的不错,您可以通过捐赠支持我!
若您觉得本插件做的不错,您可以通过捐赠支持我! 感谢您对开源项目的支持!
感谢您对开源项目的支持!
Many thanks to Jetbrains for kindly providing a license for me to work on this and other open-source projects.
[![](https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.svg)](https://www.jetbrains.com/?from=https://github.com/CarmJos/EasySQL)
<img height=25% width=25% src="https://raw.githubusercontent.com/CarmJos/CarmJos/main/img/donate-code.jpg" alt=""/>
## 开源协议
+11 -7
View File
@@ -5,13 +5,13 @@
<parent>
<groupId>cc.carm.lib</groupId>
<artifactId>easysql-parent</artifactId>
<version>0.3.9</version>
<version>0.4.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<properties>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<maven.compiler.source>${jdk.version}</maven.compiler.source>
<maven.compiler.target>${jdk.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
</properties>
@@ -52,6 +52,14 @@
<url>https://github.com/CarmJos/EasySQL/actions/workflows/maven.yml</url>
</ciManagement>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.36</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
@@ -70,10 +78,6 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
</plugin>
</plugins>
</build>
@@ -1,10 +1,11 @@
package cc.carm.lib.easysql.api;
import cc.carm.lib.easysql.api.action.SQLBaseAction;
import org.jetbrains.annotations.NotNull;
/**
* SQLBuilder 是用于构建SQL语句以生成SQLAction执行操作的中间类。
* <br>其连接了{@link SQLManager} 与 {@link SQLAction} ,避免大量的代码堆积
* <br>其连接了{@link SQLManager} 与 {@link SQLBaseAction} ,避免大量的代码堆积
* <br>也是本接口的核心功能所在
*
* @author CarmJos
@@ -1,79 +1,26 @@
package cc.carm.lib.easysql.api;
import cc.carm.lib.easysql.api.action.PreparedSQLUpdateAction;
import cc.carm.lib.easysql.api.action.PreparedSQLUpdateBatchAction;
import cc.carm.lib.easysql.api.action.SQLUpdateAction;
import cc.carm.lib.easysql.api.action.SQLUpdateBatchAction;
import cc.carm.lib.easysql.api.action.query.PreparedSQLQueryAction;
import cc.carm.lib.easysql.api.action.query.SQLQueryAction;
import cc.carm.lib.easysql.api.action.update.PreparedSQLBatchUpdateAction;
import cc.carm.lib.easysql.api.action.update.PreparedSQLUpdateAction;
import cc.carm.lib.easysql.api.action.update.SQLBatchUpdateAction;
import cc.carm.lib.easysql.api.action.update.SQLUpdateAction;
import cc.carm.lib.easysql.api.builder.*;
import cc.carm.lib.easysql.api.function.SQLExceptionHandler;
import cc.carm.lib.easysql.api.enums.IsolationLevel;
import cc.carm.lib.easysql.api.function.SQLBiFunction;
import cc.carm.lib.easysql.api.function.SQLFunction;
import cc.carm.lib.easysql.api.transaction.SQLTransaction;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.Supplier;
import java.util.logging.Logger;
import java.util.concurrent.CompletableFuture;
/**
* SQLManager 是EasySQL的核心类,用于管理数据库连接,提供数据库操作的方法。
*
* @author CarmJos
*/
public interface SQLManager {
Logger getLogger();
boolean isDebugMode();
void setDebugMode(@NotNull Supplier<@NotNull Boolean> debugMode);
default void setDebugMode(boolean enable) {
setDebugMode(() -> enable);
}
/**
* 得到连接池源
*
* @return DataSource
*/
@NotNull DataSource getDataSource();
/**
* 得到一个数据库连接实例
*
* @return Connection
* @throws SQLException 见 {@link DataSource#getConnection()}
*/
@NotNull Connection getConnection() throws SQLException;
/**
* 得到正使用的查询。
*
* @return 查询列表
*/
@NotNull Map<UUID, SQLQuery> getActiveQuery();
/**
* 获取改管理器提供的默认异常处理器。
* 若未使用过 {@link #setExceptionHandler(SQLExceptionHandler)} 方法,
* 则默认返回 {@link SQLExceptionHandler#detailed(Logger)} 。
*
* @return {@link SQLExceptionHandler}
*/
@NotNull SQLExceptionHandler getExceptionHandler();
/**
* 设定通用的异常处理器。
* <br> 在使用 {@link SQLAction#execute(SQLExceptionHandler)} 等相关方法时,若传入的处理器为null,则会采用此处理器。
* <br> 若该方法传入参数为 null,则会使用 {@link SQLExceptionHandler#detailed(Logger)} 。
*
* @param handler 异常处理器
*/
void setExceptionHandler(@Nullable SQLExceptionHandler handler);
public interface SQLManager extends SQLSource {
/**
* 执行一条不需要返回结果的SQL语句(多用于UPDATE、REPLACE、DELETE方法)
@@ -101,11 +48,10 @@ public interface SQLManager {
* @param sql SQL语句内容
* @param paramsBatch SQL语句中对应?的参数组
* @return 对应参数返回的行数
* @see PreparedSQLUpdateBatchAction
* @see PreparedSQLBatchUpdateAction
*/
@Nullable List<Integer> executeSQLBatch(String sql, Iterable<Object[]> paramsBatch);
/**
* 执行多条不需要返回结果的SQL。
* 该方法使用 Statement 实现,请注意SQL注入风险!
@@ -113,7 +59,7 @@ public interface SQLManager {
* @param sql SQL语句内容
* @param moreSQL 更多SQL语句内容
* @return 对应参数返回的行数
* @see SQLUpdateBatchAction
* @see SQLBatchUpdateAction
*/
@Nullable List<Integer> executeSQLBatch(@NotNull String sql, String... moreSQL);
@@ -125,75 +71,138 @@ public interface SQLManager {
*/
@Nullable List<Integer> executeSQLBatch(@NotNull Iterable<String> sqlBatch);
/**
* 在库中创建一个表
*
* @param tableName 表名
* @return {@link TableCreateBuilder}
*/
TableCreateBuilder createTable(@NotNull String tableName);
default @NotNull SQLTransaction createTransaction() {
return createTransaction(null);
}
@NotNull SQLTransaction createTransaction(@Nullable IsolationLevel level);
/**
* 对库中的某个表执行更改
*
* @param tableName 表名
* @return {@link TableAlterBuilder}
*/
TableAlterBuilder alterTable(@NotNull String tableName);
/**
* 新建一个查询
* 新建一个查询。
*
* @return {@link QueryBuilder}
*/
QueryBuilder createQuery();
@NotNull QueryBuilder<SQLQueryAction.Advanced, PreparedSQLQueryAction.Advanced> createQuery();
/**
* 创建一条插入操作
* 创建一条插入操作
*
* @param tableName 目标表名
* @return {@link InsertBuilder}
*/
InsertBuilder<PreparedSQLUpdateAction> createInsert(@NotNull String tableName);
@NotNull InsertBuilder<PreparedSQLUpdateAction.Advanced<Integer>> insertInto(@NotNull String tableName);
/**
* 创建支持多组数据的插入操作
* 创建支持多组数据的插入操作
*
* @param tableName 目标表名
* @return {@link InsertBuilder}
*/
InsertBuilder<PreparedSQLUpdateBatchAction> createInsertBatch(@NotNull String tableName);
@NotNull InsertBuilder<PreparedSQLBatchUpdateAction.Advanced<Integer>> insertBatchInto(@NotNull String tableName);
/**
* 创建一条替换操作
* 创建一条替换操作
*
* @param tableName 目标表名
* @return {@link ReplaceBuilder}
*/
ReplaceBuilder<PreparedSQLUpdateAction> createReplace(@NotNull String tableName);
@NotNull ReplaceBuilder<PreparedSQLUpdateAction.Advanced<Integer>> replaceInto(@NotNull String tableName);
/**
* 创建支持多组数据的替换操作
* 创建支持多组数据的替换操作
*
* @param tableName 目标表名
* @return {@link ReplaceBuilder}
*/
ReplaceBuilder<PreparedSQLUpdateBatchAction> createReplaceBatch(@NotNull String tableName);
@NotNull ReplaceBuilder<PreparedSQLBatchUpdateAction.Advanced<Integer>> replaceBatchInto(@NotNull String tableName);
/**
* 创建更新操作
* 创建更新操作
*
* @param tableName 目标表名
* @return {@link UpdateBuilder}
*/
UpdateBuilder createUpdate(@NotNull String tableName);
@NotNull UpdateBuilder<PreparedSQLUpdateAction.Advanced<Integer>> updateInto(@NotNull String tableName);
/**
* 创建删除操作
* 创建删除操作
*
* @param tableName 目标表名
* @return {@link DeleteBuilder}
*/
DeleteBuilder createDelete(@NotNull String tableName);
@NotNull DeleteBuilder<PreparedSQLUpdateAction.Advanced<Integer>> deleteFrom(@NotNull String tableName);
/**
* 在库中创建一个表。
*
* @param tableName 表名
* @return {@link TableCreateBuilder}
*/
@NotNull TableCreateBuilder createTable(@NotNull String tableName);
/**
* 对库中的某个表执行更改。
*
* @param tableName 表名
* @return {@link TableAlterBuilder}
*/
@NotNull TableAlterBuilder alterTable(@NotNull String tableName);
/**
* 快速获取表的部分元数据。
* <br> 当需要获取其他元数据时,请使用 {@link #fetchMetadata(SQLFunction, SQLFunction)} 方法。
*
* @param tablePattern 表名通配符
* @return {@link TableMetadataBuilder}
*/
@NotNull TableMetadataBuilder fetchTableMetadata(@NotNull String tablePattern);
/**
* 获取并操作 {@link DatabaseMetaData} 以得到需要的数据库消息。
*
* @param reader 操作与读取的方法
* @param <R> 最终结果的返回类型
* @return 最终结果,通过 {@link CompletableFuture#get()} 可阻塞并等待结果返回。
*/
default <R> CompletableFuture<R> fetchMetadata(@NotNull SQLFunction<DatabaseMetaData, R> reader) {
return fetchMetadata((meta, conn) -> reader.apply(meta));
}
/**
* 获取并操作 {@link DatabaseMetaData} 提供的指定 {@link ResultSet} 以得到需要的数据库消息。
* <br> 该方法会自动关闭 {@link ResultSet} 。
*
* @param supplier 操作 {@link DatabaseMetaData} 以提供信息所在的 {@link ResultSet}
* @param reader 读取 {@link ResultSet} 中指定信息的方法
* @param <R> 最终结果的返回类型
* @return 最终结果,通过 {@link CompletableFuture#get()} 可阻塞并等待结果返回。
* @throws NullPointerException 当 supplier 提供的 {@link ResultSet} 为NULL时抛出
*/
default <R> CompletableFuture<R> fetchMetadata(@NotNull SQLFunction<DatabaseMetaData, ResultSet> supplier,
@NotNull SQLFunction<@NotNull ResultSet, R> reader) {
return fetchMetadata((meta, conn) -> supplier.apply(meta), reader);
}
/**
* 获取并操作 {@link DatabaseMetaData} 以得到需要的数据库消息。
*
* @param reader 操作与读取的方法
* @param <R> 最终结果的返回类型
* @return 最终结果,通过 {@link CompletableFuture#get()} 可阻塞并等待结果返回。
*/
<R> CompletableFuture<R> fetchMetadata(@NotNull SQLBiFunction<DatabaseMetaData, Connection, R> reader);
/**
* 获取并操作 {@link DatabaseMetaData} 提供的指定 {@link ResultSet} 以得到需要的数据库消息。
* <br> 该方法会自动关闭 {@link ResultSet} 。
*
* @param supplier 操作 {@link DatabaseMetaData} 以提供信息所在的 {@link ResultSet}
* @param reader 读取 {@link ResultSet} 中指定信息的方法
* @param <R> 最终结果的返回类型
* @return 最终结果,通过 {@link CompletableFuture#get()} 可阻塞并等待结果返回。
* @throws NullPointerException 当 supplier 提供的 {@link ResultSet} 为NULL时抛出
*/
<R> CompletableFuture<R> fetchMetadata(@NotNull SQLBiFunction<DatabaseMetaData, Connection, ResultSet> supplier,
@NotNull SQLFunction<@NotNull ResultSet, R> reader);
}
@@ -1,11 +1,13 @@
package cc.carm.lib.easysql.api;
import cc.carm.lib.easysql.api.action.query.PreparedQueryAction;
import cc.carm.lib.easysql.api.action.query.QueryAction;
import cc.carm.lib.easysql.api.action.query.PreparedSQLQueryAction;
import cc.carm.lib.easysql.api.action.query.SQLQueryAction;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.concurrent.TimeUnit;
/**
* SQLQuery 是一个查询中间接口,用于查询操作的封装。
@@ -16,10 +18,22 @@ public interface SQLQuery extends AutoCloseable {
/**
* 获取该查询创建的时间
* <br>注意,此处获得的时间非时间戳毫秒数,仅用于计算耗时。
*
* @return 创建时间
*/
long getExecuteTime();
default long getExecuteTime() {
return getExecuteTime(TimeUnit.MILLISECONDS);
}
/**
* 获取该查询创建的时间
* <br>注意,此处获得的时间非时间戳毫秒数,仅用于计算耗时。
*
* @param timeUnit 时间单位
* @return 创建时间
*/
long getExecuteTime(TimeUnit timeUnit);
/**
* 得到承载该SQLQuery的对应{@link SQLManager}
@@ -29,11 +43,11 @@ public interface SQLQuery extends AutoCloseable {
SQLManager getManager();
/**
* 得到承载该SQLQuery的对应{@link QueryAction}
* 得到承载该SQLQuery的对应{@link SQLQueryAction}
*
* @return {@link QueryAction} 或 {@link PreparedQueryAction}
* @return {@link SQLQueryAction} 或 {@link PreparedSQLQueryAction}
*/
QueryAction getAction();
SQLQueryAction<?> getAction();
ResultSet getResultSet();
@@ -0,0 +1,121 @@
package cc.carm.lib.easysql.api;
import cc.carm.lib.easysql.api.action.SQLAdvancedAction;
import cc.carm.lib.easysql.api.function.SQLDebugHandler;
import cc.carm.lib.easysql.api.function.SQLExceptionHandler;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Supplier;
public interface SQLSource {
@NotNull Logger getLogger();
/**
* 获取用于执行 {@link SQLAdvancedAction#executeAsync()} 的线程池。
* <br> 默认线程池为 {@link #defaultExecutorPool(String)} 。
*
* @return {@link ExecutorService}
*/
@NotNull ExecutorService getExecutorPool();
/**
* 设定用于执行 {@link SQLAdvancedAction#executeAsync()} 的线程池.
* <br> 默认线程池为 {@link #defaultExecutorPool(String)} 。
*
* @param executorPool {@link ExecutorService}
*/
void setExecutorPool(@NotNull ExecutorService executorPool);
static @NotNull ExecutorService defaultExecutorPool(@NotNull String threadName) {
return Executors.newFixedThreadPool(4, r -> {
Thread thread = new Thread(r, threadName);
thread.setDaemon(true);
return thread;
});
}
boolean isDebugMode();
/**
* 设定是否启用调试模式。
* 启用调试模式后,会在每次执行SQL语句时,调用 {@link #getDebugHandler()} 来输出调试信息。
*
* @param debugMode 是否启用调试模式
*/
void setDebugMode(@NotNull Supplier<@NotNull Boolean> debugMode);
/**
* 设定是否启用调试模式。
* 启用调试模式后,会在每次执行SQL语句时,调用 {@link #getDebugHandler()} 来输出调试信息。
*
* @param enable 是否启用调试模式
*/
default void setDebugMode(boolean enable) {
setDebugMode(() -> enable);
}
/**
* 获取调试处理器,用于处理调试信息。
*
* @return {@link SQLDebugHandler}
*/
@NotNull SQLDebugHandler getDebugHandler();
/**
* 设定调试处理器,默认为 {@link SQLDebugHandler#defaultHandler(Logger)} 。
*
* @param debugHandler {@link SQLDebugHandler}
*/
void setDebugHandler(@NotNull SQLDebugHandler debugHandler);
/**
* 得到连接池源
*
* @return DataSource
*/
@NotNull DataSource getDataSource();
/**
* 得到一个数据库连接实例
*
* @return Connection
* @throws SQLException 见 {@link DataSource#getConnection()}
*/
@NotNull Connection getConnection() throws SQLException;
/**
* 得到正使用的查询。
*
* @return 查询列表
*/
@NotNull Map<UUID, SQLQuery> getActiveQueries();
/**
* 获取改管理器提供的默认异常处理器。
* 若未使用过 {@link #setExceptionHandler(SQLExceptionHandler)} 方法,
* 则默认返回 {@link SQLExceptionHandler#detailed(Logger)} 。
*
* @return {@link SQLExceptionHandler}
*/
@NotNull SQLExceptionHandler getExceptionHandler();
/**
* 设定通用的异常处理器。
* <br> 在使用 {@link SQLAdvancedAction#execute(SQLExceptionHandler)} 等相关方法时,若传入的处理器为null,则会采用此处理器。
* <br> 若该方法传入参数为 null,则会使用 {@link SQLExceptionHandler#detailed(Logger)} 。
*
* @param handler 异常处理器
*/
void setExceptionHandler(@Nullable SQLExceptionHandler handler);
}
@@ -1,23 +0,0 @@
package cc.carm.lib.easysql.api.action;
import org.jetbrains.annotations.Nullable;
public interface PreparedSQLUpdateAction extends SQLUpdateAction {
/**
* 设定SQL语句中所有 ? 对应的参数
*
* @param params 参数内容
* @return {@link PreparedSQLUpdateAction}
*/
PreparedSQLUpdateAction setParams(Object... params);
/**
* 设定SQL语句中所有 ? 对应的参数
*
* @param params 参数内容
* @return {@link PreparedSQLUpdateAction}
*/
PreparedSQLUpdateAction setParams(@Nullable Iterable<Object> params);
}
@@ -1,56 +0,0 @@
package cc.carm.lib.easysql.api.action;
import cc.carm.lib.easysql.api.SQLAction;
import java.util.List;
public interface PreparedSQLUpdateBatchAction extends SQLAction<List<Integer>> {
/**
* 设定多组SQL语句中所有 ? 对应的参数
*
* @param allParams 所有参数内容
* @return {@link PreparedSQLUpdateBatchAction}
*/
PreparedSQLUpdateBatchAction setAllParams(Iterable<Object[]> allParams);
/**
* 添加一组SQL语句中所有 ? 对应的参数
*
* @param params 参数内容
* @return {@link PreparedSQLUpdateBatchAction}
*/
PreparedSQLUpdateBatchAction addParamsBatch(Object... params);
/**
* 设定自增主键的序列
*
* @param keyColumnIndex 自增主键的序列
* <br>若该值 0,则 {@link #execute()} 返回自增主键数值
* <br>若该值 ≤ 0,则 {@link #execute()} 返回变更的行数
* @return {@link PreparedSQLUpdateBatchAction}
* @see #setReturnGeneratedKeys(boolean)
*/
@Deprecated
default PreparedSQLUpdateBatchAction setKeyIndex(int keyColumnIndex) {
return setReturnGeneratedKeys(keyColumnIndex > 0);
}
/**
* 设定该操作返回自增键序列。
*
* @return {@link PreparedSQLUpdateBatchAction}
*/
default PreparedSQLUpdateBatchAction returnGeneratedKeys() {
return setReturnGeneratedKeys(true);
}
/**
* 设定该操作是否返回自增键序列。
*
* @param returnGeneratedKey 是否返回自增键序列
* @return {@link PreparedSQLUpdateBatchAction}
*/
PreparedSQLUpdateBatchAction setReturnGeneratedKeys(boolean returnGeneratedKey);
}
@@ -1,4 +1,4 @@
package cc.carm.lib.easysql.api;
package cc.carm.lib.easysql.api.action;
import cc.carm.lib.easysql.api.function.SQLExceptionHandler;
import cc.carm.lib.easysql.api.function.SQLFunction;
@@ -6,13 +6,14 @@ import cc.carm.lib.easysql.api.function.SQLHandler;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import java.sql.SQLException;
import java.util.UUID;
import java.util.logging.Logger;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
/**
* SQLAction 是用于承载SQL语句并进行处理返回的基本
* SQLAdvancedAction 是用于承载SQL语句并进行处理返回的高级
*
* <ul>
* <li>同步执行 {@link #execute()}, {@link #execute(SQLFunction, SQLExceptionHandler)}
@@ -28,53 +29,9 @@ import java.util.logging.Logger;
*
* @param <T> 需要返回的类型
* @author CarmJos
* @since 0.0.1
* @since 0.5.0
*/
public interface SQLAction<T> {
/**
* 得到该Action的UUID
*
* @return UUID
*/
@NotNull UUID getActionUUID();
/**
* 得到短八位格式的UUID
*
* @return UUID(8)
*/
@NotNull String getShortID();
/**
* 得到该Action的创建时间
*
* @return 创建时间
*/
long getCreateTime();
/**
* 得到该Action所要执行的源SQL语句
*
* @return 源SQL语句
*/
@NotNull String getSQLContent();
/**
* 得到承载该Action的对应{@link SQLManager}
*
* @return {@link SQLManager}
*/
@NotNull SQLManager getManager();
/**
* 执行该Action对应的SQL语句
*
* @return 指定数据类型
* @throws SQLException 当SQL操作出现问题时抛出
*/
@NotNull T execute() throws SQLException;
public interface SQLAdvancedAction<T> extends SQLBaseAction<T> {
/**
* 执行语句并返回值
@@ -123,40 +80,6 @@ public interface SQLAction<T> {
}
}
/**
* 执行语句并处理返回值
*
* @param function 处理方法
* @param <R> 需要返回的内容
* @return 指定类型数据
* @throws SQLException 当SQL操作出现问题时抛出
*/
@Nullable
default <R> R executeFunction(@NotNull SQLFunction<@NotNull T, R> function) throws SQLException {
return executeFunction(function, null);
}
/**
* 执行语句并处理返回值
*
* @param function 处理方法
* @param defaultResult 默认结果若处理后的结果为null则返回该值
* @param <R> 需要返回的内容
* @return 指定类型数据
* @throws SQLException 当SQL操作出现问题时抛出
*/
@Nullable
@Contract("_,!null -> !null")
default <R> R executeFunction(@NotNull SQLFunction<@NotNull T, R> function,
@Nullable R defaultResult) throws SQLException {
try {
R result = function.apply(execute());
return result == null ? defaultResult : result;
} catch (SQLException exception) {
throw new SQLException(exception);
}
}
/**
* 异步执行SQL语句采用默认异常处理无需返回值
*/
@@ -177,11 +100,28 @@ public interface SQLAction<T> {
* 异步执行SQL语句
*
* @param success 成功时的操作
* @param failure 异常处理器 默认为 {@link SQLAction#defaultExceptionHandler()}
* @param failure 异常处理器 默认为 {@link SQLAdvancedAction#defaultExceptionHandler()}
*/
void executeAsync(@Nullable SQLHandler<T> success,
@Nullable SQLExceptionHandler failure);
/**
* 以异步Future方式执行SQL语句
*
* @return 异步执行的Future实例可通过 {@link Future#get()} 阻塞并等待结果
*/
default @NotNull CompletableFuture<Void> executeFuture() {
return executeFuture((t -> null));
}
/**
* 以异步Future方式执行SQL语句
*
* @return 异步执行的Future实例可通过 {@link Future#get()} 阻塞并等待结果
*/
<R> @NotNull CompletableFuture<R> executeFuture(@NotNull SQLFunction<T, R> handler);
default void handleException(@Nullable SQLExceptionHandler handler, SQLException exception) {
if (handler == null) handler = defaultExceptionHandler();
handler.accept(exception, this);
@@ -195,7 +135,7 @@ public interface SQLAction<T> {
* @return {@link SQLExceptionHandler}
*/
default SQLExceptionHandler defaultExceptionHandler() {
return getManager().getExceptionHandler();
return getSource().getExceptionHandler();
}
/**
@@ -206,7 +146,8 @@ public interface SQLAction<T> {
* @param handler 异常处理器
*/
default void setExceptionHandler(@Nullable SQLExceptionHandler handler) {
getManager().setExceptionHandler(handler);
getSource().setExceptionHandler(handler);
}
}
@@ -0,0 +1,122 @@
package cc.carm.lib.easysql.api.action;
import cc.carm.lib.easysql.api.SQLSource;
import cc.carm.lib.easysql.api.function.SQLFunction;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.sql.SQLException;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
/**
* SQLBaseAction 是用于承载SQL语句并进行处理、返回的基本类。
*
* @param <T> 需要返回的类型
* @author CarmJos
* @since 0.0.1
*/
public interface SQLBaseAction<T> {
/**
* 得到该Action的UUID
*
* @return UUID
*/
@NotNull UUID getActionUUID();
/**
* 得到短八位格式的UUID
*
* @return UUID(8)
*/
@NotNull String getShortID();
/**
* 得到该Action的创建时间。
* <br>注意,此处获得的时间非时间戳毫秒数,仅用于计算耗时。
*
* @return 创建时间 (毫秒)
*/
default long getCreateTime() {
return getCreateTime(TimeUnit.MILLISECONDS);
}
/**
* 得到该Action的创建时间
* <br>注意,此处获得的时间非时间戳毫秒数,仅用于计算耗时。
*
* @param unit 时间单位
* @return 创建时间
*/
long getCreateTime(TimeUnit unit);
/**
* 得到该Action所要执行的源SQL语句
*
* @return 源SQL语句
*/
@NotNull String getSQLContent();
/**
* 得到该Action所要执行的源SQL语句列表。
*
* @return 源SQL语句列表
*/
default @NotNull List<String> getSQLContents() {
return Collections.singletonList(getSQLContent());
}
/**
* 得到承载该Action的对应{@link SQLSource}
*
* @return {@link SQLSource}
*/
@NotNull SQLSource getSource();
/**
* 执行该Action对应的SQL语句
*
* @return 指定数据类型
* @throws SQLException 当SQL操作出现问题时抛出
*/
@NotNull T execute() throws SQLException;
/**
* 执行语句并处理返回值
*
* @param function 处理方法
* @param <R> 需要返回的内容
* @return 指定类型数据
* @throws SQLException 当SQL操作出现问题时抛出
*/
@Nullable
default <R> R executeFunction(@NotNull SQLFunction<@NotNull T, R> function) throws SQLException {
return executeFunction(function, null);
}
/**
* 执行语句并处理返回值
*
* @param function 处理方法
* @param defaultResult 默认结果,若处理后的结果为null,则返回该值
* @param <R> 需要返回的内容
* @return 指定类型数据
* @throws SQLException 当SQL操作出现问题时抛出
*/
@Nullable
@Contract("_,!null -> !null")
default <R> R executeFunction(@NotNull SQLFunction<@NotNull T, R> function,
@Nullable R defaultResult) throws SQLException {
try {
R result = function.apply(execute());
return result == null ? defaultResult : result;
} catch (SQLException exception) {
throw new SQLException(exception);
}
}
}
@@ -1,38 +0,0 @@
package cc.carm.lib.easysql.api.action;
import cc.carm.lib.easysql.api.SQLAction;
public interface SQLUpdateAction extends SQLAction<Integer> {
/**
* 设定自增主键的序列
*
* @param keyColumnIndex 自增主键的序列
* <br>若该值 0,则 {@link #execute()} 返回自增主键数值
* <br>若该值 ≤ 0,则 {@link #execute()} 返回变更的行数
* @return {@link SQLUpdateAction}
* @see #setReturnGeneratedKey(boolean)
*/
@Deprecated
default SQLUpdateAction setKeyIndex(int keyColumnIndex) {
return setReturnGeneratedKey(keyColumnIndex > 0);
}
/**
* 设定该操作返回自增键序列。
*
* @return {@link SQLUpdateAction}
*/
default SQLUpdateAction returnGeneratedKey() {
return setReturnGeneratedKey(true);
}
/**
* 设定该操作是否返回自增键序列。
*
* @param returnGeneratedKey 是否返回自增键序列
* @return {@link SQLUpdateAction}
*/
SQLUpdateAction setReturnGeneratedKey(boolean returnGeneratedKey);
}
@@ -1,26 +0,0 @@
package cc.carm.lib.easysql.api.action;
import cc.carm.lib.easysql.api.SQLAction;
import org.jetbrains.annotations.NotNull;
import java.util.List;
@SuppressWarnings("UnusedReturnValue")
public interface SQLUpdateBatchAction extends SQLAction<List<Integer>> {
/**
* 添加一条批量执行的SQL语句
*
* @param sql SQL语句
* @return {@link SQLUpdateBatchAction}
*/
SQLUpdateBatchAction addBatch(@NotNull String sql);
@Override
default @NotNull String getSQLContent() {
return getSQLContents().get(0);
}
List<String> getSQLContents();
}
@@ -1,35 +0,0 @@
package cc.carm.lib.easysql.api.action.query;
import org.jetbrains.annotations.Nullable;
import java.sql.PreparedStatement;
import java.util.function.Consumer;
public interface PreparedQueryAction extends QueryAction {
/**
* 设定SQL语句中所有 ? 对应的参数
*
* @param params 参数内容
* @return {@link PreparedQueryAction}
*/
PreparedQueryAction setParams(@Nullable Object... params);
/**
* 设定SQL语句中所有 ? 对应的参数
*
* @param params 参数内容
* @return {@link PreparedQueryAction}
*/
PreparedQueryAction setParams(@Nullable Iterable<Object> params);
/**
* 直接对 {@link PreparedStatement} 进行处理
*
* @param statement {@link Consumer} 处理操作
* 若为空则不进行处理
* @return {@link PreparedQueryAction}
*/
PreparedQueryAction handleStatement(@Nullable Consumer<PreparedStatement> statement);
}
@@ -0,0 +1,44 @@
package cc.carm.lib.easysql.api.action.query;
import cc.carm.lib.easysql.api.SQLQuery;
import cc.carm.lib.easysql.api.action.SQLAdvancedAction;
import cc.carm.lib.easysql.api.function.SQLHandler;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.sql.PreparedStatement;
public interface PreparedSQLQueryAction<B extends PreparedSQLQueryAction<B>> extends SQLQueryAction<B> {
interface Base extends PreparedSQLQueryAction<Base> {
}
interface Advanced extends PreparedSQLQueryAction<Advanced>, SQLAdvancedAction<SQLQuery> {
}
/**
* 设定SQL语句中所有 ? 对应的参数
*
* @param params 参数内容
* @return {@link PreparedSQLQueryAction}
*/
@NotNull B setParams(@Nullable Object... params);
/**
* 设定SQL语句中所有 ? 对应的参数
*
* @param params 参数内容
* @return {@link PreparedSQLQueryAction}
*/
@NotNull B setParams(@Nullable Iterable<Object> params);
/**
* 直接对 {@link PreparedStatement} 进行处理
*
* @param statement 通过 {@link SQLHandler} 处理操作
* 若为空则不进行处理
* @return {@link PreparedSQLQueryAction}
*/
@NotNull B handleStatement(@Nullable SQLHandler<PreparedStatement> statement);
}
@@ -1,7 +1,8 @@
package cc.carm.lib.easysql.api.action.query;
import cc.carm.lib.easysql.api.SQLAction;
import cc.carm.lib.easysql.api.SQLQuery;
import cc.carm.lib.easysql.api.action.SQLBaseAction;
import cc.carm.lib.easysql.api.action.SQLAdvancedAction;
import cc.carm.lib.easysql.api.function.SQLExceptionHandler;
import cc.carm.lib.easysql.api.function.SQLFunction;
import cc.carm.lib.easysql.api.function.SQLHandler;
@@ -19,7 +20,7 @@ import java.sql.SQLException;
* <br>同步执行方法中有会抛出异常的方法与不抛出异常的方法
* <br>若选择不抛出异常则返回值可能为空需要特殊处理</li>
*
* <li>异步执行 {@link #executeAsync(SQLHandler, SQLExceptionHandler)}
* <li>异步执行 {@link Advanced#executeAsync(SQLHandler, SQLExceptionHandler)}
* <br>异步执行时将提供成功与异常两种处理方式
* <br>可自行选择是否对数据或异常进行处理
* <br>默认的异常处理器为 {@link #defaultExceptionHandler()}</li>
@@ -30,7 +31,13 @@ import java.sql.SQLException;
* @author CarmJos
* @since 0.2.6
*/
public interface QueryAction extends SQLAction<SQLQuery> {
public interface SQLQueryAction<B extends SQLQueryAction<B>> extends SQLBaseAction<SQLQuery> {
interface Base extends SQLQueryAction<Base> {
}
interface Advanced extends SQLQueryAction<Advanced>, SQLAdvancedAction<SQLQuery> {
}
@Override
@Contract("_,!null -> !null")
@@ -39,8 +46,6 @@ public interface QueryAction extends SQLAction<SQLQuery> {
try (SQLQuery value = execute()) {
R result = function.apply(value);
return result == null ? defaultResult : result;
} catch (SQLException exception) {
throw new SQLException(exception);
}
}
@@ -0,0 +1,49 @@
package cc.carm.lib.easysql.api.action.update;
import cc.carm.lib.easysql.api.action.SQLBaseAction;
import cc.carm.lib.easysql.api.action.SQLAdvancedAction;
import java.util.List;
public interface PreparedSQLBatchUpdateAction<T extends Number, B extends PreparedSQLBatchUpdateAction<T, B>>
extends SQLBaseAction<List<T>> {
interface Base<T extends Number> extends PreparedSQLBatchUpdateAction<T, Base<T>> {
}
interface Advanced<T extends Number> extends PreparedSQLBatchUpdateAction<T, Advanced<T>>, SQLAdvancedAction<List<T>> {
}
/**
* 设定多组SQL语句中所有 ? 对应的参数
*
* @param allValues 所有参数内容
* @return {@link PreparedSQLBatchUpdateAction}
*/
B allValues(Iterable<Object[]> allValues);
/**
* 添加一组SQL语句中所有 ? 对应的参数
*
* @param values 参数内容
* @return {@link PreparedSQLBatchUpdateAction}
*/
B addValues(Object... values);
/**
* 设定该操作返回自增键序列。
*
* @return {@link PreparedSQLBatchUpdateAction}
*/
B returnGeneratedKeys();
/**
* 设定该操作返回自增键序列。
*
* @param keyTypeClass 自增序列的数字类型
* @param <N> 自增键序列类型 {@link Number}
* @return {@link PreparedSQLBatchUpdateAction}
* @since 0.4.0
*/
<N extends Number, D extends PreparedSQLBatchUpdateAction<N, D>> D returnGeneratedKeys(Class<N> keyTypeClass);
}
@@ -0,0 +1,32 @@
package cc.carm.lib.easysql.api.action.update;
import cc.carm.lib.easysql.api.action.SQLAdvancedAction;
import org.jetbrains.annotations.Nullable;
public interface PreparedSQLUpdateAction<T extends Number, B extends PreparedSQLUpdateAction<T, B>>
extends SQLUpdateAction<T, B> {
interface Base<T extends Number> extends PreparedSQLUpdateAction<T, Base<T>> {
}
interface Advanced<T extends Number> extends PreparedSQLUpdateAction<T, Advanced<T>>, SQLAdvancedAction<T> {
}
/**
* 设定SQL语句中所有 ? 对应的参数
*
* @param params 参数内容
* @return {@link PreparedSQLUpdateAction}
*/
B values(Object... params);
/**
* 设定SQL语句中所有 ? 对应的参数
*
* @param params 参数内容
* @return {@link PreparedSQLUpdateAction}
* @since 0.4.0
*/
B values(@Nullable Iterable<Object> params);
}
@@ -0,0 +1,33 @@
package cc.carm.lib.easysql.api.action.update;
import cc.carm.lib.easysql.api.action.SQLBaseAction;
import cc.carm.lib.easysql.api.action.SQLAdvancedAction;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public interface SQLBatchUpdateAction<T extends Number, B extends SQLBatchUpdateAction<T, B>> extends SQLBaseAction<T> {
interface Base<T extends Number> extends SQLBatchUpdateAction<T, Base<T>>, SQLBaseAction<T> {
}
interface Advanced<T extends Number> extends SQLBatchUpdateAction<T, Advanced<T>>, SQLAdvancedAction<T> {
}
/**
* 添加一条批量执行的SQL语句
*
* @param sql SQL语句
* @return {@link SQLBatchUpdateAction}
*/
B addBatch(@NotNull String sql);
@Override
default @NotNull String getSQLContent() {
return getSQLContents().get(0);
}
@Override
@NotNull List<String> getSQLContents();
}
@@ -0,0 +1,33 @@
package cc.carm.lib.easysql.api.action.update;
import cc.carm.lib.easysql.api.action.SQLBaseAction;
import cc.carm.lib.easysql.api.action.SQLAdvancedAction;
public interface SQLUpdateAction<T extends Number, B extends SQLUpdateAction<T, B>> extends SQLBaseAction<T> {
interface Base<T extends Number> extends SQLUpdateAction<T, Base<T>> {
}
interface Advanced<T extends Number> extends SQLUpdateAction<T, Advanced<T>>, SQLAdvancedAction<T> {
}
/**
* 设定该操作返回自增键序列。
*
* @return {@link SQLUpdateAction}
*/
B returnGeneratedKey();
/**
* 设定该操作返回自增键序列。
*
* @param keyTypeClass 自增序列的数字类型
* @param <N> 自增键序列类型 {@link Number}
* @return {@link SQLUpdateAction}
* @since 0.4.0
*/
<N extends Number, D extends SQLUpdateAction<N, D>> D returnGeneratedKey(Class<N> keyTypeClass);
}
@@ -1,21 +1,21 @@
package cc.carm.lib.easysql.api.builder;
import cc.carm.lib.easysql.api.SQLAction;
import cc.carm.lib.easysql.api.SQLBuilder;
import cc.carm.lib.easysql.api.action.SQLBaseAction;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Date;
import java.util.LinkedHashMap;
public interface ConditionalBuilder<B extends ConditionalBuilder<B, T>, T extends SQLAction<?>> extends SQLBuilder {
public interface ConditionalBuilder<B extends ConditionalBuilder<B, T>, T extends SQLBaseAction<?>> extends SQLBuilder {
/**
* 将现有条件构建完整的SQL语句用于执行。
*
* @return {@link SQLAction}
* @return {@link SQLBaseAction}
*/
T build();
@NotNull T build();
/**
* 设定限定的条目数
@@ -23,7 +23,7 @@ public interface ConditionalBuilder<B extends ConditionalBuilder<B, T>, T extend
* @param limit 条数限制
* @return {@link B}
*/
B setLimit(int limit);
@NotNull B limit(int limit);
/**
* 直接设定条件的源文本,不需要以WHERE开头。
@@ -32,7 +32,7 @@ public interface ConditionalBuilder<B extends ConditionalBuilder<B, T>, T extend
* @param condition 条件文本,不需要以WHERE开头。
* @return {@link B}
*/
B setConditions(@Nullable String condition);
@NotNull B where(@Nullable String condition);
/**
* 直接设定每个条件的文本与其对应数值,将以AND链接,且不需要以WHERE开头。
@@ -41,19 +41,17 @@ public interface ConditionalBuilder<B extends ConditionalBuilder<B, T>, T extend
* @param conditionSQLs 条件内容,将以AND链接,且不需要以WHERE开头。
* @return {@link B}
*/
B setConditions(LinkedHashMap<@NotNull String, @Nullable Object> conditionSQLs);
@NotNull B where(LinkedHashMap<@NotNull String, @Nullable Object> conditionSQLs);
B addCondition(@Nullable String condition);
@NotNull B addCondition(@Nullable String condition);
B addCondition(@NotNull String columnName, @NotNull String operator, @Nullable Object queryValue);
@NotNull B addCondition(@NotNull String columnName, @NotNull String operator, @Nullable Object queryValue);
default B addCondition(@NotNull String columnName, @Nullable Object queryValue) {
return addCondition(columnName, "=", queryValue);
}
@NotNull B addCondition(@NotNull String columnName, @Nullable Object queryValue);
B addCondition(@NotNull String[] columnNames, @Nullable Object[] queryValues);
@NotNull B addCondition(@NotNull String[] columnNames, @Nullable Object[] queryValues);
B addNotNullCondition(@NotNull String columnName);
@NotNull B addNotNullCondition(@NotNull String columnName);
/**
* 添加时间的限定条件。 若设定了开始时间,则限定条件为 {@code endMillis >= startMillis}
@@ -63,7 +61,7 @@ public interface ConditionalBuilder<B extends ConditionalBuilder<B, T>, T extend
* @param endMillis 结束时间戳,若{@code <0}则不作限定
* @return {@link B}
*/
default B addTimeCondition(@NotNull String columnName, long startMillis, long endMillis) {
default @NotNull B addTimeCondition(@NotNull String columnName, long startMillis, long endMillis) {
return addTimeCondition(columnName,
startMillis > 0 ? new Date(startMillis) : null,
endMillis > 0 ? new Date(endMillis) : null
@@ -78,7 +76,7 @@ public interface ConditionalBuilder<B extends ConditionalBuilder<B, T>, T extend
* @param endDate 结束时间,若为null则不作限定
* @return {@link B}
*/
B addTimeCondition(@NotNull String columnName, @Nullable java.util.Date startDate, @Nullable java.util.Date endDate);
@NotNull B addTimeCondition(@NotNull String columnName, @Nullable java.util.Date startDate, @Nullable java.util.Date endDate);
}
@@ -1,9 +1,11 @@
package cc.carm.lib.easysql.api.builder;
import cc.carm.lib.easysql.api.SQLAction;
import cc.carm.lib.easysql.api.action.update.PreparedSQLUpdateAction;
import org.jetbrains.annotations.NotNull;
public interface DeleteBuilder extends ConditionalBuilder<DeleteBuilder, SQLAction<Integer>> {
public interface DeleteBuilder<B extends PreparedSQLUpdateAction<Integer, B>>
extends ConditionalBuilder<DeleteBuilder<B>, B> {
String getTableName();
@NotNull String getTableName();
}
@@ -1,18 +1,18 @@
package cc.carm.lib.easysql.api.builder;
import cc.carm.lib.easysql.api.SQLAction;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.List;
public interface InsertBuilder<T extends SQLAction<?>> {
public interface InsertBuilder<T> {
String getTableName();
@NotNull String getTableName();
T setColumnNames(List<String> columnNames);
@NotNull T columns(List<String> columnNames);
default T setColumnNames(String... columnNames) {
return setColumnNames(columnNames == null ? null : Arrays.asList(columnNames));
default @NotNull T columns(String... columnNames) {
return columns(columnNames == null ? null : Arrays.asList(columnNames));
}
@@ -1,30 +1,30 @@
package cc.carm.lib.easysql.api.builder;
import cc.carm.lib.easysql.api.SQLBuilder;
import cc.carm.lib.easysql.api.action.query.PreparedQueryAction;
import cc.carm.lib.easysql.api.action.query.QueryAction;
import cc.carm.lib.easysql.api.action.query.PreparedSQLQueryAction;
import cc.carm.lib.easysql.api.action.query.SQLQueryAction;
import org.jetbrains.annotations.NotNull;
public interface QueryBuilder extends SQLBuilder {
public interface QueryBuilder<Q extends SQLQueryAction<Q>, P extends PreparedSQLQueryAction<P>> extends SQLBuilder {
/**
* 通过一条 SQL语句创建查询。
* 该方法使用 Statement 实现,请注意SQL注入风险!
*
* @param sql SQL语句
* @return {@link QueryAction}
* @return {@link SQLQueryAction}
* @deprecated 存在SQL注入风险,建议使用 {@link QueryBuilder#withPreparedSQL(String)}
*/
@Deprecated
QueryAction withSQL(@NotNull String sql);
@NotNull Q withSQL(@NotNull String sql);
/**
* 通过一条 SQL语句创建预查询
*
* @param sql SQL语句
* @return {@link PreparedQueryAction}
* @return {@link PreparedSQLQueryAction}
*/
PreparedQueryAction withPreparedSQL(@NotNull String sql);
@NotNull P withPreparedSQL(@NotNull String sql);
/**
* 创建表查询
@@ -32,6 +32,6 @@ public interface QueryBuilder extends SQLBuilder {
* @param tableName 表名
* @return {@link TableQueryBuilder}
*/
TableQueryBuilder inTable(@NotNull String tableName);
@NotNull TableQueryBuilder<P> fromTable(@NotNull String tableName);
}
@@ -1,6 +1,7 @@
package cc.carm.lib.easysql.api.builder;
import cc.carm.lib.easysql.api.SQLAction;
import cc.carm.lib.easysql.api.action.SQLBaseAction;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.List;
@@ -10,16 +11,16 @@ import java.util.List;
* <br> 执行后,将通过表中键判断该数据是否存在,若存在则用新数据替换原来的值,若不存在则会插入该数据。
* <br> 在使用REPLACE时,表与所给行列数据中必须包含唯一索引(或主键),且索引不得为空值,否则将等同于插入语句。
*
* @param <T> 最终构建出的 {@link SQLAction} 类型
* @param <T> 最终构建出的 {@link SQLBaseAction} 类型
*/
public interface ReplaceBuilder<T extends SQLAction<?>> {
public interface ReplaceBuilder<T extends SQLBaseAction<?>> {
String getTableName();
@NotNull String getTableName();
T setColumnNames(List<String> columnNames);
@NotNull T columns(List<String> columnNames);
default T setColumnNames(String... columnNames) {
return setColumnNames(columnNames == null ? null : Arrays.asList(columnNames));
default @NotNull T columns(String... columnNames) {
return columns(columnNames == null ? null : Arrays.asList(columnNames));
}
}
@@ -1,8 +1,7 @@
package cc.carm.lib.easysql.api.builder;
import cc.carm.lib.easysql.api.SQLAction;
import cc.carm.lib.easysql.api.SQLBuilder;
import cc.carm.lib.easysql.api.action.SQLUpdateAction;
import cc.carm.lib.easysql.api.action.SQLAdvancedAction;
import cc.carm.lib.easysql.api.enums.IndexType;
import cc.carm.lib.easysql.api.enums.NumberType;
import org.jetbrains.annotations.NotNull;
@@ -10,46 +9,46 @@ import org.jetbrains.annotations.Nullable;
public interface TableAlterBuilder extends SQLBuilder {
SQLAction<Integer> renameTo(@NotNull String newTableName);
@NotNull SQLAdvancedAction<Integer> renameTo(@NotNull String newTableName);
SQLAction<Integer> changeComment(@NotNull String newTableComment);
@NotNull SQLAdvancedAction<Integer> changeComment(@NotNull String newTableComment);
SQLAction<Integer> setAutoIncrementIndex(int index);
@NotNull SQLAdvancedAction<Integer> setAutoIncrementIndex(int index);
SQLAction<Integer> addIndex(@NotNull IndexType indexType, @Nullable String indexName,
@NotNull String columnName, @NotNull String... moreColumns);
@NotNull SQLAdvancedAction<Integer> addIndex(@NotNull IndexType indexType, @Nullable String indexName,
@NotNull String columnName, @NotNull String... moreColumns);
/**
* 为该表移除一个索引
*
* @param indexName 索引名
* @return {@link SQLUpdateAction}
* @return {@link SQLAdvancedAction}
*/
SQLAction<Integer> dropIndex(@NotNull String indexName);
@NotNull SQLAdvancedAction<Integer> dropIndex(@NotNull String indexName);
/**
* 为该表移除一个外键
*
* @param keySymbol 外键名
* @return {@link SQLUpdateAction}
* @return {@link SQLAdvancedAction}
*/
SQLAction<Integer> dropForeignKey(@NotNull String keySymbol);
@NotNull SQLAdvancedAction<Integer> dropForeignKey(@NotNull String keySymbol);
/**
* 为该表移除主键(须添加新主键)
*
* @return {@link SQLUpdateAction}
* @return {@link SQLAdvancedAction}
*/
SQLAction<Integer> dropPrimaryKey();
@NotNull SQLAdvancedAction<Integer> dropPrimaryKey();
/**
* 为表添加一列
*
* @param columnName 列名
* @param settings 列的相关设定
* @return {@link SQLUpdateAction}
* @return {@link SQLAdvancedAction}
*/
default SQLAction<Integer> addColumn(@NotNull String columnName, @NotNull String settings) {
default @NotNull SQLAdvancedAction<Integer> addColumn(@NotNull String columnName, @NotNull String settings) {
return addColumn(columnName, settings, null);
}
@@ -61,23 +60,27 @@ public interface TableAlterBuilder extends SQLBuilder {
* @param afterColumn 该列增添到哪个列的后面,
* <p> 该参数若省缺则放于最后一行
* <p> 若为 "" 则置于首行。
* @return {@link SQLUpdateAction}
* @return {@link SQLAdvancedAction}
*/
SQLAction<Integer> addColumn(@NotNull String columnName, @NotNull String settings, @Nullable String afterColumn);
@NotNull SQLAdvancedAction<Integer> addColumn(@NotNull String columnName,
@NotNull String settings,
@Nullable String afterColumn);
SQLAction<Integer> renameColumn(@NotNull String columnName, @NotNull String newName);
@NotNull SQLAdvancedAction<Integer> renameColumn(@NotNull String columnName, @NotNull String newName);
SQLAction<Integer> modifyColumn(@NotNull String columnName, @NotNull String settings);
@NotNull SQLAdvancedAction<Integer> modifyColumn(@NotNull String columnName, @NotNull String settings);
default SQLAction<Integer> modifyColumn(@NotNull String columnName, @NotNull String columnSettings, @NotNull String afterColumn) {
default @NotNull SQLAdvancedAction<Integer> modifyColumn(@NotNull String columnName,
@NotNull String columnSettings,
@NotNull String afterColumn) {
return modifyColumn(columnName, columnSettings + " AFTER `" + afterColumn + "`");
}
SQLAction<Integer> removeColumn(@NotNull String columnName);
@NotNull SQLAdvancedAction<Integer> removeColumn(@NotNull String columnName);
SQLAction<Integer> setColumnDefault(@NotNull String columnName, @NotNull String defaultValue);
@NotNull SQLAdvancedAction<Integer> setColumnDefault(@NotNull String columnName, @NotNull String defaultValue);
SQLAction<Integer> removeColumnDefault(@NotNull String columnName);
@NotNull SQLAdvancedAction<Integer> removeColumnDefault(@NotNull String columnName);
/**
* 为该表添加一个自增列
@@ -90,8 +93,9 @@ public interface TableAlterBuilder extends SQLBuilder {
* @param unsigned 是否采用 UNSIGNED (即无负数,可以增加自增键的最高数,建议为true)
* @return {@link TableCreateBuilder}
*/
default SQLAction<Integer> addAutoIncrementColumn(@NotNull String columnName, @Nullable NumberType numberType,
boolean primary, boolean unsigned) {
default @NotNull SQLAdvancedAction<Integer> addAutoIncrementColumn(@NotNull String columnName,
@Nullable NumberType numberType,
boolean primary, boolean unsigned) {
return addColumn(columnName,
(numberType == null ? NumberType.INT : numberType).name()
+ (unsigned ? " UNSIGNED " : " ")
@@ -109,7 +113,8 @@ public interface TableAlterBuilder extends SQLBuilder {
* @param numberType 数字类型,若省缺则为 {@link NumberType#INT}
* @return {@link TableAlterBuilder}
*/
default SQLAction<Integer> addAutoIncrementColumn(@NotNull String columnName, @NotNull NumberType numberType) {
default @NotNull SQLAdvancedAction<Integer> addAutoIncrementColumn(@NotNull String columnName,
@NotNull NumberType numberType) {
return addAutoIncrementColumn(columnName, numberType, false, true);
}
@@ -122,7 +127,7 @@ public interface TableAlterBuilder extends SQLBuilder {
* @param columnName 列名
* @return {@link TableAlterBuilder}
*/
default SQLAction<Integer> addAutoIncrementColumn(@NotNull String columnName) {
default @NotNull SQLAdvancedAction<Integer> addAutoIncrementColumn(@NotNull String columnName) {
return addAutoIncrementColumn(columnName, NumberType.INT);
}
@@ -1,7 +1,7 @@
package cc.carm.lib.easysql.api.builder;
import cc.carm.lib.easysql.api.SQLBuilder;
import cc.carm.lib.easysql.api.action.SQLUpdateAction;
import cc.carm.lib.easysql.api.action.update.SQLUpdateAction;
import cc.carm.lib.easysql.api.enums.ForeignKeyRule;
import cc.carm.lib.easysql.api.enums.IndexType;
import cc.carm.lib.easysql.api.enums.NumberType;
@@ -19,9 +19,9 @@ public interface TableCreateBuilder extends SQLBuilder {
/**
* 将现有条件构建完整的SQL语句用于执行。
*
* @return {@link SQLUpdateAction}
* @return {@link SQLUpdateAction.Advanced}
*/
SQLUpdateAction build();
@NotNull SQLUpdateAction.Advanced<Integer> build();
@NotNull String getTableName();
@@ -33,7 +33,7 @@ public interface TableCreateBuilder extends SQLBuilder {
*/
@NotNull String getTableSettings();
TableCreateBuilder setTableSettings(@NotNull String settings);
@NotNull TableCreateBuilder setTableSettings(@NotNull String settings);
/**
* 设定表的标注,一般用于解释该表的作用。
@@ -41,7 +41,7 @@ public interface TableCreateBuilder extends SQLBuilder {
* @param comment 表标注
* @return {@link TableCreateBuilder}
*/
TableCreateBuilder setTableComment(@Nullable String comment);
@NotNull TableCreateBuilder setTableComment(@Nullable String comment);
/**
* 直接设定表的所有列信息
@@ -49,7 +49,7 @@ public interface TableCreateBuilder extends SQLBuilder {
* @param columns 列的相关信息 (包括列设定)
* @return {@link TableCreateBuilder}
*/
TableCreateBuilder setColumns(@NotNull String... columns);
@NotNull TableCreateBuilder setColumns(@NotNull String... columns);
/**
* 为该表添加一个列
@@ -58,7 +58,7 @@ public interface TableCreateBuilder extends SQLBuilder {
* <br>如 `uuid` VARCHAR(36) NOT NULL UNIQUE KEY
* @return {@link TableCreateBuilder}
*/
TableCreateBuilder addColumn(@NotNull String column);
@NotNull TableCreateBuilder addColumn(@NotNull String column);
/**
* 为该表添加一个列
@@ -68,7 +68,7 @@ public interface TableCreateBuilder extends SQLBuilder {
* <br>如 VARCHAR(36) NOT NULL UNIQUE KEY
* @return {@link TableCreateBuilder}
*/
default TableCreateBuilder addColumn(@NotNull String columnName, @NotNull String settings) {
default @NotNull TableCreateBuilder addColumn(@NotNull String columnName, @NotNull String settings) {
Objects.requireNonNull(columnName, "columnName could not be null");
return addColumn(withBackQuote(columnName) + " " + settings);
}
@@ -82,7 +82,7 @@ public interface TableCreateBuilder extends SQLBuilder {
* @param comments 列的注解,用于解释该列数据的作用
* @return {@link TableCreateBuilder}
*/
default TableCreateBuilder addColumn(@NotNull String columnName, @NotNull String settings, @NotNull String comments) {
default @NotNull TableCreateBuilder addColumn(@NotNull String columnName, @NotNull String settings, @NotNull String comments) {
return addColumn(columnName, settings + " COMMENT " + withQuote(comments));
}
@@ -97,8 +97,8 @@ public interface TableCreateBuilder extends SQLBuilder {
* @param unsigned 是否采用 UNSIGNED (即无负数,可以增加自增键的最高数,建议为true)
* @return {@link TableCreateBuilder}
*/
TableCreateBuilder addAutoIncrementColumn(@NotNull String columnName, @Nullable NumberType numberType,
boolean asPrimaryKey, boolean unsigned);
@NotNull TableCreateBuilder addAutoIncrementColumn(@NotNull String columnName, @Nullable NumberType numberType,
boolean asPrimaryKey, boolean unsigned);
/**
* 为该表添加一个INT类型的自增主键列
@@ -110,8 +110,8 @@ public interface TableCreateBuilder extends SQLBuilder {
* @param unsigned 是否采用 UNSIGNED (即无负数,可以增加自增键的最高数,建议为true)
* @return {@link TableCreateBuilder}
*/
default TableCreateBuilder addAutoIncrementColumn(@NotNull String columnName,
boolean asPrimaryKey, boolean unsigned) {
default @NotNull TableCreateBuilder addAutoIncrementColumn(@NotNull String columnName,
boolean asPrimaryKey, boolean unsigned) {
return addAutoIncrementColumn(columnName, NumberType.INT, asPrimaryKey, unsigned);
}
@@ -125,7 +125,7 @@ public interface TableCreateBuilder extends SQLBuilder {
* @param asPrimaryKey 是否为主键,若为false则设定为唯一键
* @return {@link TableCreateBuilder}
*/
default TableCreateBuilder addAutoIncrementColumn(@NotNull String columnName, boolean asPrimaryKey) {
default @NotNull TableCreateBuilder addAutoIncrementColumn(@NotNull String columnName, boolean asPrimaryKey) {
return addAutoIncrementColumn(columnName, asPrimaryKey, true);
}
@@ -137,7 +137,7 @@ public interface TableCreateBuilder extends SQLBuilder {
* @param columnName 列名
* @return {@link TableCreateBuilder}
*/
default TableCreateBuilder addAutoIncrementColumn(@NotNull String columnName) {
default @NotNull TableCreateBuilder addAutoIncrementColumn(@NotNull String columnName) {
return addAutoIncrementColumn(columnName, true);
}
@@ -152,8 +152,8 @@ public interface TableCreateBuilder extends SQLBuilder {
* @param columnName 索引包含的列
* @return {@link TableCreateBuilder}
*/
default TableCreateBuilder setIndex(@NotNull String columnName,
@NotNull IndexType type) {
default @NotNull TableCreateBuilder setIndex(@NotNull String columnName,
@NotNull IndexType type) {
return setIndex(type, null, columnName);
}
@@ -170,8 +170,8 @@ public interface TableCreateBuilder extends SQLBuilder {
* @param moreColumns 联合索引需要包含的列
* @return {@link TableCreateBuilder}
*/
TableCreateBuilder setIndex(@NotNull IndexType type, @Nullable String indexName,
@NotNull String columnName, @NotNull String... moreColumns);
@NotNull TableCreateBuilder setIndex(@NotNull IndexType type, @Nullable String indexName,
@NotNull String columnName, @NotNull String... moreColumns);
/**
@@ -185,7 +185,7 @@ public interface TableCreateBuilder extends SQLBuilder {
* @param foreignColumn 外键关联表中对应的关联列,必须为目标表的主键,即 {@link IndexType#PRIMARY_KEY}
* @return {@link TableCreateBuilder}
*/
default TableCreateBuilder addForeignKey(@NotNull String tableColumn, @NotNull String foreignColumn) {
default @NotNull TableCreateBuilder addForeignKey(@NotNull String tableColumn, @NotNull String foreignColumn) {
return addForeignKey(tableColumn, getTableName(), foreignColumn);
}
@@ -203,8 +203,8 @@ public interface TableCreateBuilder extends SQLBuilder {
* <p> 2. 数据类型必须和所要建立主键的列的数据类型相同。
* @return {@link TableCreateBuilder}
*/
default TableCreateBuilder addForeignKey(@NotNull String tableColumn,
@NotNull String foreignTable, @NotNull String foreignColumn) {
default @NotNull TableCreateBuilder addForeignKey(@NotNull String tableColumn,
@NotNull String foreignTable, @NotNull String foreignColumn) {
return addForeignKey(tableColumn, null, foreignTable, foreignColumn);
}
@@ -223,8 +223,8 @@ public interface TableCreateBuilder extends SQLBuilder {
* <p> 2. 数据类型必须和所要建立主键的列的数据类型相同。
* @return {@link TableCreateBuilder}
*/
default TableCreateBuilder addForeignKey(@NotNull String tableColumn, @Nullable String constraintName,
@NotNull String foreignTable, @NotNull String foreignColumn) {
default @NotNull TableCreateBuilder addForeignKey(@NotNull String tableColumn, @Nullable String constraintName,
@NotNull String foreignTable, @NotNull String foreignColumn) {
return addForeignKey(tableColumn, constraintName, foreignTable, foreignColumn, null, null);
}
@@ -245,9 +245,9 @@ public interface TableCreateBuilder extends SQLBuilder {
* @param deleteRule 在外键被删除时采用的规则,缺省时默认为{@link ForeignKeyRule#RESTRICT}
* @return {@link TableCreateBuilder}
*/
TableCreateBuilder addForeignKey(@NotNull String tableColumn, @Nullable String constraintName,
@NotNull String foreignTable, @NotNull String foreignColumn,
@Nullable ForeignKeyRule updateRule, @Nullable ForeignKeyRule deleteRule);
@NotNull TableCreateBuilder addForeignKey(@NotNull String tableColumn, @Nullable String constraintName,
@NotNull String foreignTable, @NotNull String foreignColumn,
@Nullable ForeignKeyRule updateRule, @Nullable ForeignKeyRule deleteRule);
default String defaultTablesSettings() {
return "ENGINE=InnoDB DEFAULT CHARSET=utf8";
@@ -0,0 +1,56 @@
package cc.carm.lib.easysql.api.builder;
import cc.carm.lib.easysql.api.SQLBuilder;
import cc.carm.lib.easysql.api.function.SQLFunction;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.Unmodifiable;
import java.sql.ResultSet;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
public interface TableMetadataBuilder extends SQLBuilder {
/**
* @return 本表是否存在
*/
CompletableFuture<Boolean> validateExist();
/**
* 对表内的数据列元数据进行读取
*
* @param columnPattern 列的名称匹配表达式, 为空则匹配所有列
* @param reader 读取的方法
* @param <R> 结果类型
* @return 读取结果
*/
<R> CompletableFuture<R> fetchColumns(@Nullable String columnPattern,
@NotNull SQLFunction<ResultSet, R> reader);
/**
* @param columnPattern 需要判断的列名表达式
* @return 对应列是否存在
*/
CompletableFuture<Boolean> isColumnExists(@NotNull String columnPattern);
/**
* 列出所有表内的全部列。
*
* @return 表内全部数据列的列名
*/
default CompletableFuture<@Unmodifiable Set<String>> listColumns() {
return listColumns(null);
}
/**
* 列出所有满足表达式的列。
*
* @param columnPattern 列名表达式,为空则列出全部
* @return 所有满足表达式的列名
*/
CompletableFuture<@Unmodifiable Set<String>> listColumns(@Nullable String columnPattern);
// More coming soon.
}
@@ -1,9 +1,10 @@
package cc.carm.lib.easysql.api.builder;
import cc.carm.lib.easysql.api.action.query.PreparedQueryAction;
import cc.carm.lib.easysql.api.action.query.PreparedSQLQueryAction;
import org.jetbrains.annotations.NotNull;
public interface TableQueryBuilder extends ConditionalBuilder<TableQueryBuilder, PreparedQueryAction> {
public interface TableQueryBuilder<B extends PreparedSQLQueryAction<B>>
extends ConditionalBuilder<TableQueryBuilder<B>, B> {
@NotNull String getTableName();
@@ -13,7 +14,7 @@ public interface TableQueryBuilder extends ConditionalBuilder<TableQueryBuilder,
* @param columnNames 列名
* @return {@link TableQueryBuilder}
*/
TableQueryBuilder selectColumns(@NotNull String... columnNames);
TableQueryBuilder<B> select(@NotNull String... columnNames);
/**
* 对结果进行排序
@@ -22,7 +23,7 @@ public interface TableQueryBuilder extends ConditionalBuilder<TableQueryBuilder,
* @param asc 是否为正序排序 (为false则倒序排序)
* @return {@link TableQueryBuilder}
*/
TableQueryBuilder orderBy(@NotNull String columnName, boolean asc);
TableQueryBuilder<B> orderBy(@NotNull String columnName, boolean asc);
/**
* 限制查询条数,用于分页查询。
@@ -32,6 +33,6 @@ public interface TableQueryBuilder extends ConditionalBuilder<TableQueryBuilder,
* @return {@link TableQueryBuilder}
* @since 0.2.6
*/
TableQueryBuilder setPageLimit(int start, int end);
TableQueryBuilder<B> limit(int start, int end);
}
@@ -1,12 +1,13 @@
package cc.carm.lib.easysql.api.builder;
import cc.carm.lib.easysql.api.SQLAction;
import cc.carm.lib.easysql.api.action.update.PreparedSQLUpdateAction;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.LinkedHashMap;
public interface UpdateBuilder extends ConditionalBuilder<UpdateBuilder, SQLAction<Integer>> {
public interface UpdateBuilder<B extends PreparedSQLUpdateAction<Integer, B>>
extends ConditionalBuilder<UpdateBuilder<B>, B> {
String getTableName();
@@ -18,7 +19,7 @@ public interface UpdateBuilder extends ConditionalBuilder<UpdateBuilder, SQLActi
* @return {@link UpdateBuilder}
* @since 0.3.7
*/
UpdateBuilder addColumnValue(@NotNull String columnName, @Nullable Object columnValue);
UpdateBuilder<B> set(@NotNull String columnName, @Nullable Object columnValue);
/**
* 设定更新的全部字段值 <b>(此操作会覆盖之前的设定)</b>
@@ -27,7 +28,7 @@ public interface UpdateBuilder extends ConditionalBuilder<UpdateBuilder, SQLActi
* @param columnData 字段名和值的键值对
* @return {@link UpdateBuilder}
*/
UpdateBuilder setColumnValues(LinkedHashMap<@NotNull String, @Nullable Object> columnData);
UpdateBuilder<B> setAll(LinkedHashMap<@NotNull String, @Nullable Object> columnData);
/**
* 设定更新的全部字段值 <b>(此操作会覆盖之前的设定)</b>
@@ -37,20 +38,19 @@ public interface UpdateBuilder extends ConditionalBuilder<UpdateBuilder, SQLActi
* @param columnValues 字段名对应的值
* @return {@link UpdateBuilder}
*/
UpdateBuilder setColumnValues(@NotNull String[] columnNames, @Nullable Object[] columnValues);
UpdateBuilder<B> setAll(@NotNull String[] columnNames, @Nullable Object[] columnValues);
/**
* 设定更新的全部字段值 <b>(此操作会覆盖之前的设定)</b>
* <p> 如需同时更新多条字段,请使用 {@link #setColumnValues(String[], Object[])} 或 {@link #setColumnValues(LinkedHashMap)}
* <br>也可以使用 {@link #addColumnValue(String, Object)} 一条条的添加字段
* <p> 如需同时更新多条字段,请使用 {@link #setAll(String[], Object[])} 或 {@link #setAll(LinkedHashMap)}
* <br>也可以使用 {@link #set(String, Object)} 一条条的添加字段
*
* @param columnName 字段名
* @param columnValue 字段名对应的值
* @return {@link UpdateBuilder}
*/
default UpdateBuilder setColumnValues(@NotNull String columnName, @Nullable Object columnValue) {
return setColumnValues(new String[]{columnName}, new Object[]{columnValue});
default UpdateBuilder<B> setAll(@NotNull String columnName, @Nullable Object columnValue) {
return setAll(new String[]{columnName}, new Object[]{columnValue});
}
}
@@ -1,17 +0,0 @@
package cc.carm.lib.easysql.api.builder;
/**
* 存在则更新,不存在则插入。
*
* @see ReplaceBuilder
*/
@Deprecated
public interface UpsertBuilder {
String getTableName();
default UpsertBuilder setColumnNames(String[] columnNames, String updateColumn) {
throw new UnsupportedOperationException("Please use REPLACE .");
}
}
@@ -0,0 +1,39 @@
package cc.carm.lib.easysql.api.enums;
import java.sql.Connection;
/**
* 事务隔离级别。
* 部分Javadoc来自文章 <a href="https://cloud.tencent.com/developer/article/1865041">《理解事务的4种隔离级别》</a> 。
*/
public enum IsolationLevel {
/**
* 读未提交。即一个事务可以读取另一个未提交事务的数据。
*/
READ_UNCOMMITTED(Connection.TRANSACTION_READ_UNCOMMITTED),
/**
* 读提交。即一个事务要等另一个事务提交后才能读取数据。
*/
READ_COMMITTED(Connection.TRANSACTION_READ_COMMITTED),
/**
* 重复读。即在开始读取数据(事务开启)时,不再允许修改操作。
*/
REPEATED_READ(Connection.TRANSACTION_REPEATABLE_READ),
/**
* 序列化读取。此为最高隔离等级。在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。
* <br>注意: 这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。
*/
SERIALIZABLE(Connection.TRANSACTION_SERIALIZABLE);
private int id;
IsolationLevel(int id) {
this.id = id;
}
public int getID() {
return id;
}
}
@@ -0,0 +1,24 @@
package cc.carm.lib.easysql.api.function;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.sql.SQLException;
import java.util.Objects;
@FunctionalInterface
public interface SQLBiFunction<T, U, R> {
@Nullable
R apply(@NotNull T t, @NotNull U u) throws SQLException;
default <V> SQLBiFunction<T, U, V> then(@NotNull SQLFunction<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t, U u) -> {
R r = apply(t, u);
if (r == null) return null;
else return after.apply(r);
};
}
}
@@ -0,0 +1,100 @@
package cc.carm.lib.easysql.api.function;
import cc.carm.lib.easysql.api.SQLQuery;
import cc.carm.lib.easysql.api.action.SQLBaseAction;
import cc.carm.lib.easysql.api.action.base.PreparedBatchUpdateAction;
import cc.carm.lib.easysql.api.action.base.PreparedUpdateAction;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* 异常处理器。
* <br> 在使用 {@link SQLBaseAction#execute(SQLExceptionHandler)} 等相关方法时,
* 如果发生异常,则会调用错误处理器进行错误内容的输出提示。
*/
public interface SQLDebugHandler {
/**
* 该方法将在 {@link SQLBaseAction#execute()} 执行前调用。
*
* @param action {@link SQLBaseAction} 对象
* @param params 执行传入的参数列表。
* 实际上,仅有 {@link PreparedUpdateAction} 和 {@link PreparedBatchUpdateAction} 才会有传入参数。
*/
void beforeExecute(@NotNull SQLBaseAction<?> action, @NotNull List<@Nullable Object[]> params);
/**
* 该方法将在 {@link SQLQuery#close()} 执行后调用。
*
* @param query {@link SQLQuery} 对象
* @param executeNanoTime 该次查询开始执行的时间 (单位:纳秒)
* @param closeNanoTime 该次查询彻底关闭的时间 (单位:纳秒)
*/
void afterQuery(@NotNull SQLQuery query, long executeNanoTime, long closeNanoTime);
default String parseParams(@Nullable Object[] params) {
if (params == null) return "<#NULL>";
else if (params.length == 0) return "<#EMPTY>";
List<String> paramsString = new ArrayList<>();
for (Object param : params) {
if (param == null) paramsString.add("NULL");
else paramsString.add(param.toString());
}
return String.join(", ", paramsString);
}
@SuppressWarnings("DuplicatedCode")
static SQLDebugHandler defaultHandler(Logger logger) {
return new SQLDebugHandler() {
@Override
public void beforeExecute(@NotNull SQLBaseAction<?> action, @NotNull List<@Nullable Object[]> params) {
logger.info("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
logger.info("┣# 操作编号: {}", action.getActionUUID());
logger.info("┣# 操作类型: {}", action.getClass().getSimpleName());
if (action.getSQLContents().size() == 1) {
logger.info("┣# SQL语句: {}", action.getSQLContents().get(0));
} else {
logger.info("┣# SQL语句: ");
int i = 0;
for (String sqlContent : action.getSQLContents()) {
logger.info("┃ - [{}] {}", ++i, sqlContent);
}
}
if (params.size() == 1) {
Object[] param = params.get(0);
if (param != null) {
logger.info("┣# SQL参数: {}", parseParams(param));
}
} else if (params.size() > 1) {
logger.info("┣# SQL参数: ");
int i = 0;
for (Object[] param : params) {
logger.info("┃ - [{}] {}", ++i, parseParams(param));
}
}
logger.info("┣# 创建时间: {}", action.getCreateTime(TimeUnit.MILLISECONDS));
logger.info("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
}
@Override
public void afterQuery(@NotNull SQLQuery query, long executeNanoTime, long closeNanoTime) {
logger.info("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
logger.info("┣# 操作编号: {}", query.getAction().getActionUUID());
logger.info("┣# SQL语句: {}", query.getSQLContent());
logger.info("┣# 关闭时间: {} (cost {} ms)",
TimeUnit.NANOSECONDS.toMillis(closeNanoTime),
((double) (closeNanoTime - executeNanoTime) / 1000000)
);
logger.info("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
}
};
}
}
@@ -1,19 +1,19 @@
package cc.carm.lib.easysql.api.function;
import cc.carm.lib.easysql.api.SQLAction;
import cc.carm.lib.easysql.api.action.SQLUpdateBatchAction;
import cc.carm.lib.easysql.api.action.SQLAdvancedAction;
import cc.carm.lib.easysql.api.action.SQLBaseAction;
import org.slf4j.Logger;
import java.sql.SQLException;
import java.util.function.BiConsumer;
import java.util.logging.Logger;
/**
* 异常处理器。
* <br> 在使用 {@link SQLAction#execute(SQLExceptionHandler)} 等相关方法时,
* <br> 在使用 {@link SQLAdvancedAction#execute(SQLExceptionHandler)} 等相关方法时,
* 如果发生异常,则会调用错误处理器进行错误内容的输出提示。
*/
@FunctionalInterface
public interface SQLExceptionHandler extends BiConsumer<SQLException, SQLAction<?>> {
public interface SQLExceptionHandler extends BiConsumer<SQLException, SQLBaseAction<?>> {
/**
* 默认的异常处理器,将详细的输出相关错误与错误来源。
@@ -23,15 +23,11 @@ public interface SQLExceptionHandler extends BiConsumer<SQLException, SQLAction<
*/
static SQLExceptionHandler detailed(Logger logger) {
return (exception, sqlAction) -> {
if (sqlAction instanceof SQLUpdateBatchAction) {
logger.severe("Error when execute SQLs : ");
int i = 1;
for (String content : ((SQLUpdateBatchAction) sqlAction).getSQLContents()) {
logger.severe(String.format("#%d {%s}", i, content));
i++;
}
} else {
logger.severe("Error when execute { " + sqlAction.getSQLContent() + " }");
logger.error("Error occurred while executing SQL: ");
int i = 1;
for (String content : sqlAction.getSQLContents()) {
logger.error(String.format("#%d {%s}", i, content));
i++;
}
exception.printStackTrace();
};
@@ -43,6 +39,7 @@ public interface SQLExceptionHandler extends BiConsumer<SQLException, SQLAction<
*
* @return 无输出的处理器。
*/
@Deprecated
static SQLExceptionHandler silent() {
return (exception, sqlAction) -> {
};
@@ -4,6 +4,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.sql.SQLException;
import java.util.Objects;
@FunctionalInterface
public interface SQLFunction<T, R> {
@@ -11,4 +12,23 @@ public interface SQLFunction<T, R> {
@Nullable
R apply(@NotNull T t) throws SQLException;
default <V> SQLFunction<V, R> compose(@NotNull SQLFunction<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> {
T t = before.apply(v);
if (t == null) return null;
else return apply(t);
};
}
default <V> SQLFunction<T, V> then(@NotNull SQLFunction<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> {
R r = apply(t);
if (r == null) return null;
else return after.apply(r);
};
}
}
@@ -0,0 +1,7 @@
package cc.carm.lib.easysql.api.model;
public class SQLCondition {
}
@@ -0,0 +1,24 @@
package cc.carm.lib.easysql.api.model;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class TableColumn {
@NotNull String name;
@NotNull String type;
boolean notNull;
boolean primaryKey;
boolean uniqueKey;
boolean autoIncrement;
@Nullable String defaultValue;
@Nullable String onUpdate;
@Nullable String comment;
}
@@ -0,0 +1,49 @@
package cc.carm.lib.easysql.api.table;
import cc.carm.lib.easysql.api.SQLManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.sql.SQLException;
public abstract class NamedSQLTable implements SQLTable {
private final @NotNull String tableName;
protected @Nullable String tablePrefix;
protected @Nullable SQLManager manager;
/**
* 请调用 {@link SQLTable} 下的静态方法进行对象的初始化。
*
* @param tableName 该表的名称
*/
public NamedSQLTable(@NotNull String tableName) {
this.tableName = tableName;
}
public @NotNull String getTableName() {
return (tablePrefix != null ? tablePrefix : "") + tableName;
}
@Override
public @Nullable SQLManager getSQLManager() {
return this.manager;
}
/**
* 使用指定 SQLManager 进行本示例的初始化。
*
* @param sqlManager {@link SQLManager}
* @param tablePrefix 表名前缀
* @return 本表是否为首次创建
* @throws SQLException 出现任何错误时抛出
*/
public abstract boolean create(@NotNull SQLManager sqlManager, @Nullable String tablePrefix) throws SQLException;
public boolean create(@NotNull SQLManager sqlManager) throws SQLException {
return create(sqlManager, null);
}
}
@@ -0,0 +1,149 @@
package cc.carm.lib.easysql.api.table;
import cc.carm.lib.easysql.api.SQLManager;
import cc.carm.lib.easysql.api.action.update.PreparedSQLBatchUpdateAction;
import cc.carm.lib.easysql.api.action.update.PreparedSQLUpdateAction;
import cc.carm.lib.easysql.api.builder.*;
import cc.carm.lib.easysql.api.function.SQLHandler;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.sql.SQLException;
import java.util.Optional;
/**
* SQLTable 基于 {@link TableCreateBuilder} 构建表,用于快速创建与该表相关的操作。
* <ul>
* <li>1. 调用 {@link NamedSQLTable#of(String, String[])} 方法创建一个 SQLTable 对象;</li>
* <li>2. 在应用初始化阶段调用 {@link NamedSQLTable#create(SQLManager)} 方法初始化 SQLTable 对象;</li>
* <li>3. 获取已创建的{@link NamedSQLTable} 实例,直接调用对应方法进行关于表的相关操作。</li>
* </ul>
*
* @author CarmJos
* @since 0.3.10
*/
public interface SQLTable {
static @NotNull NamedSQLTable of(@NotNull String tableName, @Nullable SQLHandler<TableCreateBuilder> table) {
return new NamedSQLTable(tableName) {
@Override
public boolean create(@NotNull SQLManager sqlManager, String tablePrefix) throws SQLException {
if (this.manager == null) this.manager = sqlManager;
this.tablePrefix = tablePrefix;
TableCreateBuilder tableBuilder = sqlManager.createTable(getTableName());
if (table != null) table.accept(tableBuilder);
return tableBuilder.build().executeFunction(l -> l > 0, false);
}
};
}
static @NotNull NamedSQLTable of(@NotNull String tableName, @NotNull String[] columns) {
return of(tableName, columns, null);
}
static @NotNull NamedSQLTable of(@NotNull String tableName,
@NotNull String[] columns, @Nullable String tableSettings) {
return of(tableName, builder -> {
builder.setColumns(columns);
if (tableSettings != null) builder.setTableSettings(tableSettings);
});
}
/**
* 以指定的 {@link SQLManager} 实例初始化并创建该表
*
* @param sqlManager {@link SQLManager} 实例
* @return 是否新创建了本表 (若已创建或创建失败则返回false)
* @throws SQLException 当数据库返回异常时抛出
*/
boolean create(SQLManager sqlManager) throws SQLException;
/**
* 得到 {@link #create(SQLManager)} 用于初始化本实例的 {@link SQLManager} 实例
*
* @return {@link SQLManager} 实例
*/
@Nullable SQLManager getSQLManager();
/**
* 得到本表表名,不得为空。
*
* @return 本表表名
*/
@NotNull String getTableName();
default @NotNull TableQueryBuilder createQuery() {
return Optional.ofNullable(getSQLManager()).map(this::createQuery)
.orElseThrow(() -> new NullPointerException("This table doesn't have a SQLManger."));
}
default @NotNull TableQueryBuilder createQuery(@NotNull SQLManager sqlManager) {
return sqlManager.createQuery().fromTable(getTableName());
}
default @NotNull DeleteBuilder createDelete() {
return Optional.ofNullable(getSQLManager()).map(this::createDelete)
.orElseThrow(() -> new NullPointerException("This table doesn't have a SQLManger."));
}
default @NotNull DeleteBuilder createDelete(@NotNull SQLManager sqlManager) {
return sqlManager.deleteFrom(getTableName());
}
default @NotNull UpdateBuilder createUpdate() {
return Optional.ofNullable(getSQLManager()).map(this::createUpdate)
.orElseThrow(() -> new NullPointerException("This table doesn't have a SQLManger."));
}
default @NotNull UpdateBuilder createUpdate(@NotNull SQLManager sqlManager) {
return sqlManager.updateInto(getTableName());
}
default @NotNull InsertBuilder<PreparedSQLUpdateAction.Advanced<Integer>> createInsert() {
return Optional.ofNullable(getSQLManager()).map(this::createInsert)
.orElseThrow(() -> new NullPointerException("This table doesn't have a SQLManger."));
}
default @NotNull InsertBuilder<PreparedSQLUpdateAction.Advanced<Integer>> createInsert(@NotNull SQLManager sqlManager) {
return sqlManager.insertInto(getTableName());
}
default @NotNull InsertBuilder<PreparedSQLBatchUpdateAction.Advanced<Integer>> createInsertBatch() {
return Optional.ofNullable(getSQLManager()).map(this::createInsertBatch)
.orElseThrow(() -> new NullPointerException("This table doesn't have a SQLManger."));
}
default @NotNull InsertBuilder<PreparedSQLBatchUpdateAction.Advanced<Integer>> createInsertBatch(@NotNull SQLManager sqlManager) {
return sqlManager.insertBatchInto(getTableName());
}
default @NotNull ReplaceBuilder<PreparedSQLUpdateAction.Advanced<Integer>> createReplace() {
return Optional.ofNullable(getSQLManager()).map(this::createReplace)
.orElseThrow(() -> new NullPointerException("This table doesn't have a SQLManger."));
}
default @NotNull ReplaceBuilder<PreparedSQLUpdateAction.Advanced<Integer>> createReplace(@NotNull SQLManager sqlManager) {
return sqlManager.replaceInto(getTableName());
}
default @NotNull ReplaceBuilder<PreparedSQLBatchUpdateAction.Advanced<Integer>> createReplaceBatch() {
return Optional.ofNullable(getSQLManager()).map(this::createReplaceBatch)
.orElseThrow(() -> new NullPointerException("This table doesn't have a SQLManger."));
}
default @NotNull ReplaceBuilder<PreparedSQLBatchUpdateAction.Advanced<Integer>> createReplaceBatch(@NotNull SQLManager sqlManager) {
return sqlManager.replaceBatchInto(getTableName());
}
default @NotNull TableAlterBuilder alter() {
return Optional.ofNullable(getSQLManager()).map(this::alter)
.orElseThrow(() -> new NullPointerException("This table doesn't have a SQLManger."));
}
default @NotNull TableAlterBuilder alter(@NotNull SQLManager sqlManager) {
return sqlManager.alterTable(getTableName());
}
}
@@ -0,0 +1,15 @@
package cc.carm.lib.easysql.api.transaction;
import org.jetbrains.annotations.NotNull;
public interface SQLSavepoint {
int getID();
@NotNull String getName();
void release();
boolean isReleased();
}
@@ -0,0 +1,159 @@
package cc.carm.lib.easysql.api.transaction;
import cc.carm.lib.easysql.api.SQLManager;
import cc.carm.lib.easysql.api.action.query.PreparedSQLQueryAction;
import cc.carm.lib.easysql.api.action.query.SQLQueryAction;
import cc.carm.lib.easysql.api.action.update.PreparedSQLBatchUpdateAction;
import cc.carm.lib.easysql.api.action.update.PreparedSQLUpdateAction;
import cc.carm.lib.easysql.api.action.update.SQLBatchUpdateAction;
import cc.carm.lib.easysql.api.action.update.SQLUpdateAction;
import cc.carm.lib.easysql.api.builder.*;
import cc.carm.lib.easysql.api.enums.IsolationLevel;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public interface SQLTransaction extends AutoCloseable {
@NotNull SQLManager getManager();
/**
* 得到本次事务的隔离级别
*
* @return {@link IsolationLevel} 隔离级别
*/
@NotNull IsolationLevel getIsolationLevel();
/**
* 提交已有操作
*/
void commit();
/**
* 设定一个记录点
*
* @param name 记录点名称
* @return {@link SQLSavepoint} 事务记录点
*/
@NotNull SQLSavepoint savepoint(@NotNull String name);
/**
* 回退全部操作
*/
default void rollback() {
rollback(null);
}
/**
* 回退操作到某个记录点或回退整个事务操作。
*
* @param savepoint 记录点,若记录点为NULL则回退整个事务的操作。
*/
void rollback(@Nullable SQLSavepoint savepoint);
/**
* 执行一条不需要返回结果的SQL语句(多用于UPDATE、REPLACE、DELETE方法)
* 该方法使用 Statement 实现,请注意SQL注入风险!
*
* @param sql SQL语句内容
* @return 更新的行数
* @see SQLUpdateAction
*/
@Nullable Integer executeSQL(String sql);
/**
* 执行一条不需要返回结果的预处理SQL更改(UPDATE、REPLACE、DELETE)
*
* @param sql SQL语句内容
* @param params SQL语句中 ? 的对应参数
* @return 更新的行数
* @see PreparedSQLUpdateAction
*/
@Nullable Integer executeSQL(String sql, Object[] params);
/**
* 执行多条不需要返回结果的SQL更改(UPDATE、REPLACE、DELETE)
*
* @param sql SQL语句内容
* @param paramsBatch SQL语句中对应?的参数组
* @return 对应参数返回的行数
* @see PreparedSQLBatchUpdateAction
*/
@Nullable List<Integer> executeSQLBatch(String sql, Iterable<Object[]> paramsBatch);
/**
* 执行多条不需要返回结果的SQL。
* 该方法使用 Statement 实现,请注意SQL注入风险!
*
* @param sql SQL语句内容
* @param moreSQL 更多SQL语句内容
* @return 对应参数返回的行数
* @see SQLBatchUpdateAction
*/
@Nullable List<Integer> executeSQLBatch(@NotNull String sql, String... moreSQL);
/**
* 执行多条不需要返回结果的SQL。
*
* @param sqlBatch SQL语句内容
* @return 对应参数返回的行数
*/
@Nullable List<Integer> executeSQLBatch(@NotNull Iterable<String> sqlBatch);
/**
* 新建一个查询。
*
* @return {@link QueryBuilder}
*/
@NotNull QueryBuilder<SQLQueryAction.Base, PreparedSQLQueryAction.Base> createQuery();
/**
* 创建一条插入操作。
*
* @param tableName 目标表名
* @return {@link InsertBuilder}
*/
@NotNull InsertBuilder<PreparedSQLUpdateAction.Base<Integer>> insertInto(@NotNull String tableName);
/**
* 创建支持多组数据的插入操作。
*
* @param tableName 目标表名
* @return {@link InsertBuilder}
*/
@NotNull InsertBuilder<PreparedSQLBatchUpdateAction.Base<Integer>> insertBatchInto(@NotNull String tableName);
/**
* 创建一条替换操作。
*
* @param tableName 目标表名
* @return {@link ReplaceBuilder}
*/
@NotNull ReplaceBuilder<PreparedSQLUpdateAction.Base<Integer>> replaceInto(@NotNull String tableName);
/**
* 创建支持多组数据的替换操作。
*
* @param tableName 目标表名
* @return {@link ReplaceBuilder}
*/
@NotNull ReplaceBuilder<PreparedSQLBatchUpdateAction.Base<Integer>> replaceBatchInto(@NotNull String tableName);
/**
* 创建更新操作。
*
* @param tableName 目标表名
* @return {@link UpdateBuilder}
*/
@NotNull UpdateBuilder<PreparedSQLUpdateAction.Base<Integer>> updateInto(@NotNull String tableName);
/**
* 创建删除操作。
*
* @param tableName 目标表名
* @return {@link DeleteBuilder}
*/
@NotNull DeleteBuilder<PreparedSQLUpdateAction.Base<Integer>> deleteFrom(@NotNull String tableName);
}
@@ -0,0 +1,15 @@
package cc.carm.lib.easysql.api.transaction;
import cc.carm.lib.easysql.api.SQLSource;
import cc.carm.lib.easysql.api.action.SQLBaseAction;
import org.jetbrains.annotations.NotNull;
public interface TransactionAction<T> extends SQLBaseAction<T> {
@NotNull SQLTransaction getTransaction();
default @NotNull SQLSource getSource() {
return getTransaction().getManager();
}
}
@@ -1,9 +1,22 @@
package cc.carm.lib.easysql.api.util;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class UUIDUtil {
private static final Pattern COMPILE = Pattern.compile("-", Pattern.LITERAL);
public static UUID random() {
return UUID.randomUUID();
}
public static String toString(UUID uuid, boolean withDash) {
if (withDash) return uuid.toString();
else return COMPILE.matcher(uuid.toString()).replaceAll(Matcher.quoteReplacement(""));
}
public static UUID toUUID(String s) {
if (s.length() == 36) {
return UUID.fromString(s);
+29 -7
View File
@@ -5,18 +5,19 @@
<parent>
<artifactId>easysql-parent</artifactId>
<groupId>cc.carm.lib</groupId>
<version>0.3.9</version>
<relativePath>../../pom.xml</relativePath>
<version>0.4.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<properties>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<maven.compiler.source>${jdk.version}</maven.compiler.source>
<maven.compiler.target>${jdk.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<maven.javadoc.skip>true</maven.javadoc.skip>
<maven.deploy.skip>true</maven.deploy.skip>
<log4j.version>2.19.0</log4j.version>
</properties>
<artifactId>easysql-demo</artifactId>
@@ -69,15 +70,31 @@
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>4.0.3</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.1.210</version>
<scope>test</scope>
<version>2.1.214</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>${log4j.version}</version>
</dependency>
</dependencies>
@@ -92,6 +109,11 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
+51
View File
@@ -0,0 +1,51 @@
import cc.carm.lib.easysql.api.table.SQLTable;
import cc.carm.lib.easysql.api.enums.IndexType;
import cc.carm.lib.easysql.api.enums.NumberType;
import cc.carm.lib.easysql.api.table.NamedSQLTable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.sql.SQLException;
public enum DataTables1 {
DATA(SQLTable.of("data", (table) -> {
table.addAutoIncrementColumn("id", true);
table.addColumn("user", "INT UNSIGNED NOT NULL");
table.addColumn("content", "TEXT NOT NULL");
table.addColumn("time", "DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP");
})),
USER(SQLTable.of("user", (table) -> {
table.addAutoIncrementColumn("id", NumberType.INT, true, true);
table.addColumn("uuid", "VARCHAR(32) NOT NULL UNIQUE KEY");
table.addColumn("username", "VARCHAR(16) NOT NULL");
table.addColumn("age", "TINYINT NOT NULL DEFAULT 1");
table.addColumn("email", "VARCHAR(32)");
table.addColumn("phone", "VARCHAR(16)");
table.addColumn("registerTime", "DATETIME NOT NULL");
table.setIndex("username", IndexType.UNIQUE_KEY); // 添加唯一索引
table.setIndex(IndexType.INDEX, "contact", "email", "phone"); //添加联合索引 (示例)
}));
private final NamedSQLTable table;
DataTables1(NamedSQLTable table) {
this.table = table;
}
public NamedSQLTable get() {
return this.table;
}
public static void initialize(@NotNull SQLManager manager, @Nullable String tablePrefix) {
for (DataTables1 value : values()) {
try {
value.get().create(manager, tablePrefix);
} catch (SQLException e) {
// 提示异常
}
}
}
}
+68
View File
@@ -0,0 +1,68 @@
import cc.carm.lib.easysql.api.table.SQLTable;
import cc.carm.lib.easysql.api.builder.TableCreateBuilder;
import cc.carm.lib.easysql.api.enums.IndexType;
import cc.carm.lib.easysql.api.enums.NumberType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.sql.SQLException;
import java.util.function.Consumer;
public enum DataTables2 implements SQLTable {
USER((table) -> {
table.addAutoIncrementColumn("id", NumberType.INT, true, true);
table.addColumn("uuid", "VARCHAR(32) NOT NULL UNIQUE KEY");
table.addColumn("username", "VARCHAR(16) NOT NULL");
table.addColumn("age", "TINYINT NOT NULL DEFAULT 1");
table.addColumn("email", "VARCHAR(32)");
table.addColumn("phone", "VARCHAR(16)");
table.addColumn("registerTime", "DATETIME NOT NULL");
table.setIndex("username", IndexType.UNIQUE_KEY); // 添加唯一索引
table.setIndex(IndexType.INDEX, "contact", "email", "phone"); //添加联合索引 (示例)
});
private final Consumer<TableCreateBuilder> builder;
private @Nullable String tablePrefix;
private @Nullable SQLManager manager;
DataTables2(Consumer<TableCreateBuilder> builder) {
this.builder = builder;
}
@Override
public @Nullable SQLManager getSQLManager() {
return this.manager;
}
@Override
public @NotNull String getTableName() {
// 这里直接选择用枚举的名称作为table的主名称
return (tablePrefix != null ? tablePrefix : "") + name().toLowerCase();
}
@Override
public boolean create(SQLManager sqlManager) throws SQLException {
return create(sqlManager, null);
}
public boolean create(@NotNull SQLManager sqlManager, @Nullable String tablePrefix) throws SQLException {
if (this.manager == null) this.manager = sqlManager;
this.tablePrefix = tablePrefix;
TableCreateBuilder tableBuilder = sqlManager.createTable(getTableName());
if (builder != null) builder.accept(tableBuilder);
return tableBuilder.build().executeFunction(l -> l > 0, false);
}
public static void initialize(@NotNull SQLManager manager, @Nullable String tablePrefix) {
for (DataTables2 value : values()) {
try {
value.create(manager, tablePrefix);
} catch (SQLException e) {
// 提示异常
}
}
}
}
@@ -1,5 +1,6 @@
import cc.carm.lib.easysql.api.SQLManager;
import cc.carm.lib.easysql.api.SQLQuery;
import cc.carm.lib.easysql.api.table.SQLTable;
import cc.carm.lib.easysql.api.enums.ForeignKeyRule;
import cc.carm.lib.easysql.api.enums.IndexType;
import cc.carm.lib.easysql.api.enums.NumberType;
@@ -7,9 +8,11 @@ import cc.carm.lib.easysql.api.util.TimeDateUtils;
import cc.carm.lib.easysql.api.util.UUIDUtil;
import org.jetbrains.annotations.TestOnly;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
@TestOnly
@SuppressWarnings("all")
@@ -43,6 +46,33 @@ public class EasySQLDemo {
.build().execute(null /* 不处理错误 */);
}
public void useSQLTable(SQLManager sqlManager) {
SQLTable tags = SQLTable.of("servers", table -> {
table.addAutoIncrementColumn("id", true);
table.addColumn("user", "INT UNSIGNED NOT NULL");
table.addColumn("content", "TEXT NOT NULL");
table.addColumn("time", "DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP");
table.addForeignKey(
"user", "fk_user_tags",
"users", "id",
ForeignKeyRule.CASCADE, ForeignKeyRule.CASCADE
);
});
try {
tags.create(sqlManager);
} catch (SQLException e) {
e.printStackTrace();
}
tags.createQuery().addCondition("id", 5).build()
.executeAsync(success -> {
System.out.println("success!");
});
}
public void alertTable(SQLManager sqlManager) {
// 同步更新表
sqlManager.alterTable("users")
@@ -54,8 +84,8 @@ public class EasySQLDemo {
public void sqlQuery(SQLManager sqlManager) {
// 同步SQL查询
try (SQLQuery query = sqlManager.createQuery()
.inTable("users") // 在users表中查询
.selectColumns("id", "name") // 选中 id name列
.fromTable("users") // 在users表中查询
.select("id", "name") // 选中 id name列
.addCondition("age", ">", 18) // 限定 age 要大于5
.addCondition("email", null) // 限定查询 email 字段为空
.addNotNullCondition("phone") // 限定 phone 字段不为空
@@ -71,10 +101,10 @@ public class EasySQLDemo {
}
UUID userUUID = sqlManager.createQuery()
.inTable("users") // 在users表中查询
.selectColumns("uuid")
.fromTable("users") // 在users表中查询
.select("uuid")
.addCondition("id", 5) // 限定 id 5
.setLimit(1) // 只取出一个数据
.limit(1) // 只取出一个数据
.build().execute(query -> {
//可以直接进行数据处理
ResultSet result = query.getResultSet();
@@ -88,9 +118,9 @@ public class EasySQLDemo {
public void sqlQueryAsync(SQLManager sqlManager) {
// 异步SQL查询
sqlManager.createQuery()
.inTable("users") // 在users表中查询
.fromTable("users") // 在users表中查询
.addCondition("id", 5) // 限定 id 5
.setLimit(1) // 只取出一个数据
.limit(1) // 只取出一个数据
.build().executeAsync(success -> {
ResultSet resultSet = success.getResultSet();
if (resultSet != null && resultSet.next()) {
@@ -106,10 +136,10 @@ public class EasySQLDemo {
public void sqlInsert(SQLManager sqlManager) {
// 同步SQL插入 不使用try-catch的情况下返回的数值可能为空
Integer id = sqlManager.createInsert("users")
.setColumnNames("username", "phone", "email", "registerTime")
.setParams("CarmJos", "18888888888", "carm@carm.cc", TimeDateUtils.getCurrentTime())
.setReturnGeneratedKey(true)// 设定在后续返回自增主键
int id = sqlManager.insertInto("users")
.columns("username", "phone", "email", "registerTime")
.values("CarmJos", "18888888888", "carm@carm.cc", TimeDateUtils.getCurrentTime())
.returnGeneratedKey() // 设定在后续返回自增主键
.execute((exception, action) -> {
// 处理异常
System.out.println("#" + action.getShortID() + " -> " + action.getSQLContent());
@@ -117,11 +147,10 @@ public class EasySQLDemo {
});
try {
Integer userID = sqlManager.createInsert("users")
.setColumnNames("username", "phone", "email", "registerTime")
.setParams("CarmJos", "18888888888", "carm@carm.cc", TimeDateUtils.getCurrentTime())
.setReturnGeneratedKey(true)
.execute();
long userID = sqlManager.insertInto("users")
.columns("username", "phone", "email", "registerTime")
.values("CarmJos", "18888888888", "carm@carm.cc", TimeDateUtils.getCurrentTime())
.returnGeneratedKey(Long.class).execute();
System.out.println("新用户的ID为 " + userID);
@@ -130,4 +159,22 @@ public class EasySQLDemo {
}
}
public void metadata(SQLManager sql) {
// 操作数据库元数据直接返回结果
CompletableFuture<Boolean> roFuture = sql.fetchMetadata(DatabaseMetaData::isReadOnly);
CompletableFuture<Integer> maxColumnFuture = sql.fetchMetadata(DatabaseMetaData::getMaxColumnsInSelect);
// 操作有 ResultSet 元数据该方法会自动关闭ResultSet
CompletableFuture<Boolean> tableExists = sql.fetchMetadata(
meta -> meta.getTables(null, null, "表名", new String[]{"TABKE"}),
resultSet -> resultSet.next()
);
// SQLManager附带了几个常用元数据的获取方法
CompletableFuture<Boolean> tableExists2 = sql.fetchTableMetadata("表名").validateExist();
CompletableFuture<Boolean> columnExists = sql.fetchTableMetadata("表名").isColumnExists("字段名");
}
}
@@ -1,11 +1,11 @@
package cc.carm.lib.easysql;
import cc.carm.lib.easysql.api.SQLManager;
import cc.carm.lib.easysql.manager.SQLManagerImpl;
import cc.carm.lib.easysql.tests.*;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.jetbrains.annotations.NotNull;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.LinkedHashSet;
@@ -13,15 +13,29 @@ import java.util.Set;
public class EasySQLTest {
protected SQLManager sqlManager;
@Test
public void onTest() {
@Before
public void initialize() {
HikariConfig config = new HikariConfig();
config.setDriverClassName("org.h2.Driver");
config.setJdbcUrl("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;MODE=MYSQL;");
SQLManager sqlManager = new SQLManagerImpl(new HikariDataSource(config), "test");
this.sqlManager = new SQLManagerImpl(new HikariDataSource(config), "test");
this.sqlManager.setDebugMode(true);
}
@After
public void shutdown() {
if (sqlManager.getDataSource() instanceof HikariDataSource) {
//Close bee connection pool
((HikariDataSource) sqlManager.getDataSource()).close();
}
}
@Test
public void onTest() {
print("加载测试类...");
Set<TestHandler> tests = new LinkedHashSet<>();
@@ -29,11 +43,16 @@ public class EasySQLTest {
// tests.add(new TableAlterTest());
// tests.add(new TableRenameTest());
// tests.add(new QueryNotCloseTest());
tests.add(new QueryCloseTest());
tests.add(new SQLUpdateBatchTests());
tests.add(new SQLUpdateReturnKeysTest());
tests.add(new QueryCloseTest());
tests.add(new QueryFunctionTest());
tests.add(new DeleteTest());
tests.add(new QueryFutureTest());
tests.add(new QueryAsyncTest());
tests.add(new TableMetadataTest());
// tests.add(new DeleteTest());
print("准备进行测试...");
@@ -60,10 +79,6 @@ public class EasySQLTest {
success, (tests.size() - success)
);
if (sqlManager.getDataSource() instanceof HikariDataSource) {
//Close bee connection pool
((HikariDataSource) sqlManager.getDataSource()).close();
}
}
@@ -1,11 +1,8 @@
package cc.carm.lib.easysql;
import cc.carm.lib.easysql.api.SQLManager;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import java.sql.SQLException;
public abstract class TestHandler {
protected static void print(@NotNull String format, Object... params) {
@@ -13,7 +10,7 @@ public abstract class TestHandler {
}
@ApiStatus.OverrideOnly
public abstract void onTest(SQLManager sqlManager) throws SQLException;
public abstract void onTest(SQLManager sqlManager) throws Exception;
public boolean executeTest(int index, SQLManager sqlManager) {
String testName = getClass().getSimpleName();
@@ -0,0 +1,48 @@
package cc.carm.lib.easysql;
import cc.carm.lib.easysql.api.SQLManager;
import cc.carm.lib.easysql.api.enums.IsolationLevel;
import cc.carm.lib.easysql.api.transaction.SQLSavepoint;
import cc.carm.lib.easysql.api.transaction.SQLTransaction;
public class TransactionTest {
@SuppressWarnings("ConstantConditions")
public void demo() {
SQLManager sqlManager = null;
try (SQLTransaction transaction = sqlManager.createTransaction(IsolationLevel.REPEATED_READ)) {
transaction.updateInto("A")
.set("name", "CARM")
.addCondition("name", "CUMR")
.build().execute();
SQLSavepoint pointA = transaction.savepoint("TEST");
transaction.insertInto("A")
.columns("name")
.values("TEST")
.execute();
try {
transaction.commit(); // 提交
} catch (Exception ex) {
transaction.rollback(pointA); // 出错回滚到pointA
transaction.commit(); // 提交快照前的代码
}
pointA.release(); // release savepoint (结束后也会被自动释放)
} catch (Exception ex) {
}
}
}
@@ -1,6 +1,5 @@
package cc.carm.lib.easysql.tests;
import cc.carm.lib.easysql.api.SQLManager;
import cc.carm.lib.easysql.TestHandler;
import java.sql.SQLException;
@@ -11,12 +10,11 @@ public class DeleteTest extends TestHandler {
@Override
public void onTest(SQLManager sqlManager) throws SQLException {
Integer changes = sqlManager.createDelete("test_user_table")
System.out.println("change(s): " + sqlManager.createDelete("test_user_table")
.addCondition("id", ">", 5)
.addNotNullCondition("username")
.build().execute();
System.out.println("change(s): " + changes);
.build().execute());
}
}
@@ -0,0 +1,32 @@
package cc.carm.lib.easysql.tests;
import cc.carm.lib.easysql.TestHandler;
import java.sql.SQLException;
public class QueryAsyncTest extends TestHandler {
@Override
public void onTest(SQLManager sqlManager) throws SQLException {
sqlManager.createQuery()
.fromTable("test_user_table")
.orderBy("id", false)
.limit(1)
.build().executeAsync(query -> {
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
if (!query.getResultSet().next()) {
System.out.println("id (ps): NULL");
} else {
System.out.println("id (ps): " + query.getResultSet().getInt("id"));
}
});
}
}
@@ -1,9 +1,9 @@
package cc.carm.lib.easysql.tests;
import cc.carm.lib.easysql.api.SQLManager;
import cc.carm.lib.easysql.api.SQLQuery;
import cc.carm.lib.easysql.TestHandler;
import cc.carm.lib.easysql.api.SQLQuery;
import java.math.BigInteger;
import java.sql.ResultSet;
import java.sql.SQLException;
@@ -14,9 +14,9 @@ public class QueryCloseTest extends TestHandler {
public void onTest(SQLManager sqlManager) throws SQLException {
try (SQLQuery query = sqlManager.createQuery()
.inTable("test_user_table")
.fromTable("test_user_table")
.orderBy("id", false)
.setLimit(5)
.limit(5)
.build().execute()) {
ResultSet resultSet = query.getResultSet();
@@ -24,7 +24,7 @@ public class QueryCloseTest extends TestHandler {
System.out.printf(
"id: %d username: %s%n",
resultSet.getInt("id"),
resultSet.getObject("id", BigInteger.class),
resultSet.getString("username")
);
@@ -1,7 +1,6 @@
package cc.carm.lib.easysql.tests;
import cc.carm.lib.easysql.TestHandler;
import cc.carm.lib.easysql.api.SQLManager;
import java.sql.SQLException;
@@ -12,10 +11,15 @@ public class QueryFunctionTest extends TestHandler {
public void onTest(SQLManager sqlManager) throws SQLException {
Integer id_1 = sqlManager.createQuery()
.inTable("test_user_table")
.fromTable("test_user_table")
.orderBy("id", false)
.setLimit(1)
.limit(1)
.build().executeFunction(query -> {
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
if (!query.getResultSet().next()) return -1;
else return query.getResultSet().getInt("id");
});
@@ -0,0 +1,32 @@
package cc.carm.lib.easysql.tests;
import cc.carm.lib.easysql.TestHandler;
import java.sql.SQLException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
public class QueryFutureTest extends TestHandler {
@Override
public void onTest(SQLManager sqlManager) throws SQLException, ExecutionException, InterruptedException {
Future<Integer> future = sqlManager.createQuery()
.fromTable("test_user_table")
.orderBy("id", false)
.limit(1)
.build().executeFuture((query) -> {
if (!query.getResultSet().next()) {
return -1;
} else {
return query.getResultSet().getInt("id");
}
});
int id = future.get();
System.out.println("id(future): " + id);
}
}
@@ -1,20 +1,20 @@
package cc.carm.lib.easysql.tests;
import cc.carm.lib.easysql.api.SQLManager;
import cc.carm.lib.easysql.api.SQLQuery;
import cc.carm.lib.easysql.TestHandler;
import cc.carm.lib.easysql.api.SQLQuery;
import java.sql.ResultSet;
import java.sql.SQLException;
@SuppressWarnings("resource")
public class QueryNotCloseTest extends TestHandler {
@Override
public void onTest(SQLManager sqlManager) throws SQLException {
SQLQuery query = sqlManager.createQuery()
.inTable("test_user_table")
.fromTable("test_user_table")
.orderBy("id", false)
.setLimit(5)
.limit(5)
.build().execute();
ResultSet resultSet = query.getResultSet();
@@ -1,6 +1,5 @@
package cc.carm.lib.easysql.tests;
import cc.carm.lib.easysql.api.SQLManager;
import cc.carm.lib.easysql.TestHandler;
import java.sql.SQLException;
@@ -25,9 +24,10 @@ public class SQLUpdateBatchTests extends TestHandler {
@Override
public void onTest(SQLManager sqlManager) throws SQLException {
List<Integer> updates = sqlManager.createInsertBatch("test_user_table")
.setColumnNames("uuid", "username", "age")
.setAllParams(generateParams())
List<Long> updates = sqlManager.createInsertBatch("test_user_table")
.columns("uuid", "username", "age")
.allValues(generateParams())
.returnGeneratedKeys(Long.class)
.execute();
System.out.println("changes " + Arrays.toString(updates.toArray()));
@@ -1,7 +1,5 @@
package cc.carm.lib.easysql.tests;
import cc.carm.lib.easysql.api.SQLManager;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
@@ -12,9 +10,9 @@ public class SQLUpdateReturnKeysTest extends SQLUpdateBatchTests {
@Override
public void onTest(SQLManager sqlManager) throws SQLException {
List<Integer> generatedKeys = sqlManager.createInsertBatch("test_user_table")
.setColumnNames("uuid", "username", "age")
.setAllParams(generateParams())
.returnGeneratedKeys()
.columns("uuid", "username", "age")
.allValues(generateParams())
.returnGeneratedKeys(Integer.class)
.execute();
System.out.println("generated " + Arrays.toString(generatedKeys.toArray()));
@@ -1,8 +1,7 @@
package cc.carm.lib.easysql.tests;
import cc.carm.lib.easysql.api.SQLManager;
import cc.carm.lib.easysql.api.enums.NumberType;
import cc.carm.lib.easysql.TestHandler;
import cc.carm.lib.easysql.api.enums.NumberType;
import java.sql.SQLException;
@@ -1,9 +1,8 @@
package cc.carm.lib.easysql.tests;
import cc.carm.lib.easysql.api.SQLManager;
import cc.carm.lib.easysql.TestHandler;
import cc.carm.lib.easysql.api.enums.ForeignKeyRule;
import cc.carm.lib.easysql.api.enums.IndexType;
import cc.carm.lib.easysql.TestHandler;
import java.sql.SQLException;
@@ -0,0 +1,38 @@
package cc.carm.lib.easysql.tests;
import cc.carm.lib.easysql.TestHandler;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
public class TableMetadataTest extends TestHandler {
@Override
public void onTest(SQLManager sqlManager) throws Exception {
print(" 获取数据库中所有的表");
CompletableFuture<List<String>> tables = sqlManager.fetchMetadata(
(meta) -> meta.getTables(null, null, "%", new String[]{"TABLE"}),
(rs) -> {
List<String> data = new ArrayList<>();
while (rs.next()) {
data.add(rs.getString("TABLE_NAME"));
}
return data;
}
);
print("表名:" + Arrays.toString(tables.get().toArray()));
print(" 获取数据库中所有的列");
CompletableFuture<Set<String>> columns = sqlManager.fetchTableMetadata("test%").listColumns();
print("列名:" + Arrays.toString(columns.get().toArray()));
print("表是否存在 " + sqlManager.fetchTableMetadata("test_user_info").validateExist().get());
print("列是否存在 " + sqlManager.fetchTableMetadata("test_user_info").isColumnExists("uid").get());
}
}
@@ -1,6 +1,5 @@
package cc.carm.lib.easysql.tests;
import cc.carm.lib.easysql.api.SQLManager;
import cc.carm.lib.easysql.TestHandler;
import java.sql.SQLException;
+26
View File
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" packages="cc.carm.lib.easysql.EasySQLTest">
<Appenders>
<console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="[%d{HH:mm:ss} %level]: %msg%n"/>
</console>
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level]: %msg{nolookups}%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<OnStartupTriggeringPolicy/>
</Policies>
</RollingRandomAccessFile>
</Appenders>
<Loggers>
<Root level="info">
<filters>
<MarkerFilter marker="NETWORK_PACKETS" onMatch="DENY" onMismatch="NEUTRAL"/>
<RegexFilter regex=".*\$\{[^}]*\}.*" onMatch="DENY" onMismatch="NEUTRAL"/>
</filters>
<AppenderRef ref="File"/>
<appender-ref ref="Console"/>
</Root>
</Loggers>
</Configuration>
+3 -7
View File
@@ -5,13 +5,13 @@
<parent>
<artifactId>easysql-parent</artifactId>
<groupId>cc.carm.lib</groupId>
<version>0.3.9</version>
<version>0.4.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<properties>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<maven.compiler.source>${jdk.version}</maven.compiler.source>
<maven.compiler.target>${jdk.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
</properties>
@@ -81,10 +81,6 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
</plugin>
</plugins>
</build>
@@ -0,0 +1,224 @@
package cc.carm.lib.easysql;
import cc.carm.lib.easysql.action.PreparedSQLBatchUpdateActionImpl;
import cc.carm.lib.easysql.action.PreparedSQLUpdateActionImpl;
import cc.carm.lib.easysql.action.SQLBatchUpdateActionImpl;
import cc.carm.lib.easysql.action.UpdateActionImpl;
import cc.carm.lib.easysql.api.SQLManager;
import cc.carm.lib.easysql.api.action.base.BatchUpdateAction;
import cc.carm.lib.easysql.api.action.base.PreparedBatchUpdateAction;
import cc.carm.lib.easysql.api.action.base.PreparedUpdateAction;
import cc.carm.lib.easysql.api.action.update.PreparedSQLBatchUpdateAction;
import cc.carm.lib.easysql.api.action.update.PreparedSQLUpdateAction;
import cc.carm.lib.easysql.api.builder.*;
import cc.carm.lib.easysql.api.enums.IsolationLevel;
import cc.carm.lib.easysql.api.function.SQLBiFunction;
import cc.carm.lib.easysql.api.function.SQLDebugHandler;
import cc.carm.lib.easysql.api.function.SQLExceptionHandler;
import cc.carm.lib.easysql.api.function.SQLFunction;
import cc.carm.lib.easysql.api.transaction.SQLTransaction;
import cc.carm.lib.easysql.builder.impl.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.function.Supplier;
public class SQLManagerImpl extends SQLSourceImpl implements SQLManager {
public SQLManagerImpl(@NotNull DataSource dataSource) {
super(dataSource);
}
public SQLManagerImpl(@NotNull DataSource dataSource, @Nullable String name) {
super(dataSource, name);
}
public SQLManagerImpl(@NotNull DataSource dataSource, @NotNull Logger logger) {
super(dataSource, logger);
}
public SQLManagerImpl(@NotNull DataSource dataSource, @NotNull Logger logger, @Nullable String name) {
super(dataSource, logger, name);
}
public SQLManagerImpl(@NotNull DataSource dataSource, @NotNull Logger logger, @NotNull ExecutorService executorPool,
@NotNull Supplier<Boolean> debugMode, @NotNull SQLDebugHandler debugHandler,
@NotNull SQLExceptionHandler exceptionHandler) {
super(dataSource, logger, executorPool, debugMode, debugHandler, exceptionHandler);
}
@Override
public Integer executeSQL(String sql) {
return new UpdateActionImpl<>(this, Integer.class, sql).execute(null);
}
@Override
public Integer executeSQL(String sql, Object[] params) {
return new PreparedSQLUpdateActionImpl<>(this, Integer.class, sql, params).execute(null);
}
@Override
public List<Integer> executeSQLBatch(String sql, Iterable<Object[]> paramsBatch) {
return new PreparedSQLBatchUpdateActionImpl<>(this, Integer.class, sql).allValues(paramsBatch).execute(null);
}
@Override
public List<Integer> executeSQLBatch(@NotNull String sql, String... moreSQL) {
BatchUpdateAction action = new SQLBatchUpdateActionImpl(this, sql);
if (moreSQL != null && moreSQL.length > 0) {
Arrays.stream(moreSQL).forEach(action::addBatch);
}
return action.execute(null);
}
@Override
public @Nullable List<Integer> executeSQLBatch(@NotNull Iterable<String> sqlBatch) {
Iterator<String> iterator = sqlBatch.iterator();
if (!iterator.hasNext()) return null; // PLEASE GIVE IT SOMETHING
BatchUpdateAction action = new SQLBatchUpdateActionImpl(this, iterator.next());
while (iterator.hasNext()) {
action.addBatch(iterator.next());
}
return action.execute(null);
}
@Override
public @NotNull SQLTransaction createTransaction(@Nullable IsolationLevel level) {
return null;
}
@Override
public <R> CompletableFuture<R> fetchMetadata(@NotNull SQLBiFunction<DatabaseMetaData, Connection, R> reader) {
return CompletableFuture.supplyAsync(() -> {
try (Connection conn = getConnection()) {
return reader.apply(conn.getMetaData(), conn);
} catch (SQLException ex) {
throw new RuntimeException(ex);
}
}, this.executorPool);
}
@Override
public <R> CompletableFuture<R> fetchMetadata(@NotNull SQLBiFunction<DatabaseMetaData, Connection, ResultSet> supplier,
@NotNull SQLFunction<@NotNull ResultSet, R> reader) {
return fetchMetadata((meta, conn) -> {
try (ResultSet rs = supplier.apply(conn.getMetaData(), conn)) {
if (rs == null) throw new NullPointerException("Metadata返回的ResultSet为null。");
else return reader.apply(rs);
} catch (SQLException ex) {
throw new RuntimeException(ex);
}
});
}
@Override
public TableCreateBuilder createTable(@NotNull String tableName) {
return new TableCreateBuilderImpl(this, tableName);
}
@Override
public TableAlterBuilder alterTable(@NotNull String tableName) {
return new TableAlterBuilderImpl(this, tableName);
}
@Override
public TableMetadataBuilder fetchTableMetadata(@NotNull String tablePattern) {
return new TableMetadataBuilderImpl(this, tablePattern);
}
@Override
public QueryBuilder createQuery() {
return new QueryBuilderImpl(this);
}
@Override
public InsertBuilder<PreparedBatchUpdateAction<Integer>> createInsertBatch(@NotNull String tableName) {
return new InsertBuilderImpl<PreparedBatchUpdateAction<Integer>>(this, tableName) {
@Override
public PreparedBatchUpdateAction<Integer> columns(List<String> columnNames) {
return new PreparedSQLBatchUpdateActionImpl<>(getManager(), Integer.class, buildSQL(getTableName(), columnNames));
}
};
}
@Override
public InsertBuilder<PreparedUpdateAction<Integer>> insertInto(@NotNull String tableName) {
return new InsertBuilderImpl<PreparedUpdateAction<Integer>>(this, tableName) {
@Override
public PreparedUpdateAction<Integer> columns(List<String> columnNames) {
return new PreparedSQLUpdateActionImpl<>(getManager(), Integer.class, buildSQL(getTableName(), columnNames));
}
};
}
@Override
public @NotNull InsertBuilder<PreparedSQLBatchUpdateAction.Advanced<Integer>> insertBatchInto(@NotNull String tableName) {
return null;
}
@Override
public @NotNull ReplaceBuilder<PreparedSQLUpdateAction.Advanced<Integer>> replaceInto(@NotNull String tableName) {
return null;
}
@Override
public @NotNull ReplaceBuilder<PreparedSQLBatchUpdateAction.Advanced<Integer>> replaceBatchInto(@NotNull String tableName) {
return null;
}
@Override
public @NotNull UpdateBuilder<PreparedSQLUpdateAction.Advanced<Integer>> updateInto(@NotNull String tableName) {
return null;
}
@Override
public @NotNull DeleteBuilder<PreparedSQLUpdateAction.Advanced<Integer>> deleteFrom(@NotNull String tableName) {
return null;
}
@Override
public ReplaceBuilder<PreparedBatchUpdateAction<Integer>> createReplaceBatch(@NotNull String tableName) {
return new ReplaceBuilderImpl<PreparedBatchUpdateAction<Integer>>(this, tableName) {
@Override
public PreparedBatchUpdateAction<Integer> columns(List<String> columnNames) {
return new PreparedSQLBatchUpdateActionImpl<>(getManager(), Integer.class, buildSQL(getTableName(), columnNames));
}
};
}
@Override
public ReplaceBuilder<PreparedUpdateAction<Integer>> createReplace(@NotNull String tableName) {
return new ReplaceBuilderImpl<PreparedUpdateAction<Integer>>(this, tableName) {
@Override
public PreparedUpdateAction<Integer> columns(List<String> columnNames) {
return new PreparedSQLUpdateActionImpl<>(getManager(), Integer.class, buildSQL(getTableName(), columnNames));
}
};
}
@Override
public UpdateBuilder createUpdate(@NotNull String tableName) {
return new UpdateBuilderImpl(this, tableName);
}
@Override
public DeleteBuilder createDelete(@NotNull String tableName) {
return new DeleteBuilderImpl(this, tableName);
}
}
@@ -0,0 +1,126 @@
package cc.carm.lib.easysql;
import cc.carm.lib.easysql.api.SQLQuery;
import cc.carm.lib.easysql.api.SQLSource;
import cc.carm.lib.easysql.api.function.SQLDebugHandler;
import cc.carm.lib.easysql.api.function.SQLExceptionHandler;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.function.Supplier;
public class SQLSourceImpl implements SQLSource {
protected final @NotNull Logger logger;
protected final @NotNull DataSource dataSource;
protected @NotNull ExecutorService executorPool;
protected @NotNull Supplier<Boolean> debugMode = () -> Boolean.FALSE;
protected @NotNull SQLDebugHandler debugHandler;
protected @NotNull SQLExceptionHandler exceptionHandler;
protected final ConcurrentHashMap<UUID, SQLQuery> activeQueries = new ConcurrentHashMap<>();
public SQLSourceImpl(@NotNull DataSource dataSource) {
this(dataSource, (String) null);
}
public SQLSourceImpl(@NotNull DataSource dataSource, @Nullable String name) {
this(dataSource, LoggerFactory.getLogger(SQLManagerImpl.class), name);
}
public SQLSourceImpl(@NotNull DataSource dataSource, @NotNull Logger logger) {
this(dataSource, logger, null);
}
public SQLSourceImpl(@NotNull DataSource dataSource, @NotNull Logger logger, @Nullable String name) {
this(
dataSource, logger,
SQLSource.defaultExecutorPool("SQLSource" + (name != null ? "#" + name : "")),
() -> false, SQLDebugHandler.defaultHandler(logger), SQLExceptionHandler.detailed(logger)
);
}
public SQLSourceImpl(@NotNull DataSource dataSource, @NotNull Logger logger, @NotNull ExecutorService executorPool,
@NotNull Supplier<Boolean> debugMode, @NotNull SQLDebugHandler debugHandler,
@NotNull SQLExceptionHandler exceptionHandler) {
this.logger = logger;
this.dataSource = dataSource;
this.executorPool = executorPool;
this.exceptionHandler = exceptionHandler;
this.debugMode = debugMode;
this.debugHandler = debugHandler;
}
@Override
public @NotNull Map<UUID, SQLQuery> getActiveQueries() {
return this.activeQueries;
}
@Override
public @NotNull DataSource getDataSource() {
return this.dataSource;
}
@Override
public @NotNull Connection getConnection() throws SQLException {
return getDataSource().getConnection();
}
@Override
public @NotNull Logger getLogger() {
return this.logger;
}
@Override
public @NotNull ExecutorService getExecutorPool() {
return this.executorPool;
}
@Override
public void setExecutorPool(@NotNull ExecutorService executorPool) {
this.executorPool = executorPool;
}
@Override
public boolean isDebugMode() {
return this.debugMode.get();
}
@Override
public void setDebugMode(@NotNull Supplier<@NotNull Boolean> debugMode) {
this.debugMode = debugMode;
}
@Override
public @NotNull SQLDebugHandler getDebugHandler() {
return this.debugHandler;
}
@Override
public void setDebugHandler(@NotNull SQLDebugHandler debugHandler) {
this.debugHandler = debugHandler;
}
@Override
public @NotNull SQLExceptionHandler getExceptionHandler() {
return this.exceptionHandler;
}
@Override
public void setExceptionHandler(@Nullable SQLExceptionHandler handler) {
if (handler == null) this.exceptionHandler = SQLExceptionHandler.detailed(getLogger());
else this.exceptionHandler = handler;
}
}
@@ -0,0 +1,108 @@
package cc.carm.lib.easysql;
import cc.carm.lib.easysql.api.SQLManager;
import cc.carm.lib.easysql.api.action.query.PreparedSQLQueryAction;
import cc.carm.lib.easysql.api.action.query.SQLQueryAction;
import cc.carm.lib.easysql.api.action.update.PreparedSQLBatchUpdateAction;
import cc.carm.lib.easysql.api.action.update.PreparedSQLUpdateAction;
import cc.carm.lib.easysql.api.builder.*;
import cc.carm.lib.easysql.api.enums.IsolationLevel;
import cc.carm.lib.easysql.api.transaction.SQLSavepoint;
import cc.carm.lib.easysql.api.transaction.SQLTransaction;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public class SQLTransactionImpl implements SQLTransaction {
@Override
public @NotNull SQLManager getManager() {
return null;
}
@Override
public @NotNull IsolationLevel getIsolationLevel() {
return null;
}
@Override
public void commit() {
}
@Override
public @NotNull SQLSavepoint savepoint(@NotNull String name) {
return null;
}
@Override
public void rollback(@Nullable SQLSavepoint savepoint) {
}
@Override
public @Nullable Integer executeSQL(String sql) {
return null;
}
@Override
public @Nullable Integer executeSQL(String sql, Object[] params) {
return null;
}
@Override
public @Nullable List<Integer> executeSQLBatch(String sql, Iterable<Object[]> paramsBatch) {
return null;
}
@Override
public @Nullable List<Integer> executeSQLBatch(@NotNull String sql, String... moreSQL) {
return null;
}
@Override
public @Nullable List<Integer> executeSQLBatch(@NotNull Iterable<String> sqlBatch) {
return null;
}
@Override
public @NotNull QueryBuilder<SQLQueryAction.Base, PreparedSQLQueryAction.Base> createQuery() {
return null;
}
@Override
public @NotNull InsertBuilder<PreparedSQLUpdateAction.Base<Integer>> insertInto(@NotNull String tableName) {
return null;
}
@Override
public @NotNull InsertBuilder<PreparedSQLBatchUpdateAction.Base<Integer>> insertBatchInto(@NotNull String tableName) {
return null;
}
@Override
public @NotNull ReplaceBuilder<PreparedSQLUpdateAction.Base<Integer>> replaceInto(@NotNull String tableName) {
return null;
}
@Override
public @NotNull ReplaceBuilder<PreparedSQLBatchUpdateAction.Base<Integer>> replaceBatchInto(@NotNull String tableName) {
return null;
}
@Override
public @NotNull UpdateBuilder<PreparedSQLUpdateAction.Base<Integer>> updateInto(@NotNull String tableName) {
return null;
}
@Override
public @NotNull DeleteBuilder<PreparedSQLUpdateAction.Base<Integer>> deleteFrom(@NotNull String tableName) {
return null;
}
@Override
public void close() throws Exception {
}
}
@@ -1,43 +1,46 @@
package cc.carm.lib.easysql.action;
import cc.carm.lib.easysql.api.SQLAction;
import cc.carm.lib.easysql.api.function.SQLExceptionHandler;
import cc.carm.lib.easysql.api.function.SQLFunction;
import cc.carm.lib.easysql.api.function.SQLHandler;
import cc.carm.lib.easysql.manager.SQLManagerImpl;
import cc.carm.lib.easysql.SQLManagerImpl;
import org.jetbrains.annotations.NotNull;
import java.sql.SQLException;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
public abstract class AbstractSQLAction<T> implements SQLAction<T> {
protected final @NotNull String sqlContent;
private final @NotNull SQLManagerImpl sqlManager;
private final @NotNull UUID uuid;
private final long createTime;
private final long createNanoTime;
public AbstractSQLAction(@NotNull SQLManagerImpl manager, @NotNull String sql) {
this(manager, sql, System.currentTimeMillis());
this(manager, sql, System.nanoTime());
}
public AbstractSQLAction(@NotNull SQLManagerImpl manager, @NotNull String sql, @NotNull UUID uuid) {
this(manager, sql, uuid, System.currentTimeMillis());
this(manager, sql, uuid, System.nanoTime());
}
public AbstractSQLAction(@NotNull SQLManagerImpl manager, @NotNull String sql, long createTime) {
this(manager, sql, UUID.randomUUID(), createTime);
public AbstractSQLAction(@NotNull SQLManagerImpl manager, @NotNull String sql, long createNanoTime) {
this(manager, sql, UUID.randomUUID(), createNanoTime);
}
public AbstractSQLAction(@NotNull SQLManagerImpl manager, @NotNull String sql,
@NotNull UUID uuid, long createTime) {
@NotNull UUID uuid, long createNanoTime) {
Objects.requireNonNull(manager);
Objects.requireNonNull(sql);
Objects.requireNonNull(uuid);
this.sqlManager = manager;
this.sqlContent = sql;
this.uuid = uuid;
this.createTime = createTime;
this.createNanoTime = createNanoTime;
}
@@ -52,8 +55,8 @@ public abstract class AbstractSQLAction<T> implements SQLAction<T> {
}
@Override
public long getCreateTime() {
return this.createTime;
public long getCreateTime(TimeUnit unit) {
return unit.convert(createNanoTime, TimeUnit.NANOSECONDS);
}
@Override
@@ -66,8 +69,14 @@ public abstract class AbstractSQLAction<T> implements SQLAction<T> {
return this.sqlManager;
}
protected void outputDebugMessage() {
getManager().debug("# " + getShortID() + " -> { " + getSQLContent() + " }");
protected void debugMessage(List<Object[]> params) {
if (getManager().isDebugMode()) {
try {
getManager().getDebugHandler().beforeExecute(this, params);
} catch (Exception exception) {
exception.printStackTrace();
}
}
}
@Override
@@ -83,4 +92,10 @@ public abstract class AbstractSQLAction<T> implements SQLAction<T> {
});
}
@Override
public @NotNull <R> CompletableFuture<R> executeFuture(@NotNull SQLFunction<T, R> handler) {
CompletableFuture<R> future = new CompletableFuture<>();
executeAsync((t -> future.complete(handler.apply(t))), (e, q) -> future.completeExceptionally(e));
return future;
}
}
@@ -1,7 +1,7 @@
package cc.carm.lib.easysql.action;
import cc.carm.lib.easysql.api.action.PreparedSQLUpdateBatchAction;
import cc.carm.lib.easysql.manager.SQLManagerImpl;
import cc.carm.lib.easysql.api.action.base.PreparedBatchUpdateAction;
import cc.carm.lib.easysql.SQLManagerImpl;
import cc.carm.lib.easysql.util.StatementUtil;
import org.jetbrains.annotations.NotNull;
@@ -12,56 +12,74 @@ import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
public class PreparedSQLBatchUpdateActionImpl
extends AbstractSQLAction<List<Integer>>
implements PreparedSQLUpdateBatchAction {
public class PreparedSQLBatchUpdateActionImpl<T extends Number>
extends AbstractSQLAction<List<T>>
implements PreparedBatchUpdateAction<T> {
boolean returnKeys = false;
List<Object[]> allParams;
@NotNull List<Object[]> allParams = new ArrayList<>();
public PreparedSQLBatchUpdateActionImpl(@NotNull SQLManagerImpl manager, @NotNull String sql) {
protected final @NotNull Class<T> numberClass;
public PreparedSQLBatchUpdateActionImpl(@NotNull SQLManagerImpl manager, @NotNull Class<T> numberClass,
@NotNull String sql) {
super(manager, sql);
this.numberClass = numberClass;
this.allParams = new ArrayList<>();
}
public PreparedSQLBatchUpdateActionImpl(@NotNull SQLManagerImpl manager, @NotNull Class<T> numberClass,
@NotNull UUID uuid, @NotNull String sql) {
super(manager, sql, uuid);
this.numberClass = numberClass;
}
@Override
public PreparedSQLUpdateBatchAction setAllParams(Iterable<Object[]> allParams) {
public PreparedSQLBatchUpdateActionImpl<T> allValues(Iterable<Object[]> allValues) {
List<Object[]> paramsList = new ArrayList<>();
allParams.forEach(paramsList::add);
allValues.forEach(paramsList::add);
this.allParams = paramsList;
return this;
}
@Override
public PreparedSQLUpdateBatchAction addParamsBatch(Object... params) {
this.allParams.add(params);
public PreparedSQLBatchUpdateActionImpl<T> addValues(Object... values) {
this.allParams.add(values);
return this;
}
@Override
public PreparedSQLUpdateBatchAction setReturnGeneratedKeys(boolean returnGeneratedKey) {
this.returnKeys = returnGeneratedKey;
public PreparedSQLBatchUpdateActionImpl<T> returnGeneratedKeys() {
this.returnKeys = true;
return this;
}
@Override
public @NotNull List<Integer> execute() throws SQLException {
public <N extends Number> PreparedSQLBatchUpdateActionImpl<N> returnGeneratedKeys(Class<N> keyTypeClass) {
return new PreparedSQLBatchUpdateActionImpl<>(getManager(), keyTypeClass, getActionUUID(), getSQLContent())
.allValues(allParams).returnGeneratedKeys();
}
@Override
public @NotNull List<T> execute() throws SQLException {
debugMessage(allParams);
try (Connection connection = getManager().getConnection()) {
try (PreparedStatement statement = StatementUtil.createPrepareStatementBatch(
connection, getSQLContent(), allParams, returnKeys
)) {
outputDebugMessage();
int[] executed = statement.executeBatch();
if (!returnKeys) return Arrays.stream(executed).boxed().collect(Collectors.toList());
else {
if (!returnKeys) {
return Arrays.stream(executed).mapToObj(numberClass::cast).collect(Collectors.toList());
} else {
try (ResultSet resultSet = statement.getGeneratedKeys()) {
List<Integer> generatedKeys = new ArrayList<>();
List<T> generatedKeys = new ArrayList<>();
while (resultSet.next()) {
generatedKeys.add(resultSet.getInt(1));
generatedKeys.add(resultSet.getObject(1, numberClass));
}
return generatedKeys;
}
@@ -1,7 +1,8 @@
package cc.carm.lib.easysql.action;
import cc.carm.lib.easysql.api.action.PreparedSQLUpdateAction;
import cc.carm.lib.easysql.manager.SQLManagerImpl;
import cc.carm.lib.easysql.api.action.base.PreparedUpdateAction;
import cc.carm.lib.easysql.api.action.base.UpdateAction;
import cc.carm.lib.easysql.SQLManagerImpl;
import cc.carm.lib.easysql.util.StatementUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -11,61 +12,71 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
public class PreparedSQLUpdateActionImpl
extends SQLUpdateActionImpl
implements PreparedSQLUpdateAction {
public class PreparedSQLUpdateActionImpl<T extends Number>
extends UpdateActionImpl<T>
implements PreparedUpdateAction<T> {
Object[] params;
public PreparedSQLUpdateActionImpl(@NotNull SQLManagerImpl manager, @NotNull String sql) {
this(manager, sql, (Object[]) null);
public PreparedSQLUpdateActionImpl(@NotNull SQLManagerImpl manager, @NotNull Class<T> numberClass,
@NotNull String sql) {
this(manager, numberClass, sql, (Object[]) null);
}
public PreparedSQLUpdateActionImpl(@NotNull SQLManagerImpl manager, @NotNull String sql,
@Nullable List<Object> params) {
this(manager, sql, params == null ? null : params.toArray());
public PreparedSQLUpdateActionImpl(@NotNull SQLManagerImpl manager, @NotNull Class<T> numberClass,
@NotNull String sql, @Nullable List<Object> params) {
this(manager, numberClass, sql, params == null ? null : params.toArray());
}
public PreparedSQLUpdateActionImpl(@NotNull SQLManagerImpl manager, @NotNull String sql,
@Nullable Object[] params) {
super(manager, sql);
public PreparedSQLUpdateActionImpl(@NotNull SQLManagerImpl manager, @NotNull Class<T> numberClass,
@NotNull String sql, @Nullable Object[] params) {
super(manager, numberClass, sql);
this.params = params;
}
public PreparedSQLUpdateActionImpl(@NotNull SQLManagerImpl manager, @NotNull Class<T> numberClass,
@NotNull UUID uuid, @NotNull String sql,
Object[] params) {
super(manager, numberClass, uuid, sql);
this.params = params;
}
@Override
public PreparedSQLUpdateActionImpl setParams(Object... params) {
public PreparedSQLUpdateActionImpl<T> values(Object... params) {
this.params = params;
return this;
}
@Override
public PreparedSQLUpdateAction setParams(@Nullable Iterable<Object> params) {
public PreparedSQLUpdateActionImpl<T> values(@Nullable Iterable<Object> params) {
if (params == null) {
return setParams((Object[]) null);
return values((Object[]) null);
} else {
List<Object> paramsList = new ArrayList<>();
params.forEach(paramsList::add);
return setParams(paramsList.toArray());
return values(paramsList.toArray());
}
}
@Override
public @NotNull Integer execute() throws SQLException {
public @NotNull T execute() throws SQLException {
debugMessage(Collections.singletonList(params));
try (Connection connection = getManager().getConnection()) {
try (PreparedStatement statement = StatementUtil.createPrepareStatement(
connection, getSQLContent(), params, returnGeneratedKeys
)) {
outputDebugMessage();
int changes = statement.executeUpdate();
if (!returnGeneratedKeys) return changes;
if (!returnGeneratedKeys) return numberClass.cast(changes);
else {
try (ResultSet resultSet = statement.getGeneratedKeys()) {
return resultSet.next() ? resultSet.getInt(1) : -1;
return resultSet.next() ? resultSet.getObject(1, numberClass) : numberClass.cast(0);
}
}
@@ -74,4 +85,10 @@ public class PreparedSQLUpdateActionImpl
}
@Override
public <N extends Number> UpdateAction<N> returnGeneratedKey(Class<N> keyTypeClass) {
PreparedSQLUpdateActionImpl<N> newAction = new PreparedSQLUpdateActionImpl<>(getManager(), keyTypeClass, getActionUUID(), getSQLContent(), params);
newAction.returnGeneratedKey();
return newAction;
}
}
@@ -1,7 +1,7 @@
package cc.carm.lib.easysql.action;
import cc.carm.lib.easysql.api.action.SQLUpdateBatchAction;
import cc.carm.lib.easysql.manager.SQLManagerImpl;
import cc.carm.lib.easysql.api.action.base.BatchUpdateAction;
import cc.carm.lib.easysql.SQLManagerImpl;
import org.jetbrains.annotations.NotNull;
import java.sql.Connection;
@@ -13,13 +13,13 @@ import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public class SQLUpdateBatchActionImpl
public class SQLBatchUpdateActionImpl
extends AbstractSQLAction<List<Integer>>
implements SQLUpdateBatchAction {
implements BatchUpdateAction {
protected final List<String> sqlContents = new ArrayList<>();
public SQLUpdateBatchActionImpl(@NotNull SQLManagerImpl manager, @NotNull String sql) {
public SQLBatchUpdateActionImpl(@NotNull SQLManagerImpl manager, @NotNull String sql) {
super(manager, sql);
this.sqlContents.add(sql);
}
@@ -30,7 +30,7 @@ public class SQLUpdateBatchActionImpl
}
@Override
public SQLUpdateBatchAction addBatch(@NotNull String sql) {
public BatchUpdateAction addBatch(@NotNull String sql) {
Objects.requireNonNull(sql, "sql could not be null");
this.sqlContents.add(sql);
return this;
@@ -38,10 +38,11 @@ public class SQLUpdateBatchActionImpl
@Override
public @NotNull List<Integer> execute() throws SQLException {
debugMessage(new ArrayList<>());
try (Connection connection = getManager().getConnection()) {
try (Statement statement = connection.createStatement()) {
outputDebugMessage();
for (String content : this.sqlContents) {
statement.addBatch(content);
@@ -55,12 +56,4 @@ public class SQLUpdateBatchActionImpl
}
}
@Override
protected void outputDebugMessage() {
getManager().debug("# " + getShortID() + " -> [");
for (String content : getSQLContents()) getManager().debug(String.format(" { %s }", content));
getManager().debug("]");
}
}
@@ -1,48 +0,0 @@
package cc.carm.lib.easysql.action;
import cc.carm.lib.easysql.api.action.SQLUpdateAction;
import cc.carm.lib.easysql.manager.SQLManagerImpl;
import org.jetbrains.annotations.NotNull;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class SQLUpdateActionImpl
extends AbstractSQLAction<Integer>
implements SQLUpdateAction {
boolean returnGeneratedKeys = false;
public SQLUpdateActionImpl(@NotNull SQLManagerImpl manager, @NotNull String sql) {
super(manager, sql);
}
@Override
public @NotNull Integer execute() throws SQLException {
try (Connection connection = getManager().getConnection()) {
try (Statement statement = connection.createStatement()) {
outputDebugMessage();
if (!returnGeneratedKeys) {
return statement.executeUpdate(getSQLContent());
} else {
statement.executeUpdate(getSQLContent(), Statement.RETURN_GENERATED_KEYS);
try (ResultSet resultSet = statement.getGeneratedKeys()) {
return resultSet.next() ? resultSet.getInt(1) : -1;
}
}
}
}
}
@Override
public SQLUpdateAction setReturnGeneratedKey(boolean returnGeneratedKey) {
this.returnGeneratedKeys = returnGeneratedKey;
return this;
}
}
@@ -0,0 +1,65 @@
package cc.carm.lib.easysql.action;
import cc.carm.lib.easysql.api.action.base.UpdateAction;
import cc.carm.lib.easysql.SQLManagerImpl;
import org.jetbrains.annotations.NotNull;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.UUID;
public class UpdateActionImpl<T extends Number>
extends AbstractSQLAction<T>
implements UpdateAction<T> {
protected final @NotNull Class<T> numberClass;
protected boolean returnGeneratedKeys = false;
public UpdateActionImpl(@NotNull SQLManagerImpl manager, @NotNull Class<T> numberClass,
@NotNull String sql) {
super(manager, sql);
this.numberClass = numberClass;
}
public UpdateActionImpl(@NotNull SQLManagerImpl manager, @NotNull Class<T> numberClass,
@NotNull UUID uuid, @NotNull String sql) {
super(manager, sql, uuid);
this.numberClass = numberClass;
}
@Override
public @NotNull T execute() throws SQLException {
debugMessage(new ArrayList<>());
try (Connection connection = getManager().getConnection()) {
try (Statement statement = connection.createStatement()) {
if (!returnGeneratedKeys) {
return numberClass.cast(statement.executeUpdate(getSQLContent()));
} else {
statement.executeUpdate(getSQLContent(), Statement.RETURN_GENERATED_KEYS);
try (ResultSet resultSet = statement.getGeneratedKeys()) {
return resultSet.next() ? resultSet.getObject(1, numberClass) : numberClass.cast(0);
}
}
}
}
}
@Override
public UpdateAction<T> returnGeneratedKey() {
this.returnGeneratedKeys = true;
return this;
}
@Override
public <N extends Number> UpdateAction<N> returnGeneratedKey(Class<N> keyTypeClass) {
return new UpdateActionImpl<>(getManager(), keyTypeClass, getActionUUID(), getSQLContent()).returnGeneratedKey();
}
}
@@ -1,7 +1,7 @@
package cc.carm.lib.easysql.action.query;
import cc.carm.lib.easysql.api.action.query.PreparedQueryAction;
import cc.carm.lib.easysql.manager.SQLManagerImpl;
import cc.carm.lib.easysql.api.action.base.PreparedQueryAction;
import cc.carm.lib.easysql.SQLManagerImpl;
import cc.carm.lib.easysql.query.SQLQueryImpl;
import cc.carm.lib.easysql.util.StatementUtil;
import org.jetbrains.annotations.NotNull;
@@ -11,26 +11,27 @@ import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
public class PreparedQueryActionImpl extends QueryActionImpl implements PreparedQueryAction {
public class PreparedSQLQueryActionImpl extends SQLQueryActionImpl implements PreparedQueryAction {
Consumer<PreparedStatement> handler;
Object[] params;
public PreparedQueryActionImpl(@NotNull SQLManagerImpl manager, @NotNull String sql) {
public PreparedSQLQueryActionImpl(@NotNull SQLManagerImpl manager, @NotNull String sql) {
super(manager, sql);
}
@Override
public PreparedQueryActionImpl setParams(@Nullable Object... params) {
public @NotNull PreparedSQLQueryActionImpl setParams(@Nullable Object... params) {
this.params = params;
return this;
}
@Override
public PreparedQueryActionImpl setParams(@Nullable Iterable<Object> params) {
public PreparedSQLQueryActionImpl setParams(@Nullable Iterable<Object> params) {
if (params == null) {
return setParams((Object[]) null);
} else {
@@ -41,7 +42,7 @@ public class PreparedQueryActionImpl extends QueryActionImpl implements Prepared
}
@Override
public PreparedQueryActionImpl handleStatement(@Nullable Consumer<PreparedStatement> statement) {
public PreparedSQLQueryActionImpl handleStatement(@Nullable Consumer<PreparedStatement> statement) {
this.handler = statement;
return this;
}
@@ -49,7 +50,7 @@ public class PreparedQueryActionImpl extends QueryActionImpl implements Prepared
@Override
public @NotNull SQLQueryImpl execute() throws SQLException {
outputDebugMessage();
debugMessage(Collections.singletonList(params));
Connection connection = getManager().getConnection();
PreparedStatement preparedStatement;
@@ -66,15 +67,12 @@ public class PreparedQueryActionImpl extends QueryActionImpl implements Prepared
}
try {
long executeTime = System.currentTimeMillis();
SQLQueryImpl query = new SQLQueryImpl(
getManager(), this,
connection, preparedStatement,
preparedStatement.executeQuery(),
executeTime
preparedStatement.executeQuery()
);
getManager().getActiveQuery().put(getActionUUID(), query);
getManager().getActiveQueries().put(getActionUUID(), query);
return query;
} catch (SQLException exception) {
preparedStatement.close();
@@ -2,25 +2,27 @@ package cc.carm.lib.easysql.action.query;
import cc.carm.lib.easysql.action.AbstractSQLAction;
import cc.carm.lib.easysql.api.SQLQuery;
import cc.carm.lib.easysql.api.action.query.QueryAction;
import cc.carm.lib.easysql.api.action.query.SQLQueryAction;
import cc.carm.lib.easysql.api.function.SQLExceptionHandler;
import cc.carm.lib.easysql.api.function.SQLHandler;
import cc.carm.lib.easysql.manager.SQLManagerImpl;
import cc.carm.lib.easysql.SQLManagerImpl;
import cc.carm.lib.easysql.query.SQLQueryImpl;
import org.jetbrains.annotations.NotNull;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
public class QueryActionImpl extends AbstractSQLAction<SQLQuery> implements QueryAction {
public class SQLQueryActionImpl extends AbstractSQLAction<SQLQuery> implements SQLQueryAction<SQLQueryActionImpl> {
public QueryActionImpl(@NotNull SQLManagerImpl manager, @NotNull String sql) {
public SQLQueryActionImpl(@NotNull SQLManagerImpl manager, @NotNull String sql) {
super(manager, sql);
}
@Override
public @NotNull SQLQueryImpl execute() throws SQLException {
debugMessage(new ArrayList<>());
Connection connection = getManager().getConnection();
Statement statement;
@@ -32,16 +34,13 @@ public class QueryActionImpl extends AbstractSQLAction<SQLQuery> implements Quer
throw ex;
}
outputDebugMessage();
try {
long executeTime = System.currentTimeMillis();
SQLQueryImpl query = new SQLQueryImpl(
getManager(), this,
connection, statement,
statement.executeQuery(getSQLContent()),
executeTime
statement.executeQuery(getSQLContent())
);
getManager().getActiveQuery().put(getActionUUID(), query);
getManager().getActiveQueries().put(getActionUUID(), query);
return query;
} catch (SQLException exception) {
@@ -54,10 +53,12 @@ public class QueryActionImpl extends AbstractSQLAction<SQLQuery> implements Quer
@Override
public void executeAsync(SQLHandler<SQLQuery> success, SQLExceptionHandler failure) {
try (SQLQueryImpl query = execute()) {
if (success != null) success.accept(query);
} catch (SQLException exception) {
handleException(failure, exception);
}
getManager().getExecutorPool().submit(() -> {
try (SQLQueryImpl query = execute()) {
if (success != null) success.accept(query);
} catch (SQLException exception) {
handleException(failure, exception);
}
});
}
}
@@ -1,7 +1,7 @@
package cc.carm.lib.easysql.builder;
import cc.carm.lib.easysql.SQLManagerImpl;
import cc.carm.lib.easysql.api.SQLBuilder;
import cc.carm.lib.easysql.manager.SQLManagerImpl;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
@@ -20,4 +20,5 @@ public abstract class AbstractSQLBuilder implements SQLBuilder {
public @NotNull SQLManagerImpl getManager() {
return this.sqlManager;
}
}
@@ -1,9 +1,8 @@
package cc.carm.lib.easysql.builder.impl;
import cc.carm.lib.easysql.api.SQLAction;
import cc.carm.lib.easysql.api.builder.ConditionalBuilder;
import cc.carm.lib.easysql.builder.AbstractSQLBuilder;
import cc.carm.lib.easysql.manager.SQLManagerImpl;
import cc.carm.lib.easysql.SQLManagerImpl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -27,7 +26,7 @@ public abstract class AbstractConditionalBuilder<B extends ConditionalBuilder<B,
protected abstract B getThis();
@Override
public B setConditions(@Nullable String condition) {
public B where(@Nullable String condition) {
this.conditionSQLs = new ArrayList<>();
this.conditionParams = new ArrayList<>();
if (condition != null) this.conditionSQLs.add(condition);
@@ -35,7 +34,7 @@ public abstract class AbstractConditionalBuilder<B extends ConditionalBuilder<B,
}
@Override
public B setConditions(
public B where(
LinkedHashMap<@NotNull String, @Nullable Object> conditions
) {
conditions.forEach(this::addCondition);
@@ -48,6 +47,16 @@ public abstract class AbstractConditionalBuilder<B extends ConditionalBuilder<B,
return getThis();
}
@Override
public B addCondition(@NotNull String columnName, @Nullable Object queryValue) {
Objects.requireNonNull(columnName, "columnName could not be null");
if (queryValue == null) {
return addCondition(withBackQuote(columnName) + " IS NULL");
} else {
return addCondition(columnName, "=", queryValue);
}
}
@Override
public B addCondition(
@NotNull String columnName, @NotNull String operator, @Nullable Object queryValue
@@ -109,7 +118,7 @@ public abstract class AbstractConditionalBuilder<B extends ConditionalBuilder<B,
@Override
public B setLimit(int limit) {
public B limit(int limit) {
this.limit = limit;
return getThis();
}
@@ -1,10 +1,9 @@
package cc.carm.lib.easysql.builder.impl;
import cc.carm.lib.easysql.action.PreparedSQLUpdateActionImpl;
import cc.carm.lib.easysql.api.SQLAction;
import cc.carm.lib.easysql.api.action.PreparedSQLUpdateAction;
import cc.carm.lib.easysql.api.action.base.PreparedUpdateAction;
import cc.carm.lib.easysql.api.builder.DeleteBuilder;
import cc.carm.lib.easysql.manager.SQLManagerImpl;
import cc.carm.lib.easysql.SQLManagerImpl;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
@@ -24,7 +23,7 @@ public class DeleteBuilderImpl
}
@Override
public PreparedSQLUpdateAction build() {
public PreparedUpdateAction<Integer> build() {
StringBuilder sqlBuilder = new StringBuilder();
@@ -33,9 +32,9 @@ public class DeleteBuilderImpl
if (hasConditions()) sqlBuilder.append(" ").append(buildConditionSQL());
if (limit > 0) sqlBuilder.append(" ").append(buildLimitSQL());
return new PreparedSQLUpdateActionImpl(
getManager(), sqlBuilder.toString(),
hasConditionParams() ? getConditionParams() : null
return new PreparedSQLUpdateActionImpl<>(
getManager(), Integer.class, sqlBuilder.toString(),
(hasConditionParams() ? getConditionParams() : null)
);
}
@@ -1,9 +1,8 @@
package cc.carm.lib.easysql.builder.impl;
import cc.carm.lib.easysql.api.SQLAction;
import cc.carm.lib.easysql.api.builder.InsertBuilder;
import cc.carm.lib.easysql.builder.AbstractSQLBuilder;
import cc.carm.lib.easysql.manager.SQLManagerImpl;
import cc.carm.lib.easysql.SQLManagerImpl;
import org.jetbrains.annotations.NotNull;
import java.util.Iterator;
@@ -1,13 +1,13 @@
package cc.carm.lib.easysql.builder.impl;
import cc.carm.lib.easysql.action.query.PreparedQueryActionImpl;
import cc.carm.lib.easysql.action.query.QueryActionImpl;
import cc.carm.lib.easysql.api.action.query.PreparedQueryAction;
import cc.carm.lib.easysql.api.action.query.QueryAction;
import cc.carm.lib.easysql.action.query.PreparedSQLQueryActionImpl;
import cc.carm.lib.easysql.action.query.SQLQueryActionImpl;
import cc.carm.lib.easysql.api.action.base.PreparedQueryAction;
import cc.carm.lib.easysql.api.action.base.QueryAction;
import cc.carm.lib.easysql.api.builder.QueryBuilder;
import cc.carm.lib.easysql.api.builder.TableQueryBuilder;
import cc.carm.lib.easysql.builder.AbstractSQLBuilder;
import cc.carm.lib.easysql.manager.SQLManagerImpl;
import cc.carm.lib.easysql.SQLManagerImpl;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
@@ -21,17 +21,17 @@ public class QueryBuilderImpl extends AbstractSQLBuilder implements QueryBuilder
@Deprecated
public QueryAction withSQL(@NotNull String sql) {
Objects.requireNonNull(sql, "sql could not be null");
return new QueryActionImpl(getManager(), sql);
return new SQLQueryActionImpl(getManager(), sql);
}
@Override
public PreparedQueryAction withPreparedSQL(@NotNull String sql) {
Objects.requireNonNull(sql, "sql could not be null");
return new PreparedQueryActionImpl(getManager(), sql);
return new PreparedSQLQueryActionImpl(getManager(), sql);
}
@Override
public TableQueryBuilder inTable(@NotNull String tableName) {
public TableQueryBuilder fromTable(@NotNull String tableName) {
Objects.requireNonNull(tableName, "tableName could not be null");
return new TableQueryBuilderImpl(getManager(), tableName);
}
@@ -1,9 +1,8 @@
package cc.carm.lib.easysql.builder.impl;
import cc.carm.lib.easysql.api.SQLAction;
import cc.carm.lib.easysql.api.builder.ReplaceBuilder;
import cc.carm.lib.easysql.builder.AbstractSQLBuilder;
import cc.carm.lib.easysql.manager.SQLManagerImpl;
import cc.carm.lib.easysql.SQLManagerImpl;
import org.jetbrains.annotations.NotNull;
import java.util.List;
@@ -1,11 +1,10 @@
package cc.carm.lib.easysql.builder.impl;
import cc.carm.lib.easysql.action.SQLUpdateActionImpl;
import cc.carm.lib.easysql.api.SQLAction;
import cc.carm.lib.easysql.action.UpdateActionImpl;
import cc.carm.lib.easysql.api.builder.TableAlterBuilder;
import cc.carm.lib.easysql.api.enums.IndexType;
import cc.carm.lib.easysql.builder.AbstractSQLBuilder;
import cc.carm.lib.easysql.manager.SQLManagerImpl;
import cc.carm.lib.easysql.SQLManagerImpl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -30,24 +29,18 @@ public class TableAlterBuilderImpl extends AbstractSQLBuilder implements TableAl
@Override
public SQLAction<Integer> renameTo(@NotNull String newTableName) {
Objects.requireNonNull(newTableName, "table name could not be null");
return new SQLUpdateActionImpl(getManager(),
"ALTER TABLE " + withBackQuote(tableName) + " RENAME TO " + withBackQuote(newTableName)
);
return createAction("ALTER TABLE " + withBackQuote(tableName) + " RENAME TO " + withBackQuote(newTableName));
}
@Override
public SQLAction<Integer> changeComment(@NotNull String newTableComment) {
Objects.requireNonNull(newTableComment, "table comment could not be null");
return new SQLUpdateActionImpl(getManager(),
"ALTER TABLE " + withBackQuote(getTableName()) + " COMMENT " + withQuote(newTableComment)
);
return createAction("ALTER TABLE " + withBackQuote(getTableName()) + " COMMENT " + withQuote(newTableComment));
}
@Override
public SQLAction<Integer> setAutoIncrementIndex(int index) {
return new SQLUpdateActionImpl(getManager(),
"ALTER TABLE " + withBackQuote(getTableName()) + " AUTO_INCREMENT=" + index
);
return createAction("ALTER TABLE " + withBackQuote(getTableName()) + " AUTO_INCREMENT=" + index);
}
@Override
@@ -147,7 +140,7 @@ public class TableAlterBuilderImpl extends AbstractSQLBuilder implements TableAl
);
}
private SQLUpdateActionImpl createAction(@NotNull String sql) {
return new SQLUpdateActionImpl(getManager(), sql);
private UpdateActionImpl<Integer> createAction(@NotNull String sql) {
return new UpdateActionImpl<>(getManager(), Integer.class, sql);
}
}
@@ -1,13 +1,13 @@
package cc.carm.lib.easysql.builder.impl;
import cc.carm.lib.easysql.action.SQLUpdateActionImpl;
import cc.carm.lib.easysql.api.action.SQLUpdateAction;
import cc.carm.lib.easysql.action.UpdateActionImpl;
import cc.carm.lib.easysql.api.action.base.UpdateAction;
import cc.carm.lib.easysql.api.builder.TableCreateBuilder;
import cc.carm.lib.easysql.api.enums.ForeignKeyRule;
import cc.carm.lib.easysql.api.enums.IndexType;
import cc.carm.lib.easysql.api.enums.NumberType;
import cc.carm.lib.easysql.builder.AbstractSQLBuilder;
import cc.carm.lib.easysql.manager.SQLManagerImpl;
import cc.carm.lib.easysql.SQLManagerImpl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -75,7 +75,7 @@ public class TableCreateBuilderImpl extends AbstractSQLBuilder implements TableC
}
@Override
public SQLUpdateAction build() {
public UpdateAction<Integer> build() {
StringBuilder createSQL = new StringBuilder();
createSQL.append("CREATE TABLE IF NOT EXISTS ").append(withBackQuote(tableName));
createSQL.append("(");
@@ -94,7 +94,7 @@ public class TableCreateBuilderImpl extends AbstractSQLBuilder implements TableC
createSQL.append(" COMMENT ").append(withQuote(tableComment));
}
return new SQLUpdateActionImpl(getManager(), createSQL.toString());
return new UpdateActionImpl<>(getManager(), Integer.class, createSQL.toString());
}
@Override
@@ -0,0 +1,74 @@
package cc.carm.lib.easysql.builder.impl;
import cc.carm.lib.easysql.api.builder.TableMetadataBuilder;
import cc.carm.lib.easysql.api.function.SQLBiFunction;
import cc.carm.lib.easysql.api.function.SQLFunction;
import cc.carm.lib.easysql.builder.AbstractSQLBuilder;
import cc.carm.lib.easysql.SQLManagerImpl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
public class TableMetadataBuilderImpl
extends AbstractSQLBuilder
implements TableMetadataBuilder {
protected final @NotNull String tablePattern;
public TableMetadataBuilderImpl(@NotNull SQLManagerImpl manager, @NotNull String tablePattern) {
super(manager);
this.tablePattern = tablePattern;
}
@Override
public CompletableFuture<Boolean> validateExist() {
return validate((meta, conn) -> meta.getTables(conn.getCatalog(), conn.getSchema(), tablePattern.toUpperCase(), new String[]{"TABLE"}));
}
@Override
public <R> CompletableFuture<R> fetchColumns(@Nullable String columnPattern,
@NotNull SQLFunction<ResultSet, R> reader) {
return getManager().fetchMetadata((meta, conn) -> meta.getColumns(
conn.getCatalog(), conn.getSchema(), tablePattern.toUpperCase(),
Optional.ofNullable(columnPattern).map(String::toUpperCase).orElse("%")
), reader);
}
@Override
public CompletableFuture<Boolean> isColumnExists(@NotNull String columnPattern) {
return validate((meta, conn) -> meta.getColumns(
conn.getCatalog(), conn.getSchema(),
tablePattern.toUpperCase(), columnPattern.toUpperCase()
));
}
@Override
public CompletableFuture<Set<String>> listColumns(@Nullable String columnPattern) {
return fetchColumns(columnPattern, (rs) -> {
Set<String> data = new LinkedHashSet<>();
while (rs.next()) {
data.add(rs.getString("COLUMN_NAME"));
}
return Collections.unmodifiableSet(data);
});
}
/**
* fast validate EXISTS.
*
* @param supplier supplier to get result set
* @return result future
*/
private CompletableFuture<Boolean> validate(SQLBiFunction<DatabaseMetaData, Connection, ResultSet> supplier) {
return getManager().fetchMetadata(supplier, ResultSet::next);
}
}
@@ -1,9 +1,9 @@
package cc.carm.lib.easysql.builder.impl;
import cc.carm.lib.easysql.action.query.PreparedQueryActionImpl;
import cc.carm.lib.easysql.api.action.query.PreparedQueryAction;
import cc.carm.lib.easysql.action.query.PreparedSQLQueryActionImpl;
import cc.carm.lib.easysql.api.action.base.PreparedQueryAction;
import cc.carm.lib.easysql.api.builder.TableQueryBuilder;
import cc.carm.lib.easysql.manager.SQLManagerImpl;
import cc.carm.lib.easysql.SQLManagerImpl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -30,7 +30,7 @@ public class TableQueryBuilderImpl
}
@Override
public PreparedQueryActionImpl build() {
public PreparedSQLQueryActionImpl build() {
StringBuilder sqlBuilder = new StringBuilder();
sqlBuilder.append("SELECT").append(" ");
if (columns == null || columns.length < 1) {
@@ -58,7 +58,7 @@ public class TableQueryBuilderImpl
}
return new PreparedQueryActionImpl(getManager(), sqlBuilder.toString())
return new PreparedSQLQueryActionImpl(getManager(), sqlBuilder.toString())
.setParams(hasConditionParams() ? getConditionParams() : null);
}
@@ -68,7 +68,7 @@ public class TableQueryBuilderImpl
}
@Override
public TableQueryBuilderImpl selectColumns(@NotNull String... columnNames) {
public TableQueryBuilderImpl select(@NotNull String... columnNames) {
Objects.requireNonNull(columnNames, "columnNames could not be null");
this.columns = columnNames;
return this;
@@ -82,7 +82,7 @@ public class TableQueryBuilderImpl
}
@Override
public TableQueryBuilder setPageLimit(int start, int end) {
public TableQueryBuilder limit(int start, int end) {
this.pageLimit = new int[]{start, end};
return this;
}
@@ -1,10 +1,9 @@
package cc.carm.lib.easysql.builder.impl;
import cc.carm.lib.easysql.action.PreparedSQLUpdateActionImpl;
import cc.carm.lib.easysql.api.SQLAction;
import cc.carm.lib.easysql.api.action.PreparedSQLUpdateAction;
import cc.carm.lib.easysql.api.action.base.PreparedUpdateAction;
import cc.carm.lib.easysql.api.builder.UpdateBuilder;
import cc.carm.lib.easysql.manager.SQLManagerImpl;
import cc.carm.lib.easysql.SQLManagerImpl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -27,7 +26,7 @@ public class UpdateBuilderImpl
}
@Override
public PreparedSQLUpdateAction build() {
public PreparedUpdateAction<Integer> build() {
StringBuilder sqlBuilder = new StringBuilder();
@@ -47,7 +46,7 @@ public class UpdateBuilderImpl
if (limit > 0) sqlBuilder.append(" ").append(buildLimitSQL());
return new PreparedSQLUpdateActionImpl(getManager(), sqlBuilder.toString(), allParams);
return new PreparedSQLUpdateActionImpl<>(getManager(), Integer.class, sqlBuilder.toString(), allParams);
}
@Override
@@ -56,20 +55,20 @@ public class UpdateBuilderImpl
}
@Override
public UpdateBuilder addColumnValue(@NotNull String columnName, Object columnValue) {
public UpdateBuilder set(@NotNull String columnName, Object columnValue) {
Objects.requireNonNull(columnName, "columnName could not be null");
this.columnData.put(columnName, columnValue);
return this;
}
@Override
public UpdateBuilder setColumnValues(LinkedHashMap<String, Object> columnData) {
public UpdateBuilder setAll(LinkedHashMap<String, Object> columnData) {
this.columnData = columnData;
return this;
}
@Override
public UpdateBuilder setColumnValues(@NotNull String[] columnNames, @Nullable Object[] columnValues) {
public UpdateBuilder setAll(@NotNull String[] columnNames, @Nullable Object[] columnValues) {
Objects.requireNonNull(columnNames, "columnName could not be null");
if (columnNames.length != columnValues.length) {
throw new RuntimeException("columnNames are not match with columnValues");
@@ -78,7 +77,7 @@ public class UpdateBuilderImpl
for (int i = 0; i < columnNames.length; i++) {
columnData.put(columnNames[i], columnValues[i]);
}
return setColumnValues(columnData);
return setAll(columnData);
}
@@ -1,210 +0,0 @@
package cc.carm.lib.easysql.manager;
import cc.carm.lib.easysql.action.PreparedSQLBatchUpdateActionImpl;
import cc.carm.lib.easysql.action.PreparedSQLUpdateActionImpl;
import cc.carm.lib.easysql.action.SQLUpdateActionImpl;
import cc.carm.lib.easysql.action.SQLUpdateBatchActionImpl;
import cc.carm.lib.easysql.api.SQLManager;
import cc.carm.lib.easysql.api.SQLQuery;
import cc.carm.lib.easysql.api.action.PreparedSQLUpdateAction;
import cc.carm.lib.easysql.api.action.PreparedSQLUpdateBatchAction;
import cc.carm.lib.easysql.api.action.SQLUpdateBatchAction;
import cc.carm.lib.easysql.api.builder.*;
import cc.carm.lib.easysql.api.function.SQLExceptionHandler;
import cc.carm.lib.easysql.builder.impl.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Supplier;
import java.util.logging.Logger;
public class SQLManagerImpl implements SQLManager {
private final Logger LOGGER;
private final DataSource dataSource;
private final ConcurrentHashMap<UUID, SQLQuery> activeQuery = new ConcurrentHashMap<>();
protected ExecutorService executorPool;
@NotNull Supplier<Boolean> debugMode = () -> Boolean.FALSE;
@NotNull SQLExceptionHandler exceptionHandler;
public SQLManagerImpl(@NotNull DataSource dataSource) {
this(dataSource, null);
}
public SQLManagerImpl(@NotNull DataSource dataSource, @Nullable String name) {
String managerName = "SQLManager" + (name != null ? "#" + name : "");
this.LOGGER = Logger.getLogger(managerName);
this.dataSource = dataSource;
this.executorPool = Executors.newFixedThreadPool(3, r -> {
Thread thread = new Thread(r, managerName);
thread.setDaemon(true);
return thread;
});
this.exceptionHandler = SQLExceptionHandler.detailed(getLogger());
}
@Override
public boolean isDebugMode() {
return this.debugMode.get();
}
@Override
public void setDebugMode(@NotNull Supplier<@NotNull Boolean> debugMode) {
this.debugMode = debugMode;
}
public void debug(String msg) {
if (isDebugMode()) getLogger().info("[DEBUG] " + msg);
}
@Override
public Logger getLogger() {
return LOGGER;
}
public ExecutorService getExecutorPool() {
return executorPool;
}
@Override
public @NotNull DataSource getDataSource() {
return this.dataSource;
}
@Override
public @NotNull Connection getConnection() throws SQLException {
return getDataSource().getConnection();
}
@Override
public @NotNull Map<UUID, SQLQuery> getActiveQuery() {
return this.activeQuery;
}
@Override
public @NotNull SQLExceptionHandler getExceptionHandler() {
return this.exceptionHandler;
}
@Override
public void setExceptionHandler(@Nullable SQLExceptionHandler handler) {
if (handler == null) this.exceptionHandler = SQLExceptionHandler.detailed(getLogger());
else this.exceptionHandler = handler;
}
@Override
public Integer executeSQL(String sql) {
return new SQLUpdateActionImpl(this, sql).execute(null);
}
@Override
public Integer executeSQL(String sql, Object[] params) {
return new PreparedSQLUpdateActionImpl(this, sql, params).execute(null);
}
@Override
public List<Integer> executeSQLBatch(String sql, Iterable<Object[]> paramsBatch) {
return new PreparedSQLBatchUpdateActionImpl(this, sql)
.setAllParams(paramsBatch)
.execute(null);
}
@Override
public List<Integer> executeSQLBatch(@NotNull String sql, String... moreSQL) {
SQLUpdateBatchAction action = new SQLUpdateBatchActionImpl(this, sql);
if (moreSQL != null && moreSQL.length > 0) {
Arrays.stream(moreSQL).forEach(action::addBatch);
}
return action.execute(null);
}
@Override
public @Nullable List<Integer> executeSQLBatch(@NotNull Iterable<String> sqlBatch) {
Iterator<String> iterator = sqlBatch.iterator();
if (!iterator.hasNext()) return null; // PLEASE GIVE IT SOMETHING
SQLUpdateBatchAction action = new SQLUpdateBatchActionImpl(this, iterator.next());
while (iterator.hasNext()) {
action.addBatch(iterator.next());
}
return action.execute(null);
}
@Override
public TableCreateBuilder createTable(@NotNull String tableName) {
return new TableCreateBuilderImpl(this, tableName);
}
@Override
public TableAlterBuilder alterTable(@NotNull String tableName) {
return new TableAlterBuilderImpl(this, tableName);
}
@Override
public QueryBuilder createQuery() {
return new QueryBuilderImpl(this);
}
@Override
public InsertBuilder<PreparedSQLUpdateBatchAction> createInsertBatch(@NotNull String tableName) {
return new InsertBuilderImpl<PreparedSQLUpdateBatchAction>(this, tableName) {
@Override
public PreparedSQLUpdateBatchAction setColumnNames(List<String> columnNames) {
return new PreparedSQLBatchUpdateActionImpl(getManager(), buildSQL(getTableName(), columnNames));
}
};
}
@Override
public InsertBuilder<PreparedSQLUpdateAction> createInsert(@NotNull String tableName) {
return new InsertBuilderImpl<PreparedSQLUpdateAction>(this, tableName) {
@Override
public PreparedSQLUpdateAction setColumnNames(List<String> columnNames) {
return new PreparedSQLUpdateActionImpl(getManager(), buildSQL(getTableName(), columnNames));
}
};
}
@Override
public ReplaceBuilder<PreparedSQLUpdateBatchAction> createReplaceBatch(@NotNull String tableName) {
return new ReplaceBuilderImpl<PreparedSQLUpdateBatchAction>(this, tableName) {
@Override
public PreparedSQLUpdateBatchAction setColumnNames(List<String> columnNames) {
return new PreparedSQLBatchUpdateActionImpl(getManager(), buildSQL(getTableName(), columnNames));
}
};
}
@Override
public ReplaceBuilder<PreparedSQLUpdateAction> createReplace(@NotNull String tableName) {
return new ReplaceBuilderImpl<PreparedSQLUpdateAction>(this, tableName) {
@Override
public PreparedSQLUpdateAction setColumnNames(List<String> columnNames) {
return new PreparedSQLUpdateActionImpl(getManager(), buildSQL(getTableName(), columnNames));
}
};
}
@Override
public UpdateBuilder createUpdate(@NotNull String tableName) {
return new UpdateBuilderImpl(this, tableName);
}
@Override
public DeleteBuilder createDelete(@NotNull String tableName) {
return new DeleteBuilderImpl(this, tableName);
}
}
@@ -1,33 +1,34 @@
package cc.carm.lib.easysql.query;
import cc.carm.lib.easysql.action.query.QueryActionImpl;
import cc.carm.lib.easysql.action.query.SQLQueryActionImpl;
import cc.carm.lib.easysql.api.SQLQuery;
import cc.carm.lib.easysql.manager.SQLManagerImpl;
import cc.carm.lib.easysql.SQLManagerImpl;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.concurrent.TimeUnit;
public class SQLQueryImpl implements SQLQuery {
protected final long executeTime;
protected final SQLManagerImpl sqlManager;
final Connection connection;
final Statement statement;
final ResultSet resultSet;
protected QueryActionImpl queryAction;
protected final Connection connection;
protected final Statement statement;
protected final ResultSet resultSet;
protected SQLQueryActionImpl queryAction;
public SQLQueryImpl(
SQLManagerImpl sqlManager, QueryActionImpl queryAction,
SQLManagerImpl sqlManager, SQLQueryActionImpl queryAction,
Connection connection, Statement statement, ResultSet resultSet
) {
this(sqlManager, queryAction, connection, statement, resultSet, System.currentTimeMillis());
this(sqlManager, queryAction, connection, statement, resultSet, System.nanoTime());
}
public SQLQueryImpl(
SQLManagerImpl sqlManager, QueryActionImpl queryAction,
SQLManagerImpl sqlManager, SQLQueryActionImpl queryAction,
Connection connection, Statement statement, ResultSet resultSet,
long executeTime
) {
@@ -40,8 +41,8 @@ public class SQLQueryImpl implements SQLQuery {
}
@Override
public long getExecuteTime() {
return this.executeTime;
public long getExecuteTime(TimeUnit timeUnit) {
return timeUnit.convert(this.executeTime, TimeUnit.NANOSECONDS);
}
@Override
@@ -50,7 +51,7 @@ public class SQLQueryImpl implements SQLQuery {
}
@Override
public QueryActionImpl getAction() {
public SQLQueryActionImpl getAction() {
return this.queryAction;
}
@@ -71,10 +72,14 @@ public class SQLQueryImpl implements SQLQuery {
if (getStatement() != null && !getStatement().isClosed()) getStatement().close();
if (getConnection() != null && !getConnection().isClosed()) getConnection().close();
getManager().debug("#" + getAction().getShortID() +
" -> finished after " + (System.currentTimeMillis() - getExecuteTime()) + " ms."
);
getManager().getActiveQuery().remove(getAction().getActionUUID());
if (getManager().isDebugMode()) {
try {
getManager().getDebugHandler().afterQuery(this, getExecuteTime(TimeUnit.NANOSECONDS), System.nanoTime());
} catch (Exception ex) {
ex.printStackTrace();
}
}
getManager().getActiveQueries().remove(getAction().getActionUUID());
} catch (SQLException e) {
getAction().handleException(getAction().defaultExceptionHandler(), e);
}
+26 -12
View File
@@ -5,11 +5,13 @@
<modelVersion>4.0.0</modelVersion>
<properties>
<java.version>8</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<jdk.version>8</jdk.version>
<maven.compiler.source>${jdk.version}</maven.compiler.source>
<maven.compiler.target>${jdk.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<sonar.organization>carmjos</sonar.organization>
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
</properties>
@@ -17,7 +19,7 @@
<groupId>cc.carm.lib</groupId>
<artifactId>easysql-parent</artifactId>
<packaging>pom</packaging>
<version>0.3.9</version>
<version>0.4.6</version>
<modules>
<module>api</module>
@@ -26,7 +28,7 @@
<module>with-pool/beecp</module>
<module>with-pool/hikaricp</module>
<module>example/demo</module>
<module>demo</module>
</modules>
<name>EasySQL</name>
@@ -94,14 +96,12 @@
</repositories>
<distributionManagement>
<downloadUrl>https://github.com/CarmJos/EasySQL/releases</downloadUrl>
<site>
<id>easysql-javadoc</id>
<name>EasySQL JavaDoc (on Github Pages)</name>
<url>https://CarmJos.github.io/EasySQL</url>
</site>
</distributionManagement>
<dependencies>
@@ -169,7 +169,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.3.2</version>
<version>3.4.1</version>
<configuration>
<classifier>javadoc</classifier>
<detectJavaApiLink>false</detectJavaApiLink>
@@ -198,8 +198,8 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
<encoding>UTF-8</encoding>
<compilerArgument>-parameters</compilerArgument>
</configuration>
@@ -208,7 +208,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version>
<version>3.3.0</version>
</plugin>
<plugin>
@@ -228,7 +228,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.3.0</version>
<version>3.4.0</version>
<executions>
<execution>
<phase>package</phase>
@@ -302,6 +302,20 @@
</distributionManagement>
</profile>
<profile>
<id>local</id>
<distributionManagement>
<snapshotRepository>
<id>localRepository</id>
<url>file:${user.home}/local-deploy/</url>
</snapshotRepository>
<repository>
<id>localRepository</id>
<url>file:${user.home}/local-deploy/</url>
</repository>
</distributionManagement>
</profile>
</profiles>
</project>
+11 -5
View File
@@ -5,14 +5,14 @@
<parent>
<artifactId>easysql-parent</artifactId>
<groupId>cc.carm.lib</groupId>
<version>0.3.9</version>
<version>0.4.6</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<properties>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<maven.compiler.source>${jdk.version}</maven.compiler.source>
<maven.compiler.target>${jdk.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
</properties>
@@ -40,6 +40,12 @@
<license>
<name>The MIT License</name>
<url>https://opensource.org/licenses/MIT</url>
<comments>EasySQL的基础源代码采用MIT开源协议。</comments>
</license>
<license>
<name>GNU Lesser General Public License v2.1</name>
<url>https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html</url>
<comments>该版本打包了BeeCP,因此相关代码继续遵循LGPL协议。</comments>
</license>
</licenses>
@@ -73,7 +79,7 @@
<!--项目地址 https://github.com/Chris2018998/BeeCP -->
<groupId>com.github.chris2018998</groupId>
<artifactId>beecp</artifactId>
<version>3.3.5</version>
<version>3.3.8</version>
<optional>true</optional>
<scope>compile</scope>
</dependency>
@@ -101,7 +107,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.3.0</version>
<version>3.4.0</version>
<executions>
<execution>
<phase>package</phase>
@@ -1,9 +1,7 @@
package cc.carm.lib.easysql;
import cc.carm.lib.easysql.api.SQLManager;
import cc.carm.lib.easysql.api.SQLQuery;
import cc.carm.lib.easysql.api.util.TimeDateUtils;
import cc.carm.lib.easysql.manager.SQLManagerImpl;
import cn.beecp.BeeDataSource;
import cn.beecp.BeeDataSourceConfig;
import org.jetbrains.annotations.NotNull;
@@ -24,11 +22,11 @@ public class EasySQL {
public static void shutdownManager(SQLManager manager, boolean forceClose, boolean outputActiveQuery) {
if (!manager.getActiveQuery().isEmpty()) {
manager.getLogger().severe("There are " + manager.getActiveQuery().size() + " connections still running");
manager.getLogger().warn("There are " + manager.getActiveQuery().size() + " connections still running");
for (SQLQuery value : manager.getActiveQuery().values()) {
if (outputActiveQuery) {
manager.getLogger().severe(String.format("#%s -> %s", value.getAction().getShortID(), value.getSQLContent()));
manager.getLogger().severe(String.format("- execute at %s", TimeDateUtils.getTimeString(value.getExecuteTime())));
manager.getLogger().warn(String.format("#%s -> %s", value.getAction().getShortID(), value.getSQLContent()));
manager.getLogger().warn(String.format("- execute at %s", TimeDateUtils.getTimeString(value.getExecuteTime())));
}
if (forceClose) value.close();
}
+5 -4
View File
@@ -5,14 +5,14 @@
<parent>
<artifactId>easysql-parent</artifactId>
<groupId>cc.carm.lib</groupId>
<version>0.3.9</version>
<version>0.4.6</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<properties>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<maven.compiler.source>${jdk.version}</maven.compiler.source>
<maven.compiler.target>${jdk.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
</properties>
@@ -39,6 +39,7 @@
<license>
<name>The MIT License</name>
<url>https://opensource.org/licenses/MIT</url>
<comments>EasySQL与HikariCP均采用MIT开源协议。</comments>
</license>
</licenses>
@@ -101,7 +102,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.3.0</version>
<version>3.4.0</version>
<executions>
<execution>
<phase>package</phase>
@@ -1,9 +1,7 @@
package cc.carm.lib.easysql;
import cc.carm.lib.easysql.api.SQLManager;
import cc.carm.lib.easysql.api.SQLQuery;
import cc.carm.lib.easysql.api.util.TimeDateUtils;
import cc.carm.lib.easysql.manager.SQLManagerImpl;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.jetbrains.annotations.NotNull;
@@ -34,11 +32,11 @@ public class EasySQL {
public static void shutdownManager(SQLManager manager, boolean forceClose, boolean outputActiveQuery) {
if (!manager.getActiveQuery().isEmpty()) {
manager.getLogger().severe("There are " + manager.getActiveQuery().size() + " connections still running");
manager.getLogger().warn("There are " + manager.getActiveQuery().size() + " connections still running");
for (SQLQuery value : manager.getActiveQuery().values()) {
if (outputActiveQuery) {
manager.getLogger().severe(String.format("#%s -> %s", value.getAction().getShortID(), value.getSQLContent()));
manager.getLogger().severe(String.format("- execute at %s", TimeDateUtils.getTimeString(value.getExecuteTime())));
manager.getLogger().warn(String.format("#%s -> %s", value.getAction().getShortID(), value.getSQLContent()));
manager.getLogger().warn(String.format("- execute at %s", TimeDateUtils.getTimeString(value.getExecuteTime())));
}
if (forceClose) value.close();
}