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

Compare commits

...

196 Commits

Author SHA1 Message Date
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
carm 0a6c8ae1a9 [0.3.9] 版本更新
- `[R]` 修改项目结构,移除无用的 `easysql-tester` 模块, 整合相关测试到 `easysql-demo` 的`src/test` 下。
- `[U]` 移除`DefaultSQLExceptionHandler` 类,与 `SQLExceptionHandler` 接口下添加 `detailed()` 与 `silent()` 两种预设错误处理器,并支持通过 `SQLManager#setExceptionHandler()` 方法应用全局生效的默认错误处理器。
> 注意: 十分不建议使用 `silent()` 处理器为默认处理器!
2022-04-09 01:22:23 +08:00
carm f00e741035 Merge pull request #42 from CarmJos/dependabot/maven/com.github.chris2018998-beecp-3.3.5
Bump beecp from 3.3.4 to 3.3.5
2022-04-04 19:49:57 +08:00
dependabot[bot] 50c2016820 Bump beecp from 3.3.4 to 3.3.5
Bumps [beecp](https://github.com/Chris2018998/BeeCP) from 3.3.4 to 3.3.5.
- [Release notes](https://github.com/Chris2018998/BeeCP/releases)
- [Commits](https://github.com/Chris2018998/BeeCP/commits/3.3.5)

---
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-04-04 08:41:25 +00:00
carm 71b0bb98d8 Merge pull request #41 from CarmJos/dependabot/maven/org.apache.maven.plugins-maven-shade-plugin-3.3.0
Bump maven-shade-plugin from 3.2.4 to 3.3.0
2022-03-30 20:54:39 +08:00
dependabot[bot] ce3deb8f12 Bump maven-shade-plugin from 3.2.4 to 3.3.0
Bumps [maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.2.4 to 3.3.0.
- [Release notes](https://github.com/apache/maven-shade-plugin/releases)
- [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.2.4...maven-shade-plugin-3.3.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>
2022-03-30 08:38:35 +00:00
carm b5a40b0f52 Merge pull request #40 from CarmJos/dependabot/maven/com.github.chris2018998-beecp-3.3.4
Bump beecp from 3.3.3 to 3.3.4
2022-03-28 17:08:18 +08:00
dependabot[bot] ae5ca6cb23 Bump beecp from 3.3.3 to 3.3.4
Bumps [beecp](https://github.com/Chris2018998/BeeCP) from 3.3.3 to 3.3.4.
- [Release notes](https://github.com/Chris2018998/BeeCP/releases)
- [Commits](https://github.com/Chris2018998/BeeCP/commits)

---
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-03-28 08:46:21 +00:00
carm 866115db99 修改构建触发配置 2022-03-25 00:44:54 +08:00
carm 332540710d 修改构建触发配置 2022-03-25 00:44:01 +08:00
carm ebe51dd9a3 改用Format形式 2022-03-25 00:41:36 +08:00
carm 0bdfe3d556 修改文件夹名与项目配置 2022-03-25 00:40:28 +08:00
carm e60c44aaae Merge pull request #39 from CarmJos/dependabot/maven/com.github.chris2018998-beecp-3.3.3
Bump beecp from 3.3.2 to 3.3.3
2022-03-25 00:30:04 +08:00
dependabot[bot] 28f76ae50a Bump beecp from 3.3.2 to 3.3.3
Bumps [beecp](https://github.com/Chris2018998/BeeCP) from 3.3.2 to 3.3.3.
- [Release notes](https://github.com/Chris2018998/BeeCP/releases)
- [Commits](https://github.com/Chris2018998/BeeCP/compare/3.3.2...3.3.3)

---
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-03-24 08:30:30 +00:00
carm ffa0b74ccc Merge pull request #37 from CarmJos/dependabot/maven/org.apache.maven.plugins-maven-compiler-plugin-3.10.1
Bump maven-compiler-plugin from 3.10.0 to 3.10.1
2022-03-11 21:42:54 +08:00
dependabot[bot] 4b766d7794 Bump maven-compiler-plugin from 3.10.0 to 3.10.1
Bumps [maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.10.0 to 3.10.1.
- [Release notes](https://github.com/apache/maven-compiler-plugin/releases)
- [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.10.0...maven-compiler-plugin-3.10.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-11 08:33:09 +00:00
carm f12fdc9c66 Merge pull request #35 from CarmJos/dependabot/maven/org.apache.logging.log4j-log4j-slf4j-impl-2.17.2
Bump log4j-slf4j-impl from 2.17.1 to 2.17.2
2022-02-28 19:38:08 +08:00
carm 6115e6bf21 Merge pull request #36 from CarmJos/dependabot/maven/org.apache.logging.log4j-log4j-api-2.17.2
Bump log4j-api from 2.17.1 to 2.17.2
2022-02-28 19:38:00 +08:00
carm 6356c0f723 Merge pull request #34 from CarmJos/dependabot/maven/org.apache.logging.log4j-log4j-core-2.17.2
Bump log4j-core from 2.17.1 to 2.17.2
2022-02-28 19:37:51 +08:00
dependabot[bot] 5e15c3b308 Bump log4j-api from 2.17.1 to 2.17.2
Bumps log4j-api from 2.17.1 to 2.17.2.

---
updated-dependencies:
- dependency-name: org.apache.logging.log4j:log4j-api
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-28 08:37:52 +00:00
dependabot[bot] 46b21ead05 Bump log4j-slf4j-impl from 2.17.1 to 2.17.2
Bumps log4j-slf4j-impl from 2.17.1 to 2.17.2.

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-28 08:36:38 +00:00
dependabot[bot] 8a9e4b8d1c Bump log4j-core from 2.17.1 to 2.17.2
Bumps log4j-core from 2.17.1 to 2.17.2.

---
updated-dependencies:
- dependency-name: org.apache.logging.log4j:log4j-core
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-28 08:35:08 +00:00
carm f21095d08a [0.3.8] 执行相关优化
- 优化部分调用,替换制表符为空格。
- 补充残缺的 Objects.requireNonNull();
- 对于SQLQuery的auto-close额外判断ResultSet、Statement与Connection是否已关闭,避免重复关闭报错。
2022-02-21 22:59:39 +08:00
carm 6fd5988e09 [0.3.8] 执行相关优化
- 优化部分调用,替换制表符为空格。
- 补充残缺的 Objects.requireNonNull();
- 对于SQLQuery的auto-close额外判断ResultSet、Statement与Connection是否已关闭,避免重复关闭报错。
2022-02-21 20:59:11 +08:00
carm 962da8f6a1 [0.3.8] 执行相关优化
- 优化部分调用,替换制表符为空格。
- 补充残缺的 Objects.requireNonNull();
- 对于SQLQuery的auto-close额外判断ResultSet、Statement与Connection是否已关闭,避免重复关闭报错。
2022-02-21 20:56:51 +08:00
carm 68b5d071ae [0.3.8] 执行相关优化
- 优化部分调用,替换制表符为空格。
- 补充残缺的 Objects.requireNonNull();
- 对于SQLQuery的auto-close额外判断ResultSet、Statement与Connection是否已关闭,避免重复关闭报错。
2022-02-21 20:38:32 +08:00
carm 2de21a4658 Merge pull request #33 from CarmJos/dependabot/maven/com.github.chris2018998-beecp-3.3.2
Bump beecp from 3.3.1 to 3.3.2
2022-02-21 19:29:08 +08:00
dependabot[bot] 3f26c9e12e Bump beecp from 3.3.1 to 3.3.2
Bumps [beecp](https://github.com/Chris2018998/BeeCP) from 3.3.1 to 3.3.2.
- [Release notes](https://github.com/Chris2018998/BeeCP/releases)
- [Commits](https://github.com/Chris2018998/BeeCP/compare/3.3.1...3.3.2)

---
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-02-21 08:35:02 +00:00
carm 0640f625a1 [no ci]Merge pull request #32 from CarmJos/dependabot/maven/org.apache.maven.plugins-maven-javadoc-plugin-3.3.2
Bump maven-javadoc-plugin from 3.3.1 to 3.3.2
2022-02-14 16:42:26 +08:00
carm 7df8a67282 [no ci]Merge pull request #31 from CarmJos/dependabot/maven/org.apache.maven.plugins-maven-compiler-plugin-3.10.0
Bump maven-compiler-plugin from 3.9.0 to 3.10.0
2022-02-14 16:42:14 +08:00
dependabot[bot] 37becc7b29 Bump maven-javadoc-plugin from 3.3.1 to 3.3.2
Bumps [maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.3.1 to 3.3.2.
- [Release notes](https://github.com/apache/maven-javadoc-plugin/releases)
- [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.3.1...maven-javadoc-plugin-3.3.2)

---
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>
2022-02-14 08:41:30 +00:00
dependabot[bot] 5df61a70c3 Bump maven-compiler-plugin from 3.9.0 to 3.10.0
Bumps [maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.9.0 to 3.10.0.
- [Release notes](https://github.com/apache/maven-compiler-plugin/releases)
- [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.9.0...maven-compiler-plugin-3.10.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-14 08:34:40 +00:00
carm 4ce5fba6f1 添加部分 Objects.requireNonNull() 2022-02-13 05:40:46 +08:00
carm e3844493e5 [0.3.7] 修复Javadoc错误 2022-02-11 21:25:40 +08:00
carm 7772bc58d6 [0.3.7] 版本更新
- `[A]` 为 UpdateBuilder 添加 `#addColumnValue(String,Object)` 方法。
- `[A]` 补充部分Builder的JavaDoc。
2022-02-11 21:22:03 +08:00
carm 54166b4289 [0.3.7] 版本更新
- `[A]` 为 UpdateBuilder 添加 `#addColumnValue(String,Object)` 方法。
- `[A]` 补充部分Builder的JavaDoc。
2022-02-11 21:19:58 +08:00
carm bcf9d257a9 [0.3.7] 版本更新
- `[A]` 为 UpdateBuilder 添加 `#addColumnValue(String,Object)` 方法。
- `[A]` 补充部分Builder的JavaDoc。
2022-02-11 21:12:32 +08:00
carm 0efd526c75 [ci skip]添加实例项目 2022-02-10 20:49:05 +08:00
carm 22a8172490 完善帮助 2022-02-10 20:31:26 +08:00
carm 5444015b8b Merge pull request #30 from Ghost-chu/master
Documention or Story?
2022-02-10 19:48:35 +08:00
Ghost_chu 1ab23aa14f 修复修正+混淆改善 2022-02-10 18:57:21 +08:00
Ghost_chu 0f4bf90f56 文档:添加缺失的 java 标记 2022-02-10 17:48:37 +08:00
Ghost_chu 8e57305b83 添加蠢爆了的 EasySQL 使用指南 2022-02-10 17:47:04 +08:00
carm 855a08050f Merge pull request #29 from CarmJos/dependabot/maven/org.slf4j-slf4j-api-1.7.36
Bump slf4j-api from 1.7.35 to 1.7.36
2022-02-09 20:43:53 +08:00
dependabot[bot] 904f1bdfda Bump slf4j-api from 1.7.35 to 1.7.36
Bumps [slf4j-api](https://github.com/qos-ch/slf4j) from 1.7.35 to 1.7.36.
- [Release notes](https://github.com/qos-ch/slf4j/releases)
- [Commits](https://github.com/qos-ch/slf4j/compare/v_1.7.35...v_1.7.36)

---
updated-dependencies:
- dependency-name: org.slf4j:slf4j-api
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-09 08:45:20 +00:00
carm 508a560eed Merge pull request #28 from Ghost-chu/patch-1
修复 extraColumns 缺少 BackQuote 的问题
2022-02-06 14:01:19 +08:00
Ghost_chu 469c204d4c 修复 extraColumns 缺少 BackQuote 的问题 2022-02-06 14:00:50 +08:00
carm 7a2d1841db [0.3.6] 枚举参数默认采用 name() 方法 2022-02-05 12:07:45 +08:00
carm f7d85ddf94 Merge pull request #26 from Ghost-chu/master
修正 README.md 中 Maven 中心库的错误的URL
2022-02-03 22:02:52 +08:00
Ghost_chu a438c0e7d0 Update README.md 2022-02-03 22:00:24 +08:00
carm bb4801b41c [0.3.5] 修复 ConditionalBuilder 对于参数未添加 AND 链接的问题 2022-01-29 21:20:07 +08:00
carm 7acc2849ae [0.3.4] 对参数判断是否已加引号或反引号 2022-01-29 17:26:08 +08:00
carm 5e7519dc7a [ci skip] Merge pull request #21 from CarmJos/dependabot/maven/org.apache.maven.plugins-maven-gpg-plugin-3.0.1
Bump maven-gpg-plugin from 1.6 to 3.0.1
2022-01-29 17:05:28 +08:00
carm 643841a98a [ci skip] Merge pull request #20 from CarmJos/dependabot/maven/org.apache.maven.plugins-maven-shade-plugin-3.2.4
Bump maven-shade-plugin from 3.2.3 to 3.2.4
2022-01-29 17:05:20 +08:00
carm 8513324046 [ci skip] Merge pull request #19 from CarmJos/dependabot/maven/mysql-mysql-connector-java-8.0.28
Bump mysql-connector-java from 8.0.25 to 8.0.28
2022-01-29 17:05:11 +08:00
dependabot[bot] 6702a69f8d Bump maven-gpg-plugin from 1.6 to 3.0.1
Bumps [maven-gpg-plugin](https://github.com/apache/maven-gpg-plugin) from 1.6 to 3.0.1.
- [Release notes](https://github.com/apache/maven-gpg-plugin/releases)
- [Commits](https://github.com/apache/maven-gpg-plugin/compare/maven-gpg-plugin-1.6...maven-gpg-plugin-3.0.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-29 08:58:48 +00:00
dependabot[bot] 45cd4c326f Bump maven-shade-plugin from 3.2.3 to 3.2.4
Bumps [maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.2.3 to 3.2.4.
- [Release notes](https://github.com/apache/maven-shade-plugin/releases)
- [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.2.3...maven-shade-plugin-3.2.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-29 08:58:43 +00:00
dependabot[bot] 7097ef518e Bump mysql-connector-java from 8.0.25 to 8.0.28
Bumps [mysql-connector-java](https://github.com/mysql/mysql-connector-j) from 8.0.25 to 8.0.28.
- [Release notes](https://github.com/mysql/mysql-connector-j/releases)
- [Changelog](https://github.com/mysql/mysql-connector-j/blob/release/8.0/CHANGES)
- [Commits](https://github.com/mysql/mysql-connector-j/compare/8.0.25...8.0.28)

---
updated-dependencies:
- dependency-name: mysql:mysql-connector-java
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-29 08:58:32 +00:00
carm 6a67be5b8d [ci skip] Merge pull request #15 from CarmJos/dependabot/maven/com.zaxxer-HikariCP-5.0.1
Bump HikariCP from 4.0.3 to 5.0.1
2022-01-29 16:56:52 +08:00
carm 73e6ebef1d [ci skip] Merge pull request #17 from CarmJos/dependabot/maven/org.apache.maven.plugins-maven-source-plugin-3.2.1
Bump maven-source-plugin from 3.2.0 to 3.2.1
2022-01-29 16:55:55 +08:00
carm 9cbfda954c [ci skip] Merge pull request #16 from CarmJos/dependabot/maven/org.jetbrains-annotations-23.0.0
Bump annotations from 22.0.0 to 23.0.0
2022-01-29 16:55:26 +08:00
carm a4036a359e [ci skip] Merge pull request #14 from CarmJos/dependabot/maven/org.apache.maven.plugins-maven-surefire-plugin-2.22.2
Bump maven-surefire-plugin from 2.22.1 to 2.22.2
2022-01-29 16:55:13 +08:00
carm e5f6d621e1 Merge pull request #18 from CarmJos/dependabot/maven/org.slf4j-slf4j-api-1.7.35
Bump slf4j-api from 1.7.29 to 1.7.35
2022-01-29 16:54:49 +08:00
dependabot[bot] 03afae635b Bump slf4j-api from 1.7.29 to 1.7.35
Bumps [slf4j-api](https://github.com/qos-ch/slf4j) from 1.7.29 to 1.7.35.
- [Release notes](https://github.com/qos-ch/slf4j/releases)
- [Commits](https://github.com/qos-ch/slf4j/compare/v_1.7.29...v_1.7.35)

---
updated-dependencies:
- dependency-name: org.slf4j:slf4j-api
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-29 08:54:07 +00:00
dependabot[bot] a55809d60e Bump maven-source-plugin from 3.2.0 to 3.2.1
Bumps [maven-source-plugin](https://github.com/apache/maven-source-plugin) from 3.2.0 to 3.2.1.
- [Release notes](https://github.com/apache/maven-source-plugin/releases)
- [Commits](https://github.com/apache/maven-source-plugin/compare/maven-source-plugin-3.2.0...maven-source-plugin-3.2.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-29 08:54:03 +00:00
dependabot[bot] 45fafdf68a Bump annotations from 22.0.0 to 23.0.0
Bumps [annotations](https://github.com/JetBrains/java-annotations) from 22.0.0 to 23.0.0.
- [Release notes](https://github.com/JetBrains/java-annotations/releases)
- [Changelog](https://github.com/JetBrains/java-annotations/blob/master/CHANGELOG.md)
- [Commits](https://github.com/JetBrains/java-annotations/compare/22.0.0...23.0.0)

---
updated-dependencies:
- dependency-name: org.jetbrains:annotations
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-29 08:53:57 +00:00
dependabot[bot] e5c6fe1c92 Bump HikariCP from 4.0.3 to 5.0.1
Bumps [HikariCP](https://github.com/brettwooldridge/HikariCP) from 4.0.3 to 5.0.1.
- [Release notes](https://github.com/brettwooldridge/HikariCP/releases)
- [Changelog](https://github.com/brettwooldridge/HikariCP/blob/dev/CHANGES)
- [Commits](https://github.com/brettwooldridge/HikariCP/compare/HikariCP-4.0.3...HikariCP-5.0.1)

---
updated-dependencies:
- dependency-name: com.zaxxer:HikariCP
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-29 08:53:53 +00:00
dependabot[bot] a1d531f1cc Bump maven-surefire-plugin from 2.22.1 to 2.22.2
Bumps [maven-surefire-plugin](https://github.com/apache/maven-surefire) from 2.22.1 to 2.22.2.
- [Release notes](https://github.com/apache/maven-surefire/releases)
- [Commits](https://github.com/apache/maven-surefire/compare/surefire-2.22.1...surefire-2.22.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-29 08:53:47 +00:00
carm c1dfe8dfe0 Merge remote-tracking branch 'origin/master' 2022-01-29 16:44:53 +08:00
carm e8debf73f1 修改部分url地址 2022-01-29 16:44:37 +08:00
carm 7df308f8c6 Update bugs_report.md 2022-01-29 16:04:45 +08:00
carm 0b275d3633 Update feature_issues.md 2022-01-29 16:03:59 +08:00
carm 893511ac06 Merge remote-tracking branch 'origin/master' 2022-01-29 06:02:35 +08:00
carm 045dd9866e 添加中心库介绍 2022-01-29 06:02:25 +08:00
carm 086a6c8b31 Merge pull request #11 from Msyial/master
鉴于该库开发发布于Central,故添加 Maven Central库的相关介绍。
2022-01-29 05:58:16 +08:00
X1A 28464350ee Update README.md 2022-01-29 05:51:40 +08:00
carm 72259bef81 [0.3.3] 版本更新
- `[F]` 修复上个版本中 QueryAction 的 executeFunction 方法未重写 SQLAction 中同方法导致的链接未被自动关闭的问题。
- `[U]` 更新软件依赖于Maven相关插件的版本。
2022-01-29 04:57:29 +08:00
carm 8924258635 [0.3.3] 版本更新
- `[F]` 修复上个版本中 QueryAction 的 executeFunction 方法未重写 SQLAction 中同方法导致的链接未被自动关闭的问题。
- `[U]` 更新软件依赖于Maven相关插件的版本。
2022-01-29 04:49:30 +08:00
carm 6322689d39 Merge pull request #8 from CarmJos/dependabot/maven/org.apache.maven.plugins-maven-release-plugin-2.5.3
Bump maven-release-plugin from 2.5.1 to 2.5.3
2022-01-29 03:51:56 +08:00
carm 90fb21b72c Merge pull request #5 from CarmJos/dependabot/maven/org.apache.maven.plugins-maven-javadoc-plugin-3.3.1
Bump maven-javadoc-plugin from 3.2.0 to 3.3.1
2022-01-29 03:51:44 +08:00
dependabot[bot] 47e588dd19 Bump maven-release-plugin from 2.5.1 to 2.5.3
Bumps maven-release-plugin from 2.5.1 to 2.5.3.

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-28 19:51:28 +00:00
carm c91375f438 Merge pull request #4 from CarmJos/dependabot/maven/org.apache.maven.plugins-maven-jar-plugin-3.2.2
Bump maven-jar-plugin from 3.2.0 to 3.2.2
2022-01-29 03:51:26 +08:00
carm b2d2626b31 Merge pull request #6 from CarmJos/dependabot/maven/org.apache.maven.plugins-maven-compiler-plugin-3.9.0
Bump maven-compiler-plugin from 3.8.1 to 3.9.0
2022-01-29 03:51:21 +08:00
carm 139c1d743e Merge pull request #7 from CarmJos/dependabot/maven/com.github.chris2018998-beecp-3.3.1
Bump beecp from 3.3.0 to 3.3.1
2022-01-29 03:51:10 +08:00
dependabot[bot] 2aa52c9d7b Bump beecp from 3.3.0 to 3.3.1
Bumps [beecp](https://github.com/Chris2018998/BeeCP) from 3.3.0 to 3.3.1.
- [Release notes](https://github.com/Chris2018998/BeeCP/releases)
- [Commits](https://github.com/Chris2018998/BeeCP/compare/3.3.0...3.3.1)

---
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-01-28 19:50:27 +00:00
dependabot[bot] ebd1e54a8c Bump maven-compiler-plugin from 3.8.1 to 3.9.0
Bumps [maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.8.1 to 3.9.0.
- [Release notes](https://github.com/apache/maven-compiler-plugin/releases)
- [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.8.1...maven-compiler-plugin-3.9.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-28 19:49:47 +00:00
dependabot[bot] 9ba7afffc3 Bump maven-javadoc-plugin from 3.2.0 to 3.3.1
Bumps [maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.2.0 to 3.3.1.
- [Release notes](https://github.com/apache/maven-javadoc-plugin/releases)
- [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.2.0...maven-javadoc-plugin-3.3.1)

---
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-01-28 19:49:33 +00:00
dependabot[bot] c4bbbd132e Bump maven-jar-plugin from 3.2.0 to 3.2.2
Bumps [maven-jar-plugin](https://github.com/apache/maven-jar-plugin) from 3.2.0 to 3.2.2.
- [Release notes](https://github.com/apache/maven-jar-plugin/releases)
- [Commits](https://github.com/apache/maven-jar-plugin/compare/maven-jar-plugin-3.2.0...maven-jar-plugin-3.2.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-28 19:49:07 +00:00
carm 8652d4b824 Create dependabot.yml 2022-01-29 03:48:12 +08:00
carm e8f9b5532e 修改项目名 2022-01-29 03:28:50 +08:00
carm 3dd7702a26 删除名字中用于排序的数字 2022-01-29 03:28:22 +08:00
carm f5d04bb0bb [v0.3.2] 版本更新
- [A] 对于UPDATE类型的SQL操作采用 try-with-resources 形式获取链接与statement,避免中途报错而导致相关流未关闭。
- [U] 声明 setKeyIndex(int) 过时并移除 defaultKeyIndex() 方法,改为更明确的 setReturnGeneratedKeys(boolean) 与 returnGeneratedKeys() 方法,避免填入错误的index。
2022-01-29 03:01:10 +08:00
carm 7d11131b97 [v0.3.1] 修复一些小的规范问题 2022-01-26 22:20:53 +08:00
carm 0850194e82 [v0.3.1] 修复一些小的规范问题 2022-01-26 15:01:30 +08:00
carm ba4731c331 [v0.3.1] 修复一些小的规范问题 2022-01-26 15:00:05 +08:00
carm 36a23af450 [v0.3.1] 修复一些小的规范问题 2022-01-26 14:49:19 +08:00
carm 386093e58b [v0.3.1] 修复Javadoc内容不继承打包的问题 2022-01-26 04:14:01 +08:00
carm 8a07759b87 [v0.3.0] 添加测试项目,并对新内容进行测试 2022-01-26 02:26:30 +08:00
carm e98a3357ab [v0.3.0] 添加relativePath 2022-01-25 23:43:25 +08:00
carm 0986ffa7f1 [v0.3.0] 停用 SonarCloud 2022-01-25 23:39:26 +08:00
carm 9a684226bc [v0.3.0] 修改项目结构 2022-01-25 23:39:11 +08:00
carm 51c343e9e0 [v0.3.0] 修改gpg-key 2022-01-25 23:21:13 +08:00
carm cf91a10b6d [v0.3.0] 版本更新
- [A] 添加 TableAlertBuilder 用于快捷修改表的相关设定
- [A] 为 TableCreateBuilder 添加数个方法,包含创建索引、自增主键与外键。
- [R] 修改部分Builder的参数值,为泛型添加限定。
2022-01-25 23:18:05 +08:00
carm d29d06053c [v0.2.10] [A] 添加含默认值的SQL执行函数。 2022-01-24 17:17:47 +08:00
carm 3e05e5764b [v0.2.9] [A] 添加自定义默认异常处理器的方法。 2022-01-24 15:58:31 +08:00
carm a8a475fc7a [v0.2.9] [A] 添加自定义默认异常处理器的方法。 2022-01-24 15:53:07 +08:00
carm 360b416525 [v0.2.9] [A] 添加自定义默认异常处理器的方法。 2022-01-24 15:40:12 +08:00
carm 43baf4aa24 [v0.2.8] [R] 使用Supplier获取是否为Debug模式。 2022-01-24 15:25:12 +08:00
carm edadc50c22 将Javadoc部署整合到Maven Deploy 2022-01-14 12:40:35 +08:00
carm 6c08d265c5 修改构建名 2022-01-12 11:09:17 +08:00
carm 8878379f66 [v0.2.7] [U] 修改了SQLQuery的包位置。 2022-01-12 11:06:28 +08:00
carm 4963719956 [v0.2.7] [U] 进一步简化操作使用逻辑 2022-01-12 10:55:47 +08:00
carm 9bd1556de2 [v0.2.7] [U] 进一步简化操作使用逻辑 2022-01-12 10:55:37 +08:00
carm 66bc427f62 修改开源协议 2022-01-08 17:30:21 +08:00
carm 864c2ac128 修改协议 2022-01-08 17:29:26 +08:00
carm 69aaf4398f Create FUNDING.yml 2022-01-08 02:36:43 +08:00
carm 9e237b36bd 修改ISSUES格式 2022-01-08 01:00:07 +08:00
carm 5f13b9319d [v0.2.6] 版本更新
- [U] 优化 ConditionalBuilder 的使用方式。
- [A] 为 TableQueryBuilder 添加分表查询limit方法。
- [A] 添加 SQLFunction 类,用于对SQL结果直接进行处理,且不需要在方法内处理异常,交由 ExceptionHandler 进行处理。
2022-01-08 00:55:31 +08:00
carm 5601d1288c [v0.2.6] 版本更新
- [U] 优化 ConditionalBuilder 的使用方式。
- [A] 为 TableQueryBuilder 添加分表查询limit方法。
2022-01-07 23:01:44 +08:00
carm 50b36d8430 [v0.2.5] 打包时不再对slf4j-api进行relocation 2022-01-06 14:39:28 +08:00
carm cd60bf256e 添加依赖地址 2022-01-05 05:09:49 +08:00
carm ebe68befee 添加依赖地址 2022-01-05 04:59:02 +08:00
carm 594413e13b 添加依赖地址 2022-01-05 04:56:57 +08:00
carm df94272c73 [v0.2.4] 依赖relocation并添加Optional标签 2022-01-05 02:32:09 +08:00
carm ab986e9526 [v0.2.3] 添加默认的终止manager方法,并支持强制关闭活动链接。 2021-12-23 15:17:12 +08:00
carm 3f3b7bf4a5 添加代码折叠 2021-12-20 19:09:57 +08:00
carm c69695c16d Merge remote-tracking branch 'origin/master' 2021-12-20 19:08:28 +08:00
carm 02aad28715 添加代码折叠 2021-12-20 19:07:04 +08:00
carm b423000fe5 [U] 使用SonarCloud分析 2021-12-20 18:41:25 +08:00
carm cf356f2492 [U] 使用 SonarCloud 分析。 2021-12-20 18:40:29 +08:00
carm 4775c335d5 [v0.2.2] 版本优化
- `[F]` 修复部分类的使用异常问题
- `[F]` 修复 SQLUpdateBatchAction 中 getSQLContent 方法返回内容不正确导致的其他方法一并出现异常的问题。
- `[U]` 修改 SQLUpdateBatchAction 的默认异常处理器。
- `[F]` 修复 PreparedSQLBatchUpdateActionImpl 异常继承导致的无法使用的问题。
2021-12-19 23:53:35 +08:00
carm 84c35eb481 [v0.2.2] 版本优化
- `[F]` 修复部分类的使用异常问题
- `[F]` 修复 SQLUpdateBatchAction 中 getSQLContent 方法返回内容不正确导致的其他方法一并出现异常的问题。
- `[U]` 修改 SQLUpdateBatchAction 的默认异常处理器。
- `[F]` 修复 PreparedSQLBatchUpdateActionImpl 异常继承导致的无法使用的问题。
2021-12-19 23:47:48 +08:00
carm d30b6b9ab2 添加gpg配置 2021-12-15 20:11:57 +08:00
carm f70f73daf2 Merge remote-tracking branch 'origin/master' 2021-12-15 20:08:33 +08:00
carm 4a7c11ef13 添加SCM配置 2021-12-15 20:08:16 +08:00
carm 427aca95ca Create codacy-analysis.yml 2021-12-15 17:07:49 +08:00
carm 2b86d9234a [v0.2.1-fix] 修改javadoc为中文版本 2021-12-14 20:33:24 +08:00
carm 139d213160 [v0.2.1-fix] 补全缺失的javadoc 2021-12-14 20:23:51 +08:00
carm ebc96e5176 [v0.2.1-fix] 补全缺失的javadoc 2021-12-14 20:19:04 +08:00
carm 7621c86495 [v0.2.1-fix] 修改Javadoc 2021-12-14 20:08:54 +08:00
carm 95182748ef [v0.2.1-fix] 修改Java版本 2021-12-14 20:03:47 +08:00
139 changed files with 6351 additions and 3573 deletions
+21 -1
View File
@@ -1,3 +1,23 @@
# 欢迎使用 EasySQL
这个项目刚刚创建,详细的Javadoc与开发指南还在补充,请给我一点时间~
这个项目刚刚创建,详细的Javadoc与开发指南还在补充,请给我一点时间~
## 目录
### 文章
- [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)
+288
View File
@@ -0,0 +1,288 @@
> 本文档由 GitHub 用户 @Ghost-chu 创建。
> 本文撰写于 2022/02/09,适配 EasySQL 版本 `v0.3.6` **(部分接口已变更)**。
> 本文基于 `EasySQL-Hikari` 版本编写。
# EasySQL - HikariPool 使用指南
## 和 EasySQL 说你好:创建你的第一个 SQLManager
```java
public class HiEasySQL {
public static void createYourSQLManager() {
HikariConfig hikari = YOUR_HIKARI_CONFIG;
SQLManager sqlManager = EasySQL.createManager(hikari);
try {
if (!sqlManager.getConnection().isValid(5)) {
logger.warning("Connection invalid!");
}
} catch (SQLException e) {
logger.warning("Failed to connect to database!", e);
}
}
}
```
至此,你已经创建了一个 SQLManager 对象,与 EasySQL 的故事由此开始。
## SQL起步: 查询 (Query)
EasySQL 可以使用异步查询以避免产生性能影响和手动关闭连接的麻烦。本节我们将展示使用 "异步查询" 的示例代码,并讲解如何使用 "查询处理器" 和 "错误处理器"。
```java
public class HiEasySQL {
public static void trySomeQuery(SQLManager sqlManager) {
sqlManager.createQuery() // 创建一个查询
.inTable("table_name") // 指定表名
.selectColumns("name", "sex", "age") // 选择 "name", "sex", "age" 三个列
.addCondition("name", "Bob") // 限定条件,"name" 必须是 Bob
.build()/*构建查询体*/.executeAsync(
(query) -> { /*处理查询结果-SQLQuery*/ },
((exception, sqlAction) -> { /*SQL异常处理-SQLExceptionHandler*/ })
); // 异步查询~~~~
}
}
```
### SQLQuery
SQLQuery 是 EasySQL 执行查询类请求统一返回的对象,包括如下内容:
* ResultSet - 查询结果
* SQLAction - 执行的 SQL 操作
* Action - 操作类型
* ExecuteTime - 查询耗时
* SQLContent - 最终执行的 SQL 语句的内容
如果需要,SQLQuery 还额外提供了一些其他信息,如:
* SQLManager - 创建此 SQLQuery 对象的 SQLManager 实例
* Connection - 执行 SQL 操作的链接
等信息。
### SQLExceptionHandler
当出现 SQLException 异常时,如果你在查询中指定了一个 SQLExceptionHandler,则会被调用。 SQLExceptionHandler 接受两个参数:
* SQLException - 发生的 SQL 异常
* SQLAction - 执行的 SQL 操作
### SQLAction
SQLAction 包含 EasySQL 在处理 SQL 请求时所使用到的信息:
* SQLContent - 最终执行的 SQL 语句的内容
* ActionUUID - 执行的 SQL 操作的唯一标识
* ShortID - 执行的 SQL 操作的短 ID (短8位)
* CreateTime - SQLAction 创建的时间
* SQLManager - 与 SQLAction 有关的 SQLManager 的实例
## 不仅能读,也得能写: 插入(Insert)
除了 SELECT 查询操作以外,EasySQL 也当然支持 INSERT 插入操作。
```java
public class HiEasySQL {
public static void doSomeInsert(SQLManager sqlManager) {
sqlManager.createInsert("table_name")
.setColumnNames("name", "sex", "age")
.setParams("Alex", "female", 16)
.executeAsync();
}
}
```
EasySQL 使用 PreparedStatement 来填充参数,无需担心 SQL 注入问题。
对于常见类型,EasySQL 也对正确的对其进行转换。
### 静默处理
细心的的小伙伴可能发现,这一次我们的 executeAsync 内容为空,没有任何 Handler。
在这种情况下, EasySQL 将会静默失败,不会产生任何日志。
## 信息总是千变万化的:更新(Update)
Bob 是个喜欢改名的人,于是他今天给自己起了个新名字叫 Steve。因此我们需要更新数据库中已经存在的数据:
```java
public class HiEasySQL {
public static void updateSomething(SQLManager sqlManager) {
sqlManager.createUpdate("table_name")
.addCondition("name", "Bob")
.setColumnValues("name", "Steve")
.build().executeAsync();
}
}
```
至此,Bob 就改名为 Steve 啦!
## 旧的不去,新的不来:删除(Delete)
最近 Steve 把它人生中买的一套房给卖了,于是我们需要将这套房从数据库中删除。
不过,Steve 说它不记得这套房子是多久之前买的了,不过肯定是 10 年之前。
```java
public class HiEasySQL {
public static void sayGoodBye(SQLManager sqlManager) {
Date date = new Date(); // 使用当前日期时间戳创建一个 Date
date.setYear(date.getYear() - 10); // 把时间滑动到 10 年之前
sqlManager.createDelete("steve_house") // 进行删除
.addTimeCondition("purchase_date", new Date(0), date) // 选择从1970年1月1日0点一直到10年前的所有数据
.build()
.executeAsync(); //执行
}
}
```
现在 Steve 真的没有他的这套房了。
## 不管有没有,反正都要写:替换(Replace)
Steve 买了一盒牛奶,他要在他的购物清单中标记牛奶已经买了。
不过,Steve 忘记了自己有没有将牛奶加入过购物清单。但是如果暴力 INSERT 肯定会出错,但是又觉得写个 INSERT OR UPDATE 太麻烦了,于是这件棘手的事情又丢到了我们的头上来。
```java
public class HiEasySQL {
public static void putAnyway(SQLManager sqlManager) {
sqlManager.createReplace("steve_list")
.setColumnNames("item", "purchased")
.setParams("milk", true)
.executeAsync();
}
}
```
生活总有简单的方法不是吗?
## 上司的任务:建表
Steve 的公司老板开发了一个 IM 软件,但是 Steve 公司运维是土豆,不会搞SQL。
最要命的是,Steve 的公司老板还不让你碰生产环境,于是你便不能指望土豆会去帮你完成建表的任务了。
除此之外,由于 IM 软件上的网友特能叭叭,你还需要稍微考虑下性能问题。不然你可能会被送去西伯利亚。
```java
public class HiEasySQL {
public static void newTablePlease(SQLManager sqlManager) {
sqlManager.createTable("steve_im_history")
.addColumn("id", "BIGINT NOT NULL", "记录ID")
.addColumn("sender", "VARCHAR NOT NULL", "网友UUID")
.addColumn("message", "TEXT NULL", "网友发言")
.addAutoIncrementColumn("id") //设置 id 列自增
.setIndex(IndexType.PRIMARY_KEY, null, "id", "sender") //配置主键
.setIndex(IndexType.INDEX, "sender_message_index", "sender", "message") //配置索引
.build().executeAsync();
}
}
```
## 上司的任务2:改表
Steve 的公司老板和 Steve 提出了一个需求,迫不得已,Steve 要修改表结构。
然而此时表内已经存储了大量数据,不能删表再建,Steve 要想个办法对表做出相应的修改。
```java
public class HiEasySQL {
public static void newTablePlease(SQLManager sqlManager) {
sqlManager.alterTable("steve_im_history")
.addColumn("ipAddress", "VARCHAR(255)")
.executeAsync();
sqlManager.alterTable("steve_im_history")
.modifyColumn("message", "LONGTEXT")
.executeAsync();
}
}
```
多亏了我们的大力帮助。现在,Steve 被送去了南极担任公司的重要工作了。
## 北极熊的快乐生活:批量操作
Steve 到达南极之后,南极的员工把2FA密钥塞给Steve便骑着海豚跑路了。于是 Steve 除了日常工作以外还要照看公司的北极熊。
北极熊饲养区有一套设备,监控生活在南极的北极熊的生活状态。设备每 1 小时会把缓存的数据存入到服务器里。
然而,员工跑路的时候删库格盘了,现在 Steve 要自己想办法解决这个烂摊子了。
```java
public class HiEasySQL {
public static void iDontLikeHere(SQLManager sqlManager) {
sqlManager.createInsertBatch("polarbear")
.setColumnNames("name", "temp", "hunger")
.addParamsBatch("Karl", -17, 100)
.addParamsBatch("Lucy", -3, 80)
.addParamsBatch("Lily", -10, 70)
.setReturnGeneratedKey(true)// 设定在后续返回自增主键
.executeAsync((list) -> {/*新增行的自增主键*/});
}
}
```
## 北极熊的熊猫之旅!?:复杂查询
Steve 翻看着跑路员工留下的为数不多的资料,发现公司在南极培育北极熊是为了让它们变成熊猫!
只要满足 “温度 < -100C, 饱食度 > 70, 名字中带有 `PANDAKING` 关键字并以符合条件的北极熊门的名字倒序排序后的第一条” 的北极熊就有希望变成熊猫!
现在 Steve 已经迫不及待的看看是哪只熊猫如此幸运了!
```java
public class HiEasySQL {
public static void noBearsPlease(SQLManager sqlManager) {
sqlManager.createQuery()
.inTable("panda_king_proj")
.addCondition("temp", "<", -100)
.addCondition("hunger", ">", 70)
.addCondition("name", "LIKE", "PANDAKING")
.orderBy("name", false)
.setLimit(1)
.build().executeAsync((result) -> {
if (result.getResultSet().next()) {
System.out.println(result.getResultSet().getString("name"));
}
});
}
}
```
## 同步请求
经历人生坎坷后的 Steve 回到了自己的家:因为没能培育出熊猫来,他的老板 Async 炒了他,女友 Lambda 甩了他,连朋友 Handler 都放 Steve 鸽子,于是现在他很讨厌任何带有这两个名字的东西。
```java
public class HiEasySQL {
public static void syncLover(SQLManager sqlManager) {
try (SQLQuery query = sqlManager.createQuery().inTable("the_end")
.addCondition("thanks_read", "this_stupid_guide")
.build().execute()) {
ResultSet set = query.getResultSet(); // SQLQuery 关闭时,ResultSet 会一同关闭
if (set.next()) {
set.getString("see_you_next_time");
}
} catch (Exception exception) {
exception.printStackTrace();
}
}
}
```
当然,有时候 Steve 也会选择更优雅一点的方式。
```java
import org.jetbrains.annotations.Nullable;
import java.sql.SQLException;
public class HiEasySQL {
// 调用此方法,直接返回结果,再在调用处统一处理错误
public static @Nullable String eleganceNeverGone(SQLManager sqlManager) throws SQLException {
return sqlManager.createQuery().inTable("the_end")
.addCondition("thanks_read", "this_stupid_guide")
.build().executeFunction(query -> {
if (!query.getResultSet().next()) return null;
else return query.getResultSet().getString("see_you_next_time");
});
}
}
```
Steve 终究能找到继续生活下去的办法 :)
+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 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 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 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 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) {
// 提示异常
}
}
}
}
```
@@ -4,6 +4,6 @@
## 如何实现?
若您也想通过 [Github Actions](https://docs.github.com/en/actions/learn-github-actions)
若您也想通过 [Github Actions](https://docs.github.com/en/actions/learn-github-actions)
自动部署项目的Javadoc到 [Github Pages](https://pages.github.com/)
可以参考我的文章 [《自动部署Javadoc到Github Pages》](https://pages.carm.cc/doc/javadoc-in-github.html) 。
+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/' }
}
```
+2
View File
@@ -0,0 +1,2 @@
github: [ CarmJos ]
custom: [ 'https://donate.carm.cc' ]
+16 -9
View File
@@ -1,30 +1,37 @@
---
name: 问题提交
about: 提交并描述问题,帮助我们对其进行检查与修复。
name: 问题提交
about: 描述问题并提交,帮助我们对其进行检查与修复。
title: ''
labels: bug
labels: bug
assignees: ''
---
**问题简述**
### **问题简述**
用简短的话语描述一下大概问题。
**问题来源**
### **问题来源**
描述一下通过哪些操作才发现的问题,如:
1. 使用了 '...'
2. 输入了 '....'
3. 出现了报错 '....'
**预期结果**(可选)
### **预期结果** (可选)
如果问题不发生,应该是什么情况
**问题截图/问题报错**
### **问题截图/问题报错**
如果有报错或输出,请提供截图。
**操作环境**
### **操作环境**
- 系统环境: `Windows 10` / `Ubuntu` / `...`
- Java版本: `JDK11` / `OPENJDK8` / `JRE8` / `...`
**其他补充**
### **其他补充**
如有其他补充,可以在这里描述。
+11 -8
View File
@@ -1,20 +1,23 @@
---
name: 功能需求
about: 希望我们提供更多的功能。
name: 功能需求
about: 希望我们提供更多的功能。
title: ''
labels: enhancement
labels: enhancement
assignees: ''
---
**功能简述**
### **功能简述**
简单的描述一下你想要的功能
**需求来源**
### **需求来源**
简单的描述一下为什么需要这个功能。
**功能参考**(可选)
### **功能参考**(可选)
如果有相关功能的参考,如文本、截图,请提供给我们。
**附加内容**
### **附加内容**
如果有什么小细节需要重点注意,请在这里告诉我们。
+11
View File
@@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "maven" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "daily"
+41
View File
@@ -0,0 +1,41 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQGNBGHwDt0BDAC+2u7hHXIp+C3tvUc5w7Ga5gDVNN3xTQEurGXgYSnGnNPb89h/
tk6MBQ2AHdsj61yK/mH65RbDZe725+0zBvumxfrPbgqYBy9veE1Cjpl3wJwsGYa+
gidq3tU2WBpUpaFOcyfxzvoDjKv6BClX+m7RijRM4tTSxmzrUTfwrClSdSV2HlBu
AuKvY5W+cDwlKtuXEBtgCpdlOGsp8YZsqe4QD9xMI6GOOnXnHisYnmsMzn2RU8mW
GUS3ob1J1vAfIinixwB8tHlxB/G3jaOXtQEwFmI2dfYOdkbxOiIgcSfbRI8PGiHA
KiluZpn+Ww05GwUch2HdX8dw1hsbWM4G/X8Aqy3HdJB28p73dE4I9FRrJ1uxsmMe
iON8QevhSBC0qwSxb+16vKt58ErQnqXrJI6+HzPldn22OQIF7bMZGwYkZiOjS5LU
xAoRT4Jomks0ccOZGe7wMIUp2Ch22vmv4O78Pd2GEzAcTUvM8mrS+zJBMogjx27C
r86HOWEjmi2R32EAEQEAAbQeQ2FybSBKb3MgPEthcm11bkpAb3V0bG9vay5jb20+
iQHUBBMBCAA+FiEEL6NL2WG27xbAlAIkh337tzeYbfcFAmHwDt0CGwMFCQPCZwAF
CwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQh337tzeYbffNvQwAscXykUimCOli
lRK52P6+w5n/arl7UxCh7TZiRjf9feiCp3OivETKCeqnbtNTgv67aNbxjO9asCTK
dU6J6Zh6wO8CqDhg+EA8qn+Nu4ESPGvgyWyeck9otMy16To5/I9eQRYTOos1crOA
DRUH1MWLeIkZabM6wSPad/CcRAzFNf5+8JNuQqCgQ3Rngst1Z6Gyb1hixWnjxc4P
7dFquwbR0D0ojwj0Etqd0c5p0iwyRl2I2QQ1bS3aGqdW0LzM9ixh25HAReg2QH7G
FBQ5PLLXr4UqYQygzwhUtxl2jra0+3ia+D7OBwlgm3QPnlo82Z7nExQUYmemD7jV
3Gc1ELXKSRHKbVjSoGiHWpnSiw4ptLo+tnzhRCHlV+pTS3IbQoPdb/glBOVIkA/j
ksCfbrmC8aXpk1YycAXY2my7BpXsImWAOwPHVsvcB2IpEA2s3VfsZ/IB9z+yih3n
z8mL0BFjKWUV23IOoeRqmt7l8nB7u55Nbjasu0LdTcl2R6swE3fTuQGNBGHwDt0B
DAChLPfZ1njctL8BijLO//Hgvw9E6STJGYgqglNetfdoir+YAwCPQ32K4MsaQKl8
xQelmcOU+5jO2C8wEyNAjmvyKGB2J/IjLEtAlbOn1UltKQ/GhxgMjg0EheY81ZMa
7FDq1TDwYRCN5SMKhl5GF0JJ4OWfg1i7HbpEfkw4mW1pl0/eNdeQaC6qV6EWTsqz
WRbi8DeH1WarSgq/00Za6zxNntLNLoq7jsTbDwTc6pgOp1Z8EcGfI/mcn3moqTxc
o/PLYg+6impCKXVeRUlgGBpJ5YVvR5ACTLS9Tztwho9MpKJ9obXAfwXKyoToHCII
+pTnuzweOfOsrjLsFySnXq8WO2PY9JbNWjveKfk35fGfsrbwU0Vg+m67UahXqA4i
KNvZeA8bG8AXrxUirKLWIj/8AuW8NAKu7ui4YmexldraYUgaoBrqhXZCVe8dNQv+
erzNbmJUCPDauNddnDsCqOoZ8fWyBenDs3NS0TWuvua4/ND+AyVxPeatI4qfS2TD
gnUAEQEAAYkBvAQYAQgAJhYhBC+jS9lhtu8WwJQCJId9+7c3mG33BQJh8A7dAhsM
BQkDwmcAAAoJEId9+7c3mG33znkL/01lWSQOzFd+omzrz0RPqFUksxqQS+CUty0m
/4n9H/K3BLcut+nUNbosNuqPqISoiaV7BGigv0bT+Pu+EQQtyjYOSeibeBadB48w
cYp8k3YJbfinuKApw1Zp9IfAd3eXXWi30OY4FmlsKy6LGnusZ6KS+FzTjU94yN/0
LK05fmBtLN/MQJQyqYIkquzk//diwpsxnv34+10igYaQBAEpPIsmsYwWg+ecCtyx
lJGvmQggBrKvo5EdOGhO9DJAu1WQcFqnUCj5qvL+YKIsMyIwujQH8554P8xfCLFU
a351qs30yWXX4HGMn3o7RuVQAACs1buxlMen/JEdQOLOaUtFcu2iYzCFhuzDsetc
geNinFyo0bV9dXiahG95oTL45OA0w+E9Y0B5VXc9Yf08Yyj8ayMChASfVG5lZU6l
KhiaKHV9t4xmwP43lRjs8HTC5rtXc31kPtOAT61HG9vPA49ZdXybUqoHru15PFmc
OK7d0W/LdJ3iFeselROADHgPQn14sg==
=rRA5
-----END PGP PUBLIC KEY BLOCK-----
+54
View File
@@ -0,0 +1,54 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow checks out code, performs a Codacy security scan
# and integrates the results with the
# GitHub Advanced Security code scanning feature. For more information on
# the Codacy security scan action usage and parameters, see
# https://github.com/codacy/codacy-analysis-cli-action.
# For more information on Codacy Analysis CLI in general, see
# https://github.com/codacy/codacy-analysis-cli.
name: "Codacy Security Scan"
on:
push:
branches: [ master ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ master ]
schedule:
- cron: '27 16 * * 5'
jobs:
codacy-security-scan:
name: Codacy Security Scan
runs-on: ubuntu-latest
steps:
# Checkout the repository to the GitHub Actions runner
- name: Checkout code
uses: actions/checkout@v2
# Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis
- name: Run Codacy Analysis CLI
uses: codacy/codacy-analysis-cli-action@d840f886c4bd4edc059706d09c6a1586111c540b
with:
# Check https://github.com/codacy/codacy-analysis-cli#project-token to get your project token from your Codacy repository
# You can also omit the token and run the tools that support default configurations
project-token: ${{ secrets.CODACY_PROJECT_TOKEN }}
verbose: true
output: results.sarif
format: sarif
# Adjust severity of non-security issues
gh-code-scanning-compat: true
# Force 0 exit code to allow SARIF file generation
# This will handover control about PR rejection to the GitHub side
max-allowed-issues: 2147483647
# Upload the SARIF file generated in the previous step
- name: Upload SARIF results file
uses: github/codeql-action/upload-sarif@v1
with:
sarif_file: results.sarif
+26 -26
View File
@@ -9,7 +9,7 @@
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
name: "CodeQL Analysis"
on:
push:
@@ -37,34 +37,34 @@ jobs:
# Learn more about CodeQL language support at https://git.io/codeql-language-support
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Checkout repository
uses: actions/checkout@v2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
# ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
+112 -7
View File
@@ -1,7 +1,7 @@
# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
name: Deploy
name: "Project Deploy"
on:
# 支持手动触发构建
@@ -11,10 +11,9 @@ on:
types: [ published ]
jobs:
build:
packages-deploy:
name: "Publish Project (GitHub Packages)"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: "Set up JDK"
@@ -26,8 +25,114 @@ jobs:
server-id: github
server-username: MAVEN_USERNAME
server-password: MAVEN_TOKEN
- name: "Deploy"
run: mvn -B deploy --file pom.xml -DskipTests
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: "Packages Deploy"
run: mvn -B -Pgithub deploy --file pom.xml -DskipTests
env:
MAVEN_USERNAME: ${{ github.repository_owner }}
MAVEN_TOKEN: ${{secrets.GITHUB_TOKEN}}
MAVEN_TOKEN: ${{secrets.GITHUB_TOKEN}}
MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }}
central-deploy:
name: "Deploy Project (Central 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
server-id: ossrh
server-username: MAVEN_USERNAME
server-password: MAVEN_PASSWORD
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: "Central Deploy"
run: mvn -B -Possrh deploy --file pom.xml -DskipTests
env:
MAVEN_USERNAME: ${{ secrets.OSSRH_USER }}
MAVEN_PASSWORD: ${{ secrets.OSSRH_PASS }}
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
-73
View File
@@ -1,73 +0,0 @@
# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
name: Javadoc
on:
# 支持手动触发构建
workflow_dispatch:
release:
# 创建release的时候触发
types: [ published ]
jobs:
api-website:
runs-on: ubuntu-latest
steps:
- name: Checkout the repo
uses: actions/checkout@v2
- name: Set up the Java JDK
uses: actions/setup-java@v2
with:
java-version: '11'
distribution: 'adopt'
- name: Generate docs
run: mvn clean package
- name: Copy to Location
run: |
rm -rf docs
mkdir -vp docs
cp -vrf easysql-api/target/apidocs/* docs/
cp -vrf .documentation/JAVADOC-README.md docs/README.md
- name: Generate the 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 documentation changes
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
+3 -2
View File
@@ -1,11 +1,12 @@
# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
name: Build
name: Project Build & Tests
on:
# 支持手动触发构建
workflow_dispatch:
pull_request:
push:
jobs:
@@ -21,7 +22,7 @@ jobs:
java-version: '11'
distribution: 'adopt'
- name: "Package"
run: mvn -B package --file pom.xml
run: mvn -B package --file pom.xml -Dgpg.skip
- name: "Target Stage"
run: mkdir staging && cp */target/*.jar staging
- name: "Upload artifact"
+1 -2
View File
@@ -1,4 +1,3 @@
/.idea/
/target/
/*/target/
**/target/
**.iml
+21 -674
View File
@@ -1,674 +1,21 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.
MIT License
Copyright (c) 2022 Carm
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+132 -32
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)
两个连接池的版本。
## 优势
@@ -26,10 +26,6 @@
- 基于JDBC开发,可自选连接池、JDBC驱动。
- 简单便捷的增删改查接口,无需手写SQL语句。
- 额外提供部分常用情况的SQL操作
- 存在则更新,不存在则插入
- 创建表
- 修改表
- ...
- 自动关闭数据流
- 支持同步操作与异步操作
@@ -39,20 +35,60 @@
### 示例代码
您可以 [点击这里](easysql-demo/src/main/java/EasySQLDemo.java) 查看部分代码演示,更多演示详见 [开发介绍](.documentation/README.md) 。
您可以 [点击这里](demo/src/main/java/EasySQLDemo.java) 查看部分代码演示,更多演示详见 [开发介绍](.documentation/README.md) 。
### 依赖方式 (Maven)
### 依赖方式
#### Maven 依赖
<details>
<summary>远程库配置</summary>
```xml
<project>
<repositories>
<repository>
<id>github</id>
<!--采用Maven中心库,安全稳定,但版本更新需要等待同步-->
<id>maven</id>
<name>Maven Central</name>
<url>https://repo1.maven.org/maven2</url>
</repository>
<repository>
<!--采用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>
</repository>
<repository>
<!--采用我的私人依赖库,简单方便,但可能因为变故而无法使用-->
<id>carm-repo</id>
<name>Carm's Repo</name>
<url>https://repo.carm.cc/repository/maven-public/</url>
</repository>
</repositories>
</project>
```
</details>
<details>
<summary>原生依赖</summary>
```xml
<project>
<dependencies>
<!--对于需要提供公共接口的项目,可以仅打包API部分,方便他人调用-->
<dependency>
@@ -70,14 +106,19 @@
<scope>compile</scope>
</dependency>
<!--如需自定义连接池,则可以仅打包实现部分,自行创建SQLManager-->
<dependency>
<groupId>cc.carm.lib</groupId>
<artifactId>easysql-beecp</artifactId>
<version>[LATEST RELEASE]</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
```
</details>
<details>
<summary>含连接池版本</summary>
```xml
<project>
<dependencies>
<!--也可直接选择打包了连接池的版本-->
<dependency>
<groupId>cc.carm.lib</groupId>
@@ -91,35 +132,94 @@
<version>[LATEST VERSION]</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
```
</details>
#### Gradle 依赖
<details>
<summary>远程库配置</summary>
```groovy
repositories {
// 采用Maven中心库,安全稳定,但版本更新需要等待同步
mavenCentral()
// 采用github的repo分支依赖,实时更新。 (推荐)
maven { url 'https://github.com/CarmJos/EasySQL/blob/repo/' }
// 采用github依赖库,安全稳定,但需要配置
maven { url 'https://maven.pkg.github.com/CarmJos/EasySQL' }
// 采用我的私人依赖库,简单方便,但可能因为变故而无法使用
maven { url 'https://repo.carm.cc/repository/maven-public/' }
}
```
</details>
<details>
<summary>原生依赖</summary>
```groovy
dependencies {
//对于需要提供公共接口的项目,可以仅打包API部分,方便他人调用
api "cc.carm.lib:easysql-api:[LATEST RELEASE]"
//如需自定义连接池,则可以仅打包实现部分,自行创建SQLManager
api "cc.carm.lib:easysql-impl:[LATEST RELEASE]"
}
```
</details>
<details>
<summary>含连接池版本</summary>
```groovy
dependencies {
//也可直接选择打包了连接池的版本
api "cc.carm.lib:easysql-beecp:[LATEST RELEASE]"
api "cc.carm.lib:easysql-hikaricp:[LATEST RELEASE]"
}
```
</details>
## 支持与捐赠
若您觉得本插件做的不错,您可以通过捐赠支持我!
感谢您对开源项目的支持!
<img height=25% width=25% src="https://raw.githubusercontent.com/CarmJos/CarmJos/main/img/donate-code.jpg" alt=""/>
## 开源协议
本项目源码采用 [GNU General Public License v3.0](https://opensource.org/licenses/GPL-3.0) 开源协议。
> ### 关于 GPL 协议
> GNU General Public Licence (GPL) 有可能是开源界最常用的许可模式。GPL 保证了所有开发者的权利,同时为使用者提供了足够的复制,分发,修改的权利:
本项目源码采用 [The MIT License](https://opensource.org/licenses/MIT) 开源协议。
<details>
<summary>关于 MIT 协议</summary>
> MIT 协议可能是几大开源协议中最宽松的一个,核心条款是:
>
> #### 可自由复制
> 你可以将软件复制到你的电脑,你客户的电脑,或者任何地方。复制份数没有任何限制。
> #### 可自由分发
> 在你的网站提供下载,拷贝到U盘送人,或者将源代码打印出来从窗户扔出去(环保起见,请别这样做)。
> #### 可以用来盈利
> 你可以在分发软件的时候收费,但你必须在收费前向你的客户提供该软件的 GNU GPL 许可协议,以便让他们知道,他们可以从别的渠道免费得到这份软件,以及你收费的理由。
> #### 可自由修改
> 如果你想添加或删除某个功能,没问题,如果你想在别的项目中使用部分代码,也没问题,唯一的要求是,使用了这段代码的项目也必须使用 GPL 协议。
> 该软件及其相关文档对所有人免费,可以任意处置,包括使用,复制,修改,合并,发表,分发,再授权,或者销售。唯一的限制是,软件中必须包含上述版 权和许可提示。
>
> 需要注意的是,分发的时候,需要明确提供源代码和二进制文件,另外,用于某些程序的某些协议有一些问题和限制,你可以看一下 @PierreJoye 写的 Practical Guide to GPL Compliance 一文。使用 GPL 协议,你必须在源代码代码中包含相应信息,以及协议本身。
> 这意味着:
> - 你可以自由使用,复制,修改,可以用于自己的项目。
> - 可以免费分发或用来盈利。
> - 唯一的限制是必须包含许可声明。
>
> MIT 协议是所有开源许可中最宽松的一个,除了必须包含许可声明外,再无任何限制。
>
> *以上文字来自 [五种开源协议GPL,LGPL,BSD,MIT,Apache](https://www.oschina.net/question/54100_9455) 。*
</details>
+23 -19
View File
@@ -1,18 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>cc.carm.lib</groupId>
<artifactId>easysql-parent</artifactId>
<version>0.2.1</version>
<version>0.4.5</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<properties>
<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>
<artifactId>easysql-api</artifactId>
<packaging>jar</packaging>
<name>00-EasySQL-API</name>
<name>EasySQL-API</name>
<description>EasySQL的接口部分。用于打包到公共项目的API中,避免项目过大。</description>
<url>https://github.com/CarmJos/EasySQL</url>
@@ -30,34 +37,31 @@
<licenses>
<license>
<name>GNU General Public License v3.0</name>
<url>https://opensource.org/licenses/GPL-3.0</url>
<name>The MIT License</name>
<url>https://opensource.org/licenses/MIT</url>
</license>
</licenses>
<issueManagement>
<system>GitHub Issues</system>
<url>${project.url}/issues</url>
<url>https://github.com/CarmJos/EasySQL/issues</url>
</issueManagement>
<ciManagement>
<system>GitHub Actions</system>
<url>${project.url}/actions/workflows/maven.yml</url>
<url>https://github.com/CarmJos/EasySQL/actions/workflows/maven.yml</url>
</ciManagement>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
</properties>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.36</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
@@ -72,7 +76,7 @@
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
</plugins>
</build>
@@ -0,0 +1,254 @@
package cc.carm.lib.easysql.api;
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 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.Collections;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
/**
* SQLAction 是用于承载SQL语句并进行处理、返回的基本类。
*
* <ul>
* <li>同步执行 {@link #execute()}, {@link #execute(SQLFunction, SQLExceptionHandler)}
* <br>同步执行方法中有会抛出异常的方法与不抛出异常的方法,
* <br>若选择不抛出异常,则返回值可能为空,需要特殊处理。</li>
*
* <li>异步执行 {@link #executeAsync(SQLHandler, SQLExceptionHandler)}
* <br>异步执行时将提供成功与异常两种处理方式
* <br>可自行选择是否对数据或异常进行处理
* <br>默认的异常处理器为 {@link #defaultExceptionHandler()}
* <br>若有特殊需要,可通过{@link #setExceptionHandler(SQLExceptionHandler)} 方法修改默认的处理器</li>
* </ul>
*
* @param <T> 需要返回的类型
* @author CarmJos
* @since 0.0.1
*/
public interface SQLAction<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 SQLManager}
*
* @return {@link SQLManager}
*/
@NotNull SQLManager getManager();
/**
* 执行该Action对应的SQL语句
*
* @return 指定数据类型
* @throws SQLException 当SQL操作出现问题时抛出
*/
@NotNull T execute() throws SQLException;
/**
* 执行语句并返回值
*
* @param exceptionHandler 异常处理器 默认为 {@link #defaultExceptionHandler()}
* @return 指定类型数据
*/
@Nullable
default T execute(@Nullable SQLExceptionHandler exceptionHandler) {
return execute(t -> t, exceptionHandler);
}
/**
* 执行语句并处理返回值
*
* @param function 处理方法
* @param exceptionHandler 异常处理器 默认为 {@link #defaultExceptionHandler()}
* @param <R> 需要返回的内容
* @return 指定类型数据
*/
@Nullable
default <R> R execute(@NotNull SQLFunction<T, R> function,
@Nullable SQLExceptionHandler exceptionHandler) {
return execute(function, null, exceptionHandler);
}
/**
* 执行语句并处理返回值
*
* @param function 处理方法
* @param defaultResult 默认结果,若处理后的结果为null,则返回该值
* @param exceptionHandler 异常处理器 默认为 {@link #defaultExceptionHandler()}
* @param <R> 需要返回的内容
* @return 指定类型数据
*/
@Nullable
@Contract("_,!null,_ -> !null")
default <R> R execute(@NotNull SQLFunction<T, R> function,
@Nullable R defaultResult,
@Nullable SQLExceptionHandler exceptionHandler) {
try {
return executeFunction(function, defaultResult);
} catch (SQLException exception) {
handleException(exceptionHandler, exception);
return null;
}
}
/**
* 执行语句并处理返回值
*
* @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语句,采用默认异常处理,无需返回值。
*/
default void executeAsync() {
executeAsync(null);
}
/**
* 异步执行SQL语句
*
* @param success 成功时的操作
*/
default void executeAsync(@Nullable SQLHandler<T> success) {
executeAsync(success, null);
}
/**
* 异步执行SQL语句
*
* @param success 成功时的操作
* @param failure 异常处理器 默认为 {@link SQLAction#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);
}
/**
* 获取管理器提供的默认异常处理器。
* 若未使用过 {@link #setExceptionHandler(SQLExceptionHandler)} 方法,
* 则默认返回 {@link SQLExceptionHandler#detailed(Logger)} 。
*
* @return {@link SQLExceptionHandler}
*/
default SQLExceptionHandler defaultExceptionHandler() {
return getManager().getExceptionHandler();
}
/**
* 设定通用的异常处理器。
* <br> 在使用 {@link #execute(SQLExceptionHandler)} 等相关方法时,若传入的处理器为null,则会采用此处理器。
* <br> 若该方法传入参数为 null,则会使用 {@link #defaultExceptionHandler()} 。
*
* @param handler 异常处理器
*/
default void setExceptionHandler(@Nullable SQLExceptionHandler handler) {
getManager().setExceptionHandler(handler);
}
}
@@ -0,0 +1,31 @@
package cc.carm.lib.easysql.api;
import org.jetbrains.annotations.NotNull;
/**
* SQLBuilder 是用于构建SQL语句以生成SQLAction执行操作的中间类。
* <br>其连接了{@link SQLManager} 与 {@link SQLAction} ,避免大量的代码堆积
* <br>也是本接口的核心功能所在
*
* @author CarmJos
*/
public interface SQLBuilder {
static @NotNull String withBackQuote(@NotNull String str) {
str = str.trim();
return !str.isEmpty() && str.charAt(0) == '`' && str.charAt(str.length() - 1) == '`' ? str : "`" + str + "`";
}
static @NotNull String withQuote(@NotNull String str) {
str = str.trim();
return !str.isEmpty() && str.charAt(0) == '\'' && str.charAt(str.length() - 1) == '\'' ? str : "'" + str + "'";
}
/**
* 得到承载该Builder的对应{@link SQLManager}
*
* @return {@link SQLManager}
*/
@NotNull SQLManager getManager();
}
@@ -0,0 +1,245 @@
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.builder.*;
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.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.function.Supplier;
/**
* SQLManager 是EasySQL的核心类,用于管理数据库连接,提供数据库操作的方法。
*
* @author CarmJos
*/
public interface SQLManager {
Logger getLogger();
boolean isDebugMode();
/**
* 获取用于执行 {@link SQLAction#executeAsync()} 的线程池。
* <br> 默认线程池为 {@link ThreadPoolExecutor} ,大小为 3。
*
* @return {@link ExecutorService}
*/
@NotNull ExecutorService getExecutorPool();
/**
* 设定用于执行 {@link SQLAction#executeAsync()} 的线程池。
*
* @param executorPool {@link ExecutorService}
*/
void setExecutorPool(@NotNull ExecutorService executorPool);
/**
* 设定是否启用调试模式。
* 启用调试模式后,会在每次执行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> 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);
/**
* 执行一条不需要返回结果的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 PreparedSQLUpdateBatchAction
*/
@Nullable List<Integer> executeSQLBatch(String sql, Iterable<Object[]> paramsBatch);
/**
* 执行多条不需要返回结果的SQL。
* 该方法使用 Statement 实现,请注意SQL注入风险!
*
* @param sql SQL语句内容
* @param moreSQL 更多SQL语句内容
* @return 对应参数返回的行数
* @see SQLUpdateBatchAction
*/
@Nullable List<Integer> executeSQLBatch(@NotNull String sql, String... moreSQL);
/**
* 执行多条不需要返回结果的SQL。
*
* @param sqlBatch SQL语句内容
* @return 对应参数返回的行数
*/
@Nullable List<Integer> executeSQLBatch(@NotNull Iterable<String> sqlBatch);
/**
* 在库中创建一个表
*
* @param tableName 表名
* @return {@link TableCreateBuilder}
*/
TableCreateBuilder createTable(@NotNull String tableName);
/**
* 对库中的某个表执行更改
*
* @param tableName 表名
* @return {@link TableAlterBuilder}
*/
TableAlterBuilder alterTable(@NotNull String tableName);
/**
* 新建一个查询
*
* @return {@link QueryBuilder}
*/
QueryBuilder createQuery();
/**
* 创建一条插入操作
*
* @param tableName 目标表名
* @return {@link InsertBuilder}
*/
InsertBuilder<PreparedSQLUpdateAction<Integer>> createInsert(@NotNull String tableName);
/**
* 创建支持多组数据的插入操作
*
* @param tableName 目标表名
* @return {@link InsertBuilder}
*/
InsertBuilder<PreparedSQLUpdateBatchAction<Integer>> createInsertBatch(@NotNull String tableName);
/**
* 创建一条替换操作
*
* @param tableName 目标表名
* @return {@link ReplaceBuilder}
*/
ReplaceBuilder<PreparedSQLUpdateAction<Integer>> createReplace(@NotNull String tableName);
/**
* 创建支持多组数据的替换操作
*
* @param tableName 目标表名
* @return {@link ReplaceBuilder}
*/
ReplaceBuilder<PreparedSQLUpdateBatchAction<Integer>> createReplaceBatch(@NotNull String tableName);
/**
* 创建更新操作
*
* @param tableName 目标表名
* @return {@link UpdateBuilder}
*/
UpdateBuilder createUpdate(@NotNull String tableName);
/**
* 创建删除操作
*
* @param tableName 目标表名
* @return {@link DeleteBuilder}
*/
DeleteBuilder createDelete(@NotNull String tableName);
}
@@ -0,0 +1,70 @@
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 java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.concurrent.TimeUnit;
/**
* SQLQuery 是一个查询中间接口,用于查询操作的封装。
*
* @author CarmJos
*/
public interface SQLQuery extends AutoCloseable {
/**
* 获取该查询创建的时间
* <br>注意,此处获得的时间非时间戳毫秒数,仅用于计算耗时。
*
* @return 创建时间
*/
default long getExecuteTime() {
return getExecuteTime(TimeUnit.MILLISECONDS);
}
/**
* 获取该查询创建的时间
* <br>注意,此处获得的时间非时间戳毫秒数,仅用于计算耗时。
*
* @param timeUnit 时间单位
* @return 创建时间
*/
long getExecuteTime(TimeUnit timeUnit);
/**
* 得到承载该SQLQuery的对应{@link SQLManager}
*
* @return {@link SQLManager}
*/
SQLManager getManager();
/**
* 得到承载该SQLQuery的对应{@link QueryAction}
*
* @return {@link QueryAction} 或 {@link PreparedQueryAction}
*/
QueryAction getAction();
ResultSet getResultSet();
/**
* 得到设定的SQL语句
*
* @return SQL语句
*/
String getSQLContent();
/**
* 关闭所有内容
*/
@Override
void close();
Statement getStatement();
Connection getConnection();
}
@@ -0,0 +1,149 @@
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.builder.*;
import cc.carm.lib.easysql.api.function.SQLHandler;
import cc.carm.lib.easysql.api.table.NamedSQLTable;
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().inTable(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.createDelete(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.createUpdate(getTableName());
}
default @NotNull InsertBuilder<PreparedSQLUpdateAction<Integer>> createInsert() {
return Optional.ofNullable(getSQLManager()).map(this::createInsert)
.orElseThrow(() -> new NullPointerException("This table doesn't have a SQLManger."));
}
default @NotNull InsertBuilder<PreparedSQLUpdateAction<Integer>> createInsert(@NotNull SQLManager sqlManager) {
return sqlManager.createInsert(getTableName());
}
default @NotNull InsertBuilder<PreparedSQLUpdateBatchAction<Integer>> createInsertBatch() {
return Optional.ofNullable(getSQLManager()).map(this::createInsertBatch)
.orElseThrow(() -> new NullPointerException("This table doesn't have a SQLManger."));
}
default @NotNull InsertBuilder<PreparedSQLUpdateBatchAction<Integer>> createInsertBatch(@NotNull SQLManager sqlManager) {
return sqlManager.createInsertBatch(getTableName());
}
default @NotNull ReplaceBuilder<PreparedSQLUpdateAction<Integer>> createReplace() {
return Optional.ofNullable(getSQLManager()).map(this::createReplace)
.orElseThrow(() -> new NullPointerException("This table doesn't have a SQLManger."));
}
default @NotNull ReplaceBuilder<PreparedSQLUpdateAction<Integer>> createReplace(@NotNull SQLManager sqlManager) {
return sqlManager.createReplace(getTableName());
}
default @NotNull ReplaceBuilder<PreparedSQLUpdateBatchAction<Integer>> createReplaceBatch() {
return Optional.ofNullable(getSQLManager()).map(this::createReplaceBatch)
.orElseThrow(() -> new NullPointerException("This table doesn't have a SQLManger."));
}
default @NotNull ReplaceBuilder<PreparedSQLUpdateBatchAction<Integer>> createReplaceBatch(@NotNull SQLManager sqlManager) {
return sqlManager.createReplaceBatch(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,24 @@
package cc.carm.lib.easysql.api.action;
import org.jetbrains.annotations.Nullable;
public interface PreparedSQLUpdateAction<T extends Number> extends SQLUpdateAction<T> {
/**
* 设定SQL语句中所有 ? 对应的参数
*
* @param params 参数内容
* @return {@link PreparedSQLUpdateAction}
*/
PreparedSQLUpdateAction<T> setParams(Object... params);
/**
* 设定SQL语句中所有 ? 对应的参数
*
* @param params 参数内容
* @return {@link PreparedSQLUpdateAction}
* @since 0.4.0
*/
PreparedSQLUpdateAction<T> setParams(@Nullable Iterable<Object> params);
}
@@ -0,0 +1,42 @@
package cc.carm.lib.easysql.api.action;
import cc.carm.lib.easysql.api.SQLAction;
import java.util.List;
public interface PreparedSQLUpdateBatchAction<T extends Number> extends SQLAction<List<T>> {
/**
* 设定多组SQL语句中所有 ? 对应的参数
*
* @param allParams 所有参数内容
* @return {@link PreparedSQLUpdateBatchAction}
*/
PreparedSQLUpdateBatchAction<T> setAllParams(Iterable<Object[]> allParams);
/**
* 添加一组SQL语句中所有 ? 对应的参数
*
* @param params 参数内容
* @return {@link PreparedSQLUpdateBatchAction}
*/
PreparedSQLUpdateBatchAction<T> addParamsBatch(Object... params);
/**
* 设定该操作返回自增键序列。
*
* @return {@link SQLUpdateAction}
*/
PreparedSQLUpdateBatchAction<T> returnGeneratedKeys();
/**
* 设定该操作返回自增键序列。
*
* @param keyTypeClass 自增序列的数字类型
* @param <N> 自增键序列类型 {@link Number}
* @return {@link SQLUpdateAction}
* @since 0.4.0
*/
<N extends Number> PreparedSQLUpdateBatchAction<N> returnGeneratedKeys(Class<N> keyTypeClass);
}
@@ -0,0 +1,26 @@
package cc.carm.lib.easysql.api.action;
import cc.carm.lib.easysql.api.SQLAction;
public interface SQLUpdateAction<T extends Number> extends SQLAction<T> {
/**
* 设定该操作返回自增键序列。
*
* @return {@link SQLUpdateAction}
*/
SQLUpdateAction<T> returnGeneratedKey();
/**
* 设定该操作返回自增键序列。
*
* @param keyTypeClass 自增序列的数字类型
* @param <N> 自增键序列类型 {@link Number}
* @return {@link SQLUpdateAction}
* @since 0.4.0
*/
<N extends Number> SQLUpdateAction<N> returnGeneratedKey(Class<N> keyTypeClass);
}
@@ -0,0 +1,27 @@
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);
}
@Override
@NotNull List<String> getSQLContents();
}
@@ -0,0 +1,35 @@
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,45 @@
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.function.SQLExceptionHandler;
import cc.carm.lib.easysql.api.function.SQLFunction;
import cc.carm.lib.easysql.api.function.SQLHandler;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.sql.SQLException;
/**
* SQLQueryAction 是用于承载SQL查询语句并进行处理、返回并自动关闭连接的基本类。
*
* <ul>
* <li>同步执行 {@link #execute()}, {@link #execute(SQLFunction, SQLExceptionHandler)}
* <br>同步执行方法中有会抛出异常的方法与不抛出异常的方法,
* <br>若选择不抛出异常,则返回值可能为空,需要特殊处理。</li>
*
* <li>异步执行 {@link #executeAsync(SQLHandler, SQLExceptionHandler)}
* <br>异步执行时将提供成功与异常两种处理方式
* <br>可自行选择是否对数据或异常进行处理
* <br>默认的异常处理器为 {@link #defaultExceptionHandler()}</li>
* </ul>
*
* <b>注意: 无论是否异步,都不需要自行关闭ResultSet,本API已自动关闭</b>
*
* @author CarmJos
* @since 0.2.6
*/
public interface QueryAction extends SQLAction<SQLQuery> {
@Override
@Contract("_,!null -> !null")
default <R> @Nullable R executeFunction(@NotNull SQLFunction<@NotNull SQLQuery, R> function,
@Nullable R defaultResult) throws SQLException {
try (SQLQuery value = execute()) {
R result = function.apply(value);
return result == null ? defaultResult : result;
}
}
}
@@ -0,0 +1,82 @@
package cc.carm.lib.easysql.api.builder;
import cc.carm.lib.easysql.api.SQLAction;
import cc.carm.lib.easysql.api.SQLBuilder;
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 {
/**
* 将现有条件构建完整的SQL语句用于执行。
*
* @return {@link SQLAction}
*/
T build();
/**
* 设定限定的条目数
*
* @param limit 条数限制
* @return {@link B}
*/
B setLimit(int limit);
/**
* 直接设定条件的源文本,不需要以WHERE开头。
* <br>如 {@code id = 1 AND name = 'test' OR name = 'test2'} 。
*
* @param condition 条件文本,不需要以WHERE开头。
* @return {@link B}
*/
B setConditions(@Nullable String condition);
/**
* 直接设定每个条件的文本与其对应数值,将以AND链接,且不需要以WHERE开头。
* <br>条件如 {@code id = ? },问号将被以对应的数值填充。。
*
* @param conditionSQLs 条件内容,将以AND链接,且不需要以WHERE开头。
* @return {@link B}
*/
B setConditions(LinkedHashMap<@NotNull String, @Nullable Object> conditionSQLs);
B addCondition(@Nullable String condition);
B addCondition(@NotNull String columnName, @NotNull String operator, @Nullable Object queryValue);
B addCondition(@NotNull String columnName, @Nullable Object queryValue);
B addCondition(@NotNull String[] columnNames, @Nullable Object[] queryValues);
B addNotNullCondition(@NotNull String columnName);
/**
* 添加时间的限定条件。 若设定了开始时间,则限定条件为 {@code endMillis >= startMillis}
*
* @param columnName 判断的行
* @param startMillis 开始时间戳,若{@code <0}则不作限定
* @param endMillis 结束时间戳,若{@code <0}则不作限定
* @return {@link B}
*/
default B addTimeCondition(@NotNull String columnName, long startMillis, long endMillis) {
return addTimeCondition(columnName,
startMillis > 0 ? new Date(startMillis) : null,
endMillis > 0 ? new Date(endMillis) : null
);
}
/**
* 添加时间的限定条件。 若设定了开始时间,则限定条件为 {@code endDate >= startTime}
*
* @param columnName 判断的行
* @param startDate 开始时间,若为null则不作限定
* @param endDate 结束时间,若为null则不作限定
* @return {@link B}
*/
B addTimeCondition(@NotNull String columnName, @Nullable java.util.Date startDate, @Nullable java.util.Date endDate);
}
@@ -0,0 +1,9 @@
package cc.carm.lib.easysql.api.builder;
import cc.carm.lib.easysql.api.SQLAction;
public interface DeleteBuilder extends ConditionalBuilder<DeleteBuilder, SQLAction<Integer>> {
String getTableName();
}
@@ -0,0 +1,19 @@
package cc.carm.lib.easysql.api.builder;
import cc.carm.lib.easysql.api.SQLAction;
import java.util.Arrays;
import java.util.List;
public interface InsertBuilder<T extends SQLAction<?>> {
String getTableName();
T setColumnNames(List<String> columnNames);
default T setColumnNames(String... columnNames) {
return setColumnNames(columnNames == null ? null : Arrays.asList(columnNames));
}
}
@@ -0,0 +1,37 @@
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 org.jetbrains.annotations.NotNull;
public interface QueryBuilder extends SQLBuilder {
/**
* 通过一条 SQL语句创建查询。
* 该方法使用 Statement 实现,请注意SQL注入风险!
*
* @param sql SQL语句
* @return {@link QueryAction}
* @deprecated 存在SQL注入风险,建议使用 {@link QueryBuilder#withPreparedSQL(String)}
*/
@Deprecated
QueryAction withSQL(@NotNull String sql);
/**
* 通过一条 SQL语句创建预查询
*
* @param sql SQL语句
* @return {@link PreparedQueryAction}
*/
PreparedQueryAction withPreparedSQL(@NotNull String sql);
/**
* 创建表查询
*
* @param tableName 表名
* @return {@link TableQueryBuilder}
*/
TableQueryBuilder inTable(@NotNull String tableName);
}
@@ -0,0 +1,25 @@
package cc.carm.lib.easysql.api.builder;
import cc.carm.lib.easysql.api.SQLAction;
import java.util.Arrays;
import java.util.List;
/**
* REPLACE 语句用于将一组值更新进数据表中。
* <br> 执行后,将通过表中键判断该数据是否存在,若存在则用新数据替换原来的值,若不存在则会插入该数据。
* <br> 在使用REPLACE时,表与所给行列数据中必须包含唯一索引(或主键),且索引不得为空值,否则将等同于插入语句。
*
* @param <T> 最终构建出的 {@link SQLAction} 类型
*/
public interface ReplaceBuilder<T extends SQLAction<?>> {
String getTableName();
T setColumnNames(List<String> columnNames);
default T setColumnNames(String... columnNames) {
return setColumnNames(columnNames == null ? null : Arrays.asList(columnNames));
}
}
@@ -0,0 +1,129 @@
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.enums.IndexType;
import cc.carm.lib.easysql.api.enums.NumberType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface TableAlterBuilder extends SQLBuilder {
SQLAction<Integer> renameTo(@NotNull String newTableName);
SQLAction<Integer> changeComment(@NotNull String newTableComment);
SQLAction<Integer> setAutoIncrementIndex(int index);
SQLAction<Integer> addIndex(@NotNull IndexType indexType, @Nullable String indexName,
@NotNull String columnName, @NotNull String... moreColumns);
/**
* 为该表移除一个索引
*
* @param indexName 索引名
* @return {@link SQLUpdateAction}
*/
SQLAction<Integer> dropIndex(@NotNull String indexName);
/**
* 为该表移除一个外键
*
* @param keySymbol 外键名
* @return {@link SQLUpdateAction}
*/
SQLAction<Integer> dropForeignKey(@NotNull String keySymbol);
/**
* 为该表移除主键(须添加新主键)
*
* @return {@link SQLUpdateAction}
*/
SQLAction<Integer> dropPrimaryKey();
/**
* 为表添加一列
*
* @param columnName 列名
* @param settings 列的相关设定
* @return {@link SQLUpdateAction}
*/
default SQLAction<Integer> addColumn(@NotNull String columnName, @NotNull String settings) {
return addColumn(columnName, settings, null);
}
/**
* 为表添加一列
*
* @param columnName 列名
* @param settings 列的相关设定
* @param afterColumn 该列增添到哪个列的后面,
* <p> 该参数若省缺则放于最后一行
* <p> 若为 "" 则置于首行。
* @return {@link SQLUpdateAction}
*/
SQLAction<Integer> addColumn(@NotNull String columnName, @NotNull String settings, @Nullable String afterColumn);
SQLAction<Integer> renameColumn(@NotNull String columnName, @NotNull String newName);
SQLAction<Integer> modifyColumn(@NotNull String columnName, @NotNull String settings);
default SQLAction<Integer> modifyColumn(@NotNull String columnName, @NotNull String columnSettings, @NotNull String afterColumn) {
return modifyColumn(columnName, columnSettings + " AFTER `" + afterColumn + "`");
}
SQLAction<Integer> removeColumn(@NotNull String columnName);
SQLAction<Integer> setColumnDefault(@NotNull String columnName, @NotNull String defaultValue);
SQLAction<Integer> removeColumnDefault(@NotNull String columnName);
/**
* 为该表添加一个自增列
* <p> 自增列强制要求为数字类型,非空,且为UNIQUE。
* <p> 注意:一个表只允许有一个自增列!
*
* @param columnName 列名
* @param numberType 数字类型,若省缺则为 {@link NumberType#INT}
* @param primary 是否为主键,若否则只为唯一键
* @param unsigned 是否采用 UNSIGNED (即无负数,可以增加自增键的最高数,建议为true)
* @return {@link TableCreateBuilder}
*/
default SQLAction<Integer> addAutoIncrementColumn(@NotNull String columnName, @Nullable NumberType numberType,
boolean primary, boolean unsigned) {
return addColumn(columnName,
(numberType == null ? NumberType.INT : numberType).name()
+ (unsigned ? " UNSIGNED " : " ")
+ "NOT NULL AUTO_INCREMENT " + (primary ? "PRIMARY KEY" : "UNIQUE KEY"),
""
);
}
/**
* 为该表添加一个自增列
* <br> 自增列强制要求为数字类型,非空,且为UNIQUE。
* <p> 注意:一个表只允许有一个自增列!
*
* @param columnName 列名
* @param numberType 数字类型,若省缺则为 {@link NumberType#INT}
* @return {@link TableAlterBuilder}
*/
default SQLAction<Integer> addAutoIncrementColumn(@NotNull String columnName, @NotNull NumberType numberType) {
return addAutoIncrementColumn(columnName, numberType, false, true);
}
/**
* 为该表添加一个自增列
* <br> 自增列强制要求为数字类型,非空,且为UNIQUE。
* <p> 注意:一个表只允许有一个自增列!
*
* @param columnName 列名
* @return {@link TableAlterBuilder}
*/
default SQLAction<Integer> addAutoIncrementColumn(@NotNull String columnName) {
return addAutoIncrementColumn(columnName, NumberType.INT);
}
}
@@ -0,0 +1,256 @@
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.enums.ForeignKeyRule;
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.util.Objects;
import static cc.carm.lib.easysql.api.SQLBuilder.withBackQuote;
import static cc.carm.lib.easysql.api.SQLBuilder.withQuote;
public interface TableCreateBuilder extends SQLBuilder {
/**
* 将现有条件构建完整的SQL语句用于执行。
*
* @return {@link SQLUpdateAction}
*/
SQLUpdateAction<Integer> build();
@NotNull String getTableName();
/**
* 得到表的设定。
* <p> 若未使用 {@link #setTableSettings(String)} 方法则会采用 {@link #defaultTablesSettings()} 。
*
* @return TableSettings
*/
@NotNull String getTableSettings();
TableCreateBuilder setTableSettings(@NotNull String settings);
/**
* 设定表的标注,一般用于解释该表的作用。
*
* @param comment 表标注
* @return {@link TableCreateBuilder}
*/
TableCreateBuilder setTableComment(@Nullable String comment);
/**
* 直接设定表的所有列信息
*
* @param columns 列的相关信息 (包括列设定)
* @return {@link TableCreateBuilder}
*/
TableCreateBuilder setColumns(@NotNull String... columns);
/**
* 为该表添加一个列
*
* @param column 列的相关信息
* <br>如 `uuid` VARCHAR(36) NOT NULL UNIQUE KEY
* @return {@link TableCreateBuilder}
*/
TableCreateBuilder addColumn(@NotNull String column);
/**
* 为该表添加一个列
*
* @param columnName 列名
* @param settings 列的设定
* <br>如 VARCHAR(36) NOT NULL UNIQUE KEY
* @return {@link TableCreateBuilder}
*/
default TableCreateBuilder addColumn(@NotNull String columnName, @NotNull String settings) {
Objects.requireNonNull(columnName, "columnName could not be null");
return addColumn(withBackQuote(columnName) + " " + settings);
}
/**
* 为该表添加一个列
*
* @param columnName 列名
* @param settings 列的设定
* <br>如 VARCHAR(36) NOT NULL UNIQUE KEY
* @param comments 列的注解,用于解释该列数据的作用
* @return {@link TableCreateBuilder}
*/
default TableCreateBuilder addColumn(@NotNull String columnName, @NotNull String settings, @NotNull String comments) {
return addColumn(columnName, settings + " COMMENT " + withQuote(comments));
}
/**
* 为该表添加一个自增列
* <p> 自增列强制要求为数字类型,非空,且为UNIQUE。
* <p> 注意:一个表只允许有一个自增列!
*
* @param columnName 列名
* @param numberType 数字类型,若省缺则为 {@link NumberType#INT}
* @param asPrimaryKey 是否为主键,若为false则设定为唯一键
* @param unsigned 是否采用 UNSIGNED (即无负数,可以增加自增键的最高数,建议为true)
* @return {@link TableCreateBuilder}
*/
TableCreateBuilder addAutoIncrementColumn(@NotNull String columnName, @Nullable NumberType numberType,
boolean asPrimaryKey, boolean unsigned);
/**
* 为该表添加一个INT类型的自增主键列
* <p> 自增列强制要求为数字类型,非空,且为UNIQUE。
* <p> 注意:一个表只允许有一个自增列!
*
* @param columnName 列名
* @param asPrimaryKey 是否为主键,若为false则设定为唯一键
* @param unsigned 是否采用 UNSIGNED (即无负数,可以增加自增键的最高数,建议为true)
* @return {@link TableCreateBuilder}
*/
default TableCreateBuilder addAutoIncrementColumn(@NotNull String columnName,
boolean asPrimaryKey, boolean unsigned) {
return addAutoIncrementColumn(columnName, NumberType.INT, asPrimaryKey, unsigned);
}
/**
* 为该表添加一个INT类型的自增列
* <p> 自增列强制要求为数字类型,非空,且为UNIQUE。
* <p> 注意:一个表只允许有一个自增列!
*
* @param columnName 列名
* @param asPrimaryKey 是否为主键,若为false则设定为唯一键
* @return {@link TableCreateBuilder}
*/
default TableCreateBuilder addAutoIncrementColumn(@NotNull String columnName, boolean asPrimaryKey) {
return addAutoIncrementColumn(columnName, asPrimaryKey, true);
}
/**
* 为该表添加一个INT类型的自增主键列
* <p> 自增列强制要求为数字类型,非空,且为UNIQUE。
* <p> 注意:一个表只允许有一个自增列!
*
* @param columnName 列名
* @return {@link TableCreateBuilder}
*/
default TableCreateBuilder addAutoIncrementColumn(@NotNull String columnName) {
return addAutoIncrementColumn(columnName, true);
}
/**
* 设定表中的某列为索引或键。
*
* <p>创建索引时,你需要确保该索引是应用在 SQL 查询语句的条件(一般作为 WHERE 子句的条件)。
* <br>虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE 和DELETE。
* <br>因此,请合理的设计索引。
*
* @param type 索引类型
* @param columnName 索引包含的列
* @return {@link TableCreateBuilder}
*/
default TableCreateBuilder setIndex(@NotNull String columnName,
@NotNull IndexType type) {
return setIndex(type, null, columnName);
}
/**
* 设定表中的某列为索引或键。
*
* <p>创建索引时,你需要确保该索引是应用在 SQL 查询语句的条件(一般作为 WHERE 子句的条件)。
* <br>虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE 和DELETE。
* <br>因此,请合理的设计索引。
*
* @param type 索引类型
* @param indexName 索引名称,缺省时将根据第一个索引列赋一个名称
* @param columnName 索引包含的列
* @param moreColumns 联合索引需要包含的列
* @return {@link TableCreateBuilder}
*/
TableCreateBuilder setIndex(@NotNull IndexType type, @Nullable String indexName,
@NotNull String columnName, @NotNull String... moreColumns);
/**
* 以本表位从表,为表中某列设定自参照外键(即自参照完整性)。
*
* <p>外键约束(FOREIGN KEY)是表的一个特殊字段,经常与主键约束一起使用。
* <br>外键用来建立主表与从表的关联关系,为两个表的数据建立连接,约束两个表中数据的一致性和完整性。
* <br>主表删除某条记录时,从表中与之对应的记录也必须有相应的改变。
*
* @param tableColumn 本表中的列
* @param foreignColumn 外键关联表中对应的关联列,必须为目标表的主键,即 {@link IndexType#PRIMARY_KEY}
* @return {@link TableCreateBuilder}
*/
default TableCreateBuilder addForeignKey(@NotNull String tableColumn, @NotNull String foreignColumn) {
return addForeignKey(tableColumn, getTableName(), foreignColumn);
}
/**
* 以本表位从表,为表中某列设定外键。
*
* <p>外键约束(FOREIGN KEY)是表的一个特殊字段,经常与主键约束一起使用。
* <br>外键用来建立主表与从表的关联关系,为两个表的数据建立连接,约束两个表中数据的一致性和完整性。
* <br>主表删除某条记录时,从表中与之对应的记录也必须有相应的改变。
*
* @param tableColumn 本表中的列
* @param foreignTable 外键关联主表,必须为已存在的表或本表,且必须有主键。
* @param foreignColumn 外键关联主表中对应的关联列,须满足
* <p> 1. 为主表的主键,即 {@link IndexType#PRIMARY_KEY}
* <p> 2. 数据类型必须和所要建立主键的列的数据类型相同。
* @return {@link TableCreateBuilder}
*/
default TableCreateBuilder addForeignKey(@NotNull String tableColumn,
@NotNull String foreignTable, @NotNull String foreignColumn) {
return addForeignKey(tableColumn, null, foreignTable, foreignColumn);
}
/**
* 以本表位从表,为表中某列设定外键。
*
* <p>外键约束(FOREIGN KEY)是表的一个特殊字段,经常与主键约束一起使用。
* <br>外键用来建立主表与从表的关联关系,为两个表的数据建立连接,约束两个表中数据的一致性和完整性。
* <br>主表删除某条记录时,从表中与之对应的记录也必须有相应的改变。
*
* @param tableColumn 本表中的列
* @param constraintName 约束名,缺省时将使用参数自动生成,如 <i>fk_[tableColumn]_[foreignTable]</i>
* @param foreignTable 外键关联主表,必须为已存在的表或本表,且必须有主键。
* @param foreignColumn 外键关联主表中对应的关联列,须满足
* <p> 1. 为主表的主键,即 {@link IndexType#PRIMARY_KEY}
* <p> 2. 数据类型必须和所要建立主键的列的数据类型相同。
* @return {@link TableCreateBuilder}
*/
default TableCreateBuilder addForeignKey(@NotNull String tableColumn, @Nullable String constraintName,
@NotNull String foreignTable, @NotNull String foreignColumn) {
return addForeignKey(tableColumn, constraintName, foreignTable, foreignColumn, null, null);
}
/**
* 以本表位从表,为表中某列设定外键。
*
* <p>外键约束(FOREIGN KEY)是表的一个特殊字段,经常与主键约束一起使用。
* <br>外键用来建立主表与从表的关联关系,为两个表的数据建立连接,约束两个表中数据的一致性和完整性。
* <br>主表删除某条记录时,从表中与之对应的记录也必须有相应的改变。
*
* @param tableColumn 本表中的列
* @param constraintName 约束名,缺省时将使用参数自动生成,如 <i>fk_[tableColumn]_[foreignTable]</i>
* @param foreignTable 外键关联主表,必须为已存在的表或本表,且必须有主键。
* @param foreignColumn 外键关联主表中对应的关联列,须满足
* <p> 1. 为主表的主键,即 {@link IndexType#PRIMARY_KEY}
* <p> 2. 数据类型必须和所要建立主键的列的数据类型相同。
* @param updateRule 在外键被更新时采用的规则,缺省时默认为{@link ForeignKeyRule#RESTRICT}
* @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);
default String defaultTablesSettings() {
return "ENGINE=InnoDB DEFAULT CHARSET=utf8";
}
}
@@ -0,0 +1,37 @@
package cc.carm.lib.easysql.api.builder;
import cc.carm.lib.easysql.api.action.query.PreparedQueryAction;
import org.jetbrains.annotations.NotNull;
public interface TableQueryBuilder extends ConditionalBuilder<TableQueryBuilder, PreparedQueryAction> {
@NotNull String getTableName();
/**
* 选定用于查询的列名
*
* @param columnNames 列名
* @return {@link TableQueryBuilder}
*/
TableQueryBuilder selectColumns(@NotNull String... columnNames);
/**
* 对结果进行排序
*
* @param columnName 排序使用的列名
* @param asc 是否为正序排序 (为false则倒序排序)
* @return {@link TableQueryBuilder}
*/
TableQueryBuilder orderBy(@NotNull String columnName, boolean asc);
/**
* 限制查询条数,用于分页查询。
*
* @param start 开始数
* @param end 结束条数
* @return {@link TableQueryBuilder}
* @since 0.2.6
*/
TableQueryBuilder setPageLimit(int start, int end);
}
@@ -0,0 +1,56 @@
package cc.carm.lib.easysql.api.builder;
import cc.carm.lib.easysql.api.SQLAction;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.LinkedHashMap;
public interface UpdateBuilder extends ConditionalBuilder<UpdateBuilder, SQLAction<Integer>> {
String getTableName();
/**
* 添加一条需要更新的字段名与值
*
* @param columnName 字段名
* @param columnValue 字段名对应的值
* @return {@link UpdateBuilder}
* @since 0.3.7
*/
UpdateBuilder addColumnValue(@NotNull String columnName, @Nullable Object columnValue);
/**
* 设定更新的全部字段值 <b>(此操作会覆盖之前的设定)</b>
* <p> <b>此操作会覆盖之前的设定</b>
*
* @param columnData 字段名和值的键值对
* @return {@link UpdateBuilder}
*/
UpdateBuilder setColumnValues(LinkedHashMap<@NotNull String, @Nullable Object> columnData);
/**
* 设定更新的全部字段值 <b>(此操作会覆盖之前的设定)</b>
* <p> <b>此操作会覆盖之前的设定</b>
*
* @param columnNames 字段名
* @param columnValues 字段名对应的值
* @return {@link UpdateBuilder}
*/
UpdateBuilder setColumnValues(@NotNull String[] columnNames, @Nullable Object[] columnValues);
/**
* 设定更新的全部字段值 <b>(此操作会覆盖之前的设定)</b>
* <p> 如需同时更新多条字段,请使用 {@link #setColumnValues(String[], Object[])} 或 {@link #setColumnValues(LinkedHashMap)}
* <br>也可以使用 {@link #addColumnValue(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});
}
}
@@ -0,0 +1,17 @@
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,41 @@
package cc.carm.lib.easysql.api.enums;
public enum ForeignKeyRule {
/**
* 啥也不做
* <p>注意: 在Mysql中该选项实际上等同于采用默认的 {@link #RESTRICT} 设定!
*/
NO_ACTION("NO ACTION"),
/**
* 拒绝删除要求,直到使用删除键值的辅助表被手工删除,并且没有参照时(这是默认设置,也是最安全的设置)
*/
RESTRICT("RESTRICT"),
/**
* 修改包含与已删除键值有参照关系的所有记录,使用NULL值替换(只能用于已标记为NOT NULL的字段)
*/
SET_NULL("SET NULL"),
/**
* 修改包含与已删除键值有参照关系的所有记录,使用默认值替换(只能用于设定了DEFAULT的字段)
*/
SET_DEFAULT("SET DEFAULT"),
/**
* <b>级联删除</b>,删除包含与已删除键值有参照关系的所有记录
*/
CASCADE("CASCADE");
final String ruleName;
ForeignKeyRule(String ruleName) {
this.ruleName = ruleName;
}
public String getRuleName() {
return ruleName;
}
}
@@ -0,0 +1,41 @@
package cc.carm.lib.easysql.api.enums;
public enum IndexType {
/**
* <b>普通索引</b>(由关键字KEY或INDEX定义的索引)的唯一任务是加快对数据的访问速度。
* <br> 因此,应该只为那些最经常出现在查询条件(WHERE column=)或排序条件(ORDER BY column)中的数据列创建索引。
* <br> 只要有可能,就应该选择一个数据最整齐、最紧凑的数据列(如一个整数类型的数据列)来创建索引。
*/
INDEX("INDEX"),
/**
* <b>唯一索引</b> 是在表上一个或者多个字段组合建立的索引,这个或者这些字段的值组合起来在表中不可以重复,用于保证数据的唯一性。
*/
UNIQUE_KEY("UNIQUE KEY"),
/**
* <b>主键索引</b> 是唯一索引的特定类型。表中创建主键时自动创建的索引 。一个表只能建立一个主索引。
*/
PRIMARY_KEY("PRIMARY KEY"),
/**
* <b>全文索引</b> 主要用来查找文本中的关键字,而不是直接与索引中的值相比较。
* <br> 请搭配 MATCH 等语句使用,而不是使用 WHERE - LIKE 。
* <br> 全文索引只可用于 CHAR、 VARCHAR 与 TEXT 系列类型。
*/
FULLTEXT_INDEX("FULLTEXT");
final String name;
IndexType(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
@@ -0,0 +1,11 @@
package cc.carm.lib.easysql.api.enums;
public enum NumberType {
TINYINT,
SMALLINT,
MEDIUMINT,
INT,
BIGINT
}
@@ -0,0 +1,100 @@
package cc.carm.lib.easysql.api.function;
import cc.carm.lib.easysql.api.SQLAction;
import cc.carm.lib.easysql.api.SQLQuery;
import cc.carm.lib.easysql.api.action.PreparedSQLUpdateAction;
import cc.carm.lib.easysql.api.action.PreparedSQLUpdateBatchAction;
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 SQLAction#execute(SQLExceptionHandler)} 等相关方法时,
* 如果发生异常,则会调用错误处理器进行错误内容的输出提示。
*/
public interface SQLDebugHandler {
/**
* 该方法将在 {@link SQLAction#execute()} 执行前调用。
*
* @param action {@link SQLAction} 对象
* @param params 执行传入的参数列表。
* 实际上,仅有 {@link PreparedSQLUpdateAction} 和 {@link PreparedSQLUpdateBatchAction} 才会有传入参数。
*/
void beforeExecute(@NotNull SQLAction<?> 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 SQLAction<?> action, @NotNull List<@Nullable Object[]> params) {
logger.info("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
logger.info("┣# ActionUUID: {}", action.getActionUUID());
logger.info("┣# ActionType: {}", action.getClass().getSimpleName());
if (action.getSQLContents().size() == 1) {
logger.info("┣# SQLContent: {}", action.getSQLContents().get(0));
} else {
logger.info("┣# SQLContents: ");
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("┣# SQLParam: {}", parseParams(param));
}
} else if (params.size() > 1) {
logger.info("┣# SQLParams: ");
int i = 0;
for (Object[] param : params) {
logger.info("┃ - [{}] {}", ++i, parseParams(param));
}
}
logger.info("┣# CreateTime: {}", action.getCreateTime(TimeUnit.MILLISECONDS));
logger.info("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
}
@Override
public void afterQuery(@NotNull SQLQuery query, long executeNanoTime, long closeNanoTime) {
logger.info("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
logger.info("┣# ActionUUID: {}", query.getAction().getActionUUID());
logger.info("┣# SQLContent: {}", query.getSQLContent());
logger.info("┣# CloseTime: {} (cost {} ms)",
TimeUnit.NANOSECONDS.toMillis(closeNanoTime),
((double) (closeNanoTime - executeNanoTime) / 1000000)
);
logger.info("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
}
};
}
}
@@ -0,0 +1,46 @@
package cc.carm.lib.easysql.api.function;
import cc.carm.lib.easysql.api.SQLAction;
import org.slf4j.Logger;
import java.sql.SQLException;
import java.util.function.BiConsumer;
/**
* 异常处理器。
* <br> 在使用 {@link SQLAction#execute(SQLExceptionHandler)} 等相关方法时,
* 如果发生异常,则会调用错误处理器进行错误内容的输出提示。
*/
@FunctionalInterface
public interface SQLExceptionHandler extends BiConsumer<SQLException, SQLAction<?>> {
/**
* 默认的异常处理器,将详细的输出相关错误与错误来源。
*
* @param logger 用于输出错误信息的Logger。
* @return 输出详细信息的错误处理器。
*/
static SQLExceptionHandler detailed(Logger logger) {
return (exception, sqlAction) -> {
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();
};
}
/**
* “安静“ 的错误处理器,发生错误什么都不做。
* 强烈不建议把此处理器作为默认处理器使用!
*
* @return 无输出的处理器。
*/
static SQLExceptionHandler silent() {
return (exception, sqlAction) -> {
};
}
}
@@ -0,0 +1,34 @@
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 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,23 @@
package cc.carm.lib.easysql.api.function;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import java.sql.SQLException;
import java.util.Objects;
@FunctionalInterface
public interface SQLHandler<T> {
void accept(@NotNull T t) throws SQLException;
@NotNull
@Contract(pure = true)
default SQLHandler<T> andThen(@NotNull SQLHandler<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> {
accept(t);
after.accept(t);
};
}
}
@@ -0,0 +1,50 @@
package cc.carm.lib.easysql.api.table;
import cc.carm.lib.easysql.api.SQLManager;
import cc.carm.lib.easysql.api.SQLTable;
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 NamedSQLTable} 下的静态方法进行对象的初始化。
*
* @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,108 @@
package cc.carm.lib.easysql.api.util;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TimeDateUtils {
public static final DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public TimeDateUtils() {
}
/**
* 得到当前时间文本。
*
* @return 时间文本 格式{@link TimeDateUtils#getFormat()}
*/
public static String getCurrentTime() {
return getTimeString(System.currentTimeMillis());
}
/**
* 得到一个时间戳的文本
*
* @param timeMillis 时间戳
* @return 时间文本 格式{@link TimeDateUtils#getFormat()}
*/
public static String getTimeString(long timeMillis) {
return getFormat().format(new Date(timeMillis));
}
/**
* 得到一个日期时间的文本
*
* @param time 日期时间
* @return 时间文本 格式{@link TimeDateUtils#getFormat()}
*/
public static String getTimeString(Date time) {
return getFormat().format(time);
}
/**
* 得到一个时间文本的时间戳
*
* @param timeString 时间文本
* @return 时间戳 格式{@link TimeDateUtils#getFormat()}
*/
public static long parseTimeMillis(String timeString) {
if (timeString == null) {
return -1L;
} else {
try {
return format.parse(timeString).getTime();
} catch (ParseException var2) {
return -1L;
}
}
}
/**
* 得到一个时间文本的对应日期实例
*
* @param timeString 时间文本
* @return 日期实例 格式{@link TimeDateUtils#getFormat()}
*/
public static Date getTimeDate(String timeString) {
if (timeString == null) {
return null;
} else {
try {
return format.parse(timeString);
} catch (ParseException var2) {
return null;
}
}
}
/**
* 将秒数转化为 DD:hh:mm:ss 格式
*
* @param allSeconds 秒数
* @return DD:hh:mm:ss格式文本
*/
public static String toDHMSStyle(long allSeconds) {
long days = allSeconds / 86400L;
long hours = allSeconds % 86400L / 3600L;
long minutes = allSeconds % 3600L / 60L;
long seconds = allSeconds % 60L;
String DateTimes;
if (days > 0L) {
DateTimes = days + "" + (hours > 0L ? hours + "小时" : "") + (minutes > 0L ? minutes + "分钟" : "") + (seconds > 0L ? seconds + "" : "");
} else if (hours > 0L) {
DateTimes = hours + "小时" + (minutes > 0L ? minutes + "分钟" : "") + (seconds > 0L ? seconds + "" : "");
} else if (minutes > 0L) {
DateTimes = minutes + "分钟" + (seconds > 0L ? seconds + "" : "");
} else {
DateTimes = seconds + "";
}
return DateTimes;
}
public static DateFormat getFormat() {
return format;
}
}
@@ -0,0 +1,28 @@
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);
} else {
return UUID.fromString(s.substring(0, 8) + '-' + s.substring(8, 12) + '-' + s.substring(12, 16) + '-' + s.substring(16, 20) + '-' + s.substring(20));
}
}
}
+45 -21
View File
@@ -1,18 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>easysql-parent</artifactId>
<groupId>cc.carm.lib</groupId>
<version>0.2.1</version>
<version>0.4.5</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>easysql-hikaricp</artifactId>
<properties>
<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>
<name>11-EasySQL-HikariCP</name>
<description>EasySQL的应用部分。此为HikariCP版本。</description>
<log4j.version>2.18.0</log4j.version>
</properties>
<artifactId>easysql-demo</artifactId>
<packaging>jar</packaging>
<name>EasySQL-Demo</name>
<description>EasySQL的演示部分</description>
<url>https://github.com/CarmJos/EasySQL</url>
<developers>
@@ -29,8 +41,8 @@
<licenses>
<license>
<name>GNU General Public License v3.0</name>
<url>https://opensource.org/licenses/GPL-3.0</url>
<name>The MIT License</name>
<url>https://opensource.org/licenses/MIT</url>
</license>
</licenses>
@@ -44,14 +56,6 @@
<url>${project.url}/actions/workflows/maven.yml</url>
</ciManagement>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</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>
</properties>
<dependencies>
<dependency>
@@ -66,7 +70,31 @@
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>4.0.3</version>
<scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<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>
@@ -81,10 +109,6 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
+52
View File
@@ -0,0 +1,52 @@
import cc.carm.lib.easysql.api.SQLManager;
import cc.carm.lib.easysql.api.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) {
// 提示异常
}
}
}
}
+69
View File
@@ -0,0 +1,69 @@
import cc.carm.lib.easysql.api.SQLManager;
import cc.carm.lib.easysql.api.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) {
// 提示异常
}
}
}
}
+160
View File
@@ -0,0 +1,160 @@
import cc.carm.lib.easysql.api.SQLManager;
import cc.carm.lib.easysql.api.SQLQuery;
import cc.carm.lib.easysql.api.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;
import cc.carm.lib.easysql.api.util.TimeDateUtils;
import cc.carm.lib.easysql.api.util.UUIDUtil;
import org.jetbrains.annotations.TestOnly;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.UUID;
@TestOnly
@SuppressWarnings("all")
public class EasySQLDemo {
public void createTable(SQLManager sqlManager) {
// 同步创建表
sqlManager.createTable("users")
// .addColumn("id", "INT(11) AUTO_INCREMENT NOT NULL PRIMARY KEY")
.addAutoIncrementColumn("id", NumberType.INT, true, true)
.addColumn("uuid", "VARCHAR(32) NOT NULL UNIQUE KEY")
.addColumn("username", "VARCHAR(16) NOT NULL")
.addColumn("age", "TINYINT NOT NULL DEFAULT 1")
.addColumn("email", "VARCHAR(32)")
.addColumn("phone", "VARCHAR(16)")
.addColumn("registerTime", "DATETIME NOT NULL")
// .addColumn("INDEX `phone`") // 原始方法添加索引
.setIndex("username", IndexType.UNIQUE_KEY) // 添加唯一索引
.setIndex(IndexType.INDEX, "contact", "email", "phone") //添加联合索引 (示例)
.build().execute(null /* 不处理错误 */);
sqlManager.createTable("user_ipaddr")
.addAutoIncrementColumn("id", NumberType.INT, true, true)
.addColumn("uuid", "VARCHAR(32) NOT NULL")
.addColumn("ip", "VARCHAR(16)")
.addColumn("time", "DATETIME NOT NULL")
.addForeignKey("uuid", null,
"users", "uuid",
ForeignKeyRule.CASCADE, ForeignKeyRule.CASCADE
)
.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")
.modifyColumn("age", "TINYINT NOT NULL DEFAULT 0")
.execute(null /* 不处理错误 */);
}
public void sqlQuery(SQLManager sqlManager) {
// 同步SQL查询
try (SQLQuery query = sqlManager.createQuery()
.inTable("users") // 在users表中查询
.selectColumns("id", "name") // 选中 id 与 name列
.addCondition("age", ">", 18) // 限定 age 要大于5
.addCondition("email", null) // 限定查询 email 字段为空
.addNotNullCondition("phone") // 限定 phone 字段不为空
.addTimeCondition("registerTime", // 时间字段
System.currentTimeMillis() - 100000, //限制开始时间
-1//不限制结束时间
).build().execute()) {
ResultSet resultSet = query.getResultSet();
//do something
} catch (SQLException exception) {
exception.printStackTrace();
}
UUID userUUID = sqlManager.createQuery()
.inTable("users") // 在users表中查询
.selectColumns("uuid")
.addCondition("id", 5) // 限定 id 为 5
.setLimit(1) // 只取出一个数据
.build().execute(query -> {
//可以直接进行数据处理
ResultSet result = query.getResultSet();
return result.next() ? UUIDUtil.toUUID(result.getString("uuid")) : null;
}, (exception, action) -> {
// 处理异常,不想处理直接填null
});
}
public void sqlQueryAsync(SQLManager sqlManager) {
// 异步SQL查询
sqlManager.createQuery()
.inTable("users") // 在users表中查询
.addCondition("id", 5) // 限定 id 为 5
.setLimit(1) // 只取出一个数据
.build().executeAsync(success -> {
ResultSet resultSet = success.getResultSet();
if (resultSet != null && resultSet.next()) {
String username = resultSet.getString("username");
}
}, (exception, action) -> {
//do something
long createTIme = action.getCreateTime();
String shortID = action.getShortID();
String sqlContent = action.getSQLContent();
});
}
public void sqlInsert(SQLManager sqlManager) {
// 同步SQL插入 (不使用try-catch的情况下,返回的数值可能为空。)
int id = sqlManager.createInsert("users")
.setColumnNames("username", "phone", "email", "registerTime")
.setParams("CarmJos", "18888888888", "carm@carm.cc", TimeDateUtils.getCurrentTime())
.returnGeneratedKey() // 设定在后续返回自增主键
.execute((exception, action) -> {
// 处理异常
System.out.println("#" + action.getShortID() + " -> " + action.getSQLContent());
exception.printStackTrace();
});
try {
int userID = sqlManager.createInsert("users")
.setColumnNames("username", "phone", "email", "registerTime")
.setParams("CarmJos", "18888888888", "carm@carm.cc", TimeDateUtils.getCurrentTime())
.returnGeneratedKey().execute();
System.out.println("新用户的ID为 " + userID);
} catch (SQLException exception) {
exception.printStackTrace();
}
}
}
@@ -0,0 +1,90 @@
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;
import java.util.Set;
public class EasySQLTest {
protected SQLManager sqlManager;
@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;");
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<>();
tests.add(new TableCreateTest());
// tests.add(new TableAlterTest());
// tests.add(new TableRenameTest());
// tests.add(new QueryNotCloseTest());
tests.add(new SQLUpdateBatchTests());
tests.add(new SQLUpdateReturnKeysTest());
tests.add(new QueryCloseTest());
tests.add(new QueryFunctionTest());
tests.add(new QueryFutureTest());
tests.add(new QueryAsyncTest());
// tests.add(new DeleteTest());
print("准备进行测试...");
int index = 1;
int success = 0;
for (TestHandler currentTest : tests) {
print("-------------------------------------------------");
if (currentTest.executeTest(index, sqlManager)) {
success++;
}
index++;
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
print(" ");
print("全部测试执行完毕,成功 %s 个,失败 %s 个。",
success, (tests.size() - success)
);
}
public static void print(@NotNull String format, Object... params) {
System.out.printf((format) + "%n", params);
}
}
@@ -0,0 +1,37 @@
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;
import java.util.concurrent.ExecutionException;
public abstract class TestHandler {
protected static void print(@NotNull String format, Object... params) {
EasySQLTest.print(format, params);
}
@ApiStatus.OverrideOnly
public abstract void onTest(SQLManager sqlManager) throws SQLException, ExecutionException, InterruptedException;
public boolean executeTest(int index, SQLManager sqlManager) {
String testName = getClass().getSimpleName();
print(" #%s 测试 @%s 开始", index, testName);
long start = System.currentTimeMillis();
try {
onTest(sqlManager);
print(" #%s 测试 @%s 成功,耗时 %s ms。", index, testName, (System.currentTimeMillis() - start));
return true;
} catch (Exception exception) {
print(" #%s 测试 @%s 失败,耗时 %s ms。", index, testName, (System.currentTimeMillis() - start));
exception.printStackTrace();
return false;
}
}
}
@@ -0,0 +1,21 @@
package cc.carm.lib.easysql.tests;
import cc.carm.lib.easysql.TestHandler;
import cc.carm.lib.easysql.api.SQLManager;
import java.sql.SQLException;
public class DeleteTest extends TestHandler {
@Override
public void onTest(SQLManager sqlManager) throws SQLException {
System.out.println("change(s): " + sqlManager.createDelete("test_user_table")
.addCondition("id", ">", 5)
.addNotNullCondition("username")
.build().execute());
}
}
@@ -0,0 +1,33 @@
package cc.carm.lib.easysql.tests;
import cc.carm.lib.easysql.TestHandler;
import cc.carm.lib.easysql.api.SQLManager;
import java.sql.SQLException;
public class QueryAsyncTest extends TestHandler {
@Override
public void onTest(SQLManager sqlManager) throws SQLException {
sqlManager.createQuery()
.inTable("test_user_table")
.orderBy("id", false)
.setLimit(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"));
}
});
}
}
@@ -0,0 +1,36 @@
package cc.carm.lib.easysql.tests;
import cc.carm.lib.easysql.TestHandler;
import cc.carm.lib.easysql.api.SQLManager;
import cc.carm.lib.easysql.api.SQLQuery;
import java.math.BigInteger;
import java.sql.ResultSet;
import java.sql.SQLException;
public class QueryCloseTest extends TestHandler {
@Override
public void onTest(SQLManager sqlManager) throws SQLException {
try (SQLQuery query = sqlManager.createQuery()
.inTable("test_user_table")
.orderBy("id", false)
.setLimit(5)
.build().execute()) {
ResultSet resultSet = query.getResultSet();
while (resultSet.next()) {
System.out.printf(
"id: %d username: %s%n",
resultSet.getObject("id", BigInteger.class),
resultSet.getString("username")
);
}
}
}
}
@@ -0,0 +1,31 @@
package cc.carm.lib.easysql.tests;
import cc.carm.lib.easysql.TestHandler;
import cc.carm.lib.easysql.api.SQLManager;
import java.sql.SQLException;
public class QueryFunctionTest extends TestHandler {
@Override
public void onTest(SQLManager sqlManager) throws SQLException {
Integer id_1 = sqlManager.createQuery()
.inTable("test_user_table")
.orderBy("id", false)
.setLimit(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");
});
System.out.println("id (ps): " + id_1);
}
}
@@ -0,0 +1,33 @@
package cc.carm.lib.easysql.tests;
import cc.carm.lib.easysql.TestHandler;
import cc.carm.lib.easysql.api.SQLManager;
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()
.inTable("test_user_table")
.orderBy("id", false)
.setLimit(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);
}
}
@@ -0,0 +1,31 @@
package cc.carm.lib.easysql.tests;
import cc.carm.lib.easysql.TestHandler;
import cc.carm.lib.easysql.api.SQLManager;
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")
.orderBy("id", false)
.setLimit(5)
.build().execute();
ResultSet resultSet = query.getResultSet();
while (resultSet.next()) {
System.out.printf("id: %d username: %s%n", resultSet.getInt("id"), resultSet.getString("username"));
}
}
}
@@ -0,0 +1,39 @@
package cc.carm.lib.easysql.tests;
import cc.carm.lib.easysql.TestHandler;
import cc.carm.lib.easysql.api.SQLManager;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class SQLUpdateBatchTests extends TestHandler {
protected static List<Object[]> generateParams() {
return IntStream.range(0, 5).mapToObj(i -> generateParam()).collect(Collectors.toList());
}
protected static Object[] generateParam() {
UUID uuid = UUID.randomUUID();
return new Object[]{uuid, uuid.toString().substring(0, 5), (int) (Math.random() * 50)};
}
@Override
public void onTest(SQLManager sqlManager) throws SQLException {
List<Long> updates = sqlManager.createInsertBatch("test_user_table")
.setColumnNames("uuid", "username", "age")
.setAllParams(generateParams())
.returnGeneratedKeys(Long.class)
.execute();
System.out.println("changes " + Arrays.toString(updates.toArray()));
}
}
@@ -0,0 +1,24 @@
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;
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(Integer.class)
.execute();
System.out.println("generated " + Arrays.toString(generatedKeys.toArray()));
}
}
@@ -0,0 +1,35 @@
package cc.carm.lib.easysql.tests;
import cc.carm.lib.easysql.TestHandler;
import cc.carm.lib.easysql.api.SQLManager;
import cc.carm.lib.easysql.api.enums.NumberType;
import java.sql.SQLException;
public class TableAlterTest extends TestHandler {
@Override
public void onTest(SQLManager sqlManager) throws SQLException {
print(" 修改 test_user_table");
sqlManager.alterTable("test_user_table")
.addColumn("test", "VARCHAR(16) NOT NULL")
.execute();
sqlManager.alterTable("test_user_table")
.addColumn("test2", "VARCHAR(16) NOT NULL", "username")
.execute();
print(" 修改 test_user_info");
sqlManager.alterTable("test_user_info")
.addAutoIncrementColumn("num", NumberType.BIGINT, false, true)
.execute();
sqlManager.alterTable("test_user_info")
.addColumn("a", "VARCHAR(16) NOT NULL", "")
.execute();
}
}
@@ -0,0 +1,37 @@
package cc.carm.lib.easysql.tests;
import cc.carm.lib.easysql.TestHandler;
import cc.carm.lib.easysql.api.SQLManager;
import cc.carm.lib.easysql.api.enums.ForeignKeyRule;
import cc.carm.lib.easysql.api.enums.IndexType;
import java.sql.SQLException;
public class TableCreateTest extends TestHandler {
@Override
public void onTest(SQLManager sqlManager) throws SQLException {
print(" 创建 test_user_table");
sqlManager.createTable("test_user_table")
.addAutoIncrementColumn("id")
.addColumn("uuid", "VARCHAR(36) NOT NULL", "用户UUID")
.addColumn("username", "VARCHAR(16) NOT NULL", "用户名")
.addColumn("age", "TINYINT DEFAULT 0 NOT NULL", "年龄")
.setIndex("uuid", IndexType.UNIQUE_KEY)
.build().execute();
print(" 创建 test_user_info");
sqlManager.createTable("test_user_info")
.addColumn("uid", "INT UNSIGNED NOT NULL")
.addColumn("info", "TEXT", "相关信息")
.addForeignKey("uid", "user",
"test_user_table", "id",
ForeignKeyRule.CASCADE, ForeignKeyRule.CASCADE
)
.build().execute();
}
}
@@ -0,0 +1,16 @@
package cc.carm.lib.easysql.tests;
import cc.carm.lib.easysql.TestHandler;
import cc.carm.lib.easysql.api.SQLManager;
import java.sql.SQLException;
public class TableRenameTest extends TestHandler {
@Override
public void onTest(SQLManager sqlManager) throws SQLException {
print(" 重命名 test_user_table");
sqlManager.alterTable("test_user_table")
.renameTo("test_user_table2")
.execute();
}
}
+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>
@@ -1,145 +0,0 @@
package cc.carm.lib.easysql.api;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.sql.SQLException;
import java.util.UUID;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
/**
* SQLAction 是用于承载SQL语句并进行处理、返回的基本类。
*
* <ul>
* <li>同步执行 {@link #execute()}, {@link #execute(Function, BiConsumer)}</li>
* <br> 同步执行方法中有会抛出异常的方法与不抛出异常的方法,
* <br> 若选择不抛出异常,则返回值可能为空,需要特殊处理。
*
* <li>异步执行 {@link #executeAsync(Consumer, BiConsumer)}</li>
* <br> 异步执行时将提供成功与异常两种处理方式
* <br> 可自行选择是否对数据或异常进行处理
* <br> 默认的异常处理器为 {@link #defaultExceptionHandler()}
* </ul>
*
* <b>注意:</b> 无论是否异步,都不需要自行关闭ResultSet,本API已自动关闭
*
* @param <T> 需要返回的类型
* @author CarmJos
* @since 0.0.1
*/
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;
/**
* 执行语句并处理返回值
*
* @param function 处理方法
* @param exceptionHandler 异常处理器 默认为 {@link #defaultExceptionHandler()}
* @param <R> 需要返回的内容
* @return 指定类型数据
*/
@Nullable
default <R> R execute(@NotNull Function<T, R> function, @Nullable BiConsumer<SQLException, SQLAction<T>> exceptionHandler) {
T value = execute(exceptionHandler);
if (value == null) return null;
else return function.apply(value);
}
/**
* 执行语句并返回值
*
* @param exceptionHandler 异常处理器 默认为 {@link #defaultExceptionHandler()}
* @return 指定类型数据
*/
@Nullable
default T execute(@Nullable BiConsumer<SQLException, SQLAction<T>> exceptionHandler) {
if (exceptionHandler == null) exceptionHandler = defaultExceptionHandler();
T value = null;
try {
value = execute();
} catch (SQLException exception) {
exceptionHandler.accept(exception, this);
}
return value;
}
/**
* 异步执行SQL语句,采用默认异常处理,无需返回值。
*/
default void executeAsync() {
executeAsync(null);
}
/**
* 异步执行SQL语句
*
* @param success 成功时的操作
*/
default void executeAsync(@Nullable Consumer<T> success) {
executeAsync(success, null);
}
/**
* 异步执行SQL语句
*
* @param success 成功时的操作
* @param failure 异常处理器 默认为 {@link SQLAction#defaultExceptionHandler()}
*/
void executeAsync(@Nullable Consumer<T> success, @Nullable BiConsumer<SQLException, SQLAction<T>> failure);
/**
* @return 默认的异常处理器
*/
default BiConsumer<SQLException, SQLAction<T>> defaultExceptionHandler() {
return (exception, action) -> {
getManager().getLogger().severe("Error when execute [" + action.getSQLContent() + "]");
getManager().getLogger().severe(exception.getLocalizedMessage());
};
}
}
@@ -1,21 +0,0 @@
package cc.carm.lib.easysql.api;
import org.jetbrains.annotations.NotNull;
/**
* SQLBuilder 是用于构建SQL语句以生成SQLAction执行操作的中间类。
* <br> 其连接了{@link SQLManager} 与 {@link SQLAction} ,避免大量的代码堆积
* <br> 也是本接口的核心功能所在
*
* @author CarmJos
*/
public interface SQLBuilder {
/**
* 得到承载该Builder的对应{@link SQLManager}
*
* @return {@link SQLManager}
*/
@NotNull SQLManager getManager();
}
@@ -1,104 +0,0 @@
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.query.SQLQuery;
import cc.carm.lib.easysql.api.builder.*;
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.List;
import java.util.Map;
import java.util.UUID;
import java.util.logging.Logger;
public interface SQLManager {
Logger getLogger();
boolean isDebugMode();
void setDebugMode(boolean enable);
/**
* 得到连接池源
*
* @return DataSource
*/
@NotNull DataSource getDataSource();
/**
* 得到一个数据库连接实例
*
* @return Connection
*/
@NotNull Connection getConnection() throws SQLException;
/**
* 得到正使用的查询。
*
* @return 查询列表
*/
@NotNull Map<UUID, SQLQuery> getActiveQuery();
/**
* 执行一条不需要返回结果的SQL语句(多用于UPDATE、REPLACE、DELETE方法)
*
* @param sql SQL语句内容
* @return 更新的行数
*/
@Nullable Integer executeSQL(String sql);
/**
* 执行一条不需要返回结果的SQL更改(UPDATE、REPLACE、DELETE)
*
* @param sql SQL语句内容
* @return 更新的行数
*/
@Nullable Integer executeSQL(String sql, Object[] params);
/**
* 执行多条不需要返回结果的SQL更改(UPDATE、REPLACE、DELETE)
*
* @param sql SQL语句内容
* @return 对应参数返回的行数
*/
@Nullable List<Integer> executeSQLBatch(String sql, Iterable<Object[]> paramsBatch);
/**
* 执行多条不需要返回结果的SQL。
*
* @param sql SQL语句内容
* @return 对应参数返回的行数
*/
@Nullable List<Integer> executeSQLBatch(@NotNull String sql, String... moreSQL);
/**
* 执行多条不需要返回结果的SQL。
*
* @param sqlBatch SQL语句内容
* @return 对应参数返回的行数
*/
@Nullable List<Integer> executeSQLBatch(@NotNull Iterable<String> sqlBatch);
TableCreateBuilder createTable(@NotNull String tableName);
QueryBuilder createQuery();
InsertBuilder<PreparedSQLUpdateBatchAction> createInsertBatch(@NotNull String tableName);
InsertBuilder<PreparedSQLUpdateAction> createInsert(@NotNull String tableName);
ReplaceBuilder<PreparedSQLUpdateBatchAction> createReplaceBatch(@NotNull String tableName);
ReplaceBuilder<PreparedSQLUpdateAction> createReplace(@NotNull String tableName);
UpdateBuilder createUpdate(@NotNull String tableName);
DeleteBuilder createDelete(@NotNull String tableName);
}
@@ -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,44 +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 自增主键的序列
* 若该值 > 0,则 {@link #execute()} 返回自增主键数值
* 若该值 ≤ 0,则 {@link #execute()} 返回变更的行数
* @return {@link PreparedSQLUpdateBatchAction}
*/
PreparedSQLUpdateBatchAction setKeyIndex(int keyColumnIndex);
/**
* 默认主键序列的数值为 -1 (≤0) ,即默认返回发生变更的行数。
*
* @return 默认主键序列
*/
default PreparedSQLUpdateBatchAction defaultKeyIndex() {
return setKeyIndex(-1); // will return changed lines number
}
}
@@ -1,26 +0,0 @@
package cc.carm.lib.easysql.api.action;
import cc.carm.lib.easysql.api.SQLAction;
public interface SQLUpdateAction extends SQLAction<Integer> {
/**
* 设定自增主键的序列
*
* @param keyColumnIndex 自增主键的序列
* 若该值 > 0,则 {@link #execute()} 返回自增主键数值
* 若该值 ≤ 0,则 {@link #execute()} 返回变更的行数
* @return {@link SQLUpdateAction}
*/
SQLUpdateAction setKeyIndex(int keyColumnIndex);
/**
* 默认主键序列的数值为 -1 (≤0) ,即默认返回发生变更的行数。
*
* @return 默认主键序列
*/
default SQLUpdateAction defaultKeyIndex() {
return setKeyIndex(-1); // will return changed lines number
}
}
@@ -1,18 +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;
public interface SQLUpdateBatchAction extends SQLAction<List<Integer>> {
/**
* 添加一条批量执行的SQL语句
*
* @param sql SQL语句
* @return {@link SQLUpdateBatchAction}
*/
SQLUpdateBatchAction addBatch(@NotNull String sql);
}
@@ -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);
}
@@ -1,7 +0,0 @@
package cc.carm.lib.easysql.api.action.query;
import cc.carm.lib.easysql.api.SQLAction;
public interface QueryAction extends SQLAction<SQLQuery> {
}
@@ -1,50 +0,0 @@
package cc.carm.lib.easysql.api.action.query;
import cc.carm.lib.easysql.api.SQLManager;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
public interface SQLQuery extends AutoCloseable {
/**
* 获取该查询创建的时间
*
* @return 创建时间
*/
long getExecuteTime();
/**
* 得到承载该SQLQuery的对应{@link SQLManager}
*
* @return {@link SQLManager}
*/
SQLManager getManager();
/**
* 得到承载该SQLQuery的对应{@link QueryAction}
*
* @return {@link QueryAction} 或 {@link PreparedQueryAction}
*/
QueryAction getAction();
ResultSet getResultSet();
/**
* 得到设定的SQL语句
*
* @return SQL语句
*/
String getSQLContent();
/**
* 关闭所有内容
*/
void close();
Statement getStatement();
Connection getConnection();
}
@@ -1,42 +0,0 @@
package cc.carm.lib.easysql.api.builder;
import cc.carm.lib.easysql.api.SQLBuilder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Date;
import java.util.LinkedHashMap;
public interface ConditionalBuilder<T> extends SQLBuilder {
T build();
ConditionalBuilder<T> setLimit(int limit);
ConditionalBuilder<T> setConditions(@Nullable String condition);
ConditionalBuilder<T> setConditions(LinkedHashMap<@NotNull String, @Nullable Object> conditionSQLs);
ConditionalBuilder<T> addCondition(@Nullable String condition);
ConditionalBuilder<T> addCondition(@NotNull String queryName, @NotNull String operator, @Nullable Object queryValue);
default ConditionalBuilder<T> addCondition(@NotNull String queryName, @Nullable Object queryValue) {
return addCondition(queryName, "=", queryValue);
}
ConditionalBuilder<T> addCondition(@NotNull String[] queryNames, @Nullable Object[] queryValues);
ConditionalBuilder<T> addNotNullCondition(@NotNull String queryName);
default ConditionalBuilder<T> addTimeCondition(@NotNull String queryName, long startMillis, long endMillis) {
return addTimeCondition(queryName,
startMillis > 0 ? new Date(startMillis) : null,
endMillis > 0 ? new Date(endMillis) : null
);
}
ConditionalBuilder<T> addTimeCondition(@NotNull String queryName, @Nullable java.util.Date startDate, @Nullable java.util.Date endDate);
}
@@ -1,9 +0,0 @@
package cc.carm.lib.easysql.api.builder;
import cc.carm.lib.easysql.api.action.PreparedSQLUpdateAction;
public interface DeleteBuilder extends ConditionalBuilder<PreparedSQLUpdateAction> {
String getTableName();
}
@@ -1,19 +0,0 @@
package cc.carm.lib.easysql.api.builder;
import java.util.Arrays;
import java.util.List;
public interface InsertBuilder<T> {
String getTableName();
InsertBuilder<T> setTableName(String tableName);
T setColumnNames(List<String> columnNames);
default T setColumnNames(String... columnNames) {
return setColumnNames(columnNames == null ? null : Arrays.asList(columnNames));
}
}
@@ -1,36 +0,0 @@
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 org.jetbrains.annotations.NotNull;
public interface QueryBuilder extends SQLBuilder {
/**
* 通过一条 SQL语句创建查询
*
* @param sql SQL语句
* @return {@link QueryAction}
* @deprecated 存在SQL注入风险,请使用 {@link QueryBuilder#withPreparedSQL(String)}
*/
@Deprecated
QueryAction withSQL(@NotNull String sql);
/**
* 通过一条 SQL语句创建预查询
*
* @param sql SQL语句
* @return {@link PreparedQueryAction}
*/
PreparedQueryAction withPreparedSQL(@NotNull String sql);
/**
* 创建表查询
*
* @param tableName 表名
* @return {@link TableQueryBuilder}
*/
TableQueryBuilder inTable(@NotNull String tableName);
}
@@ -1,19 +0,0 @@
package cc.carm.lib.easysql.api.builder;
import java.util.Arrays;
import java.util.List;
public interface ReplaceBuilder<T> {
String getTableName();
ReplaceBuilder<T> setTableName(String tableName);
T setColumnNames(List<String> columnNames);
default T setColumnNames(String... columnNames) {
return setColumnNames(columnNames == null ? null : Arrays.asList(columnNames));
}
}
@@ -1,32 +0,0 @@
package cc.carm.lib.easysql.api.builder;
import cc.carm.lib.easysql.api.SQLBuilder;
import cc.carm.lib.easysql.api.action.SQLUpdateAction;
import org.jetbrains.annotations.NotNull;
public interface TableCreateBuilder extends SQLBuilder {
@NotNull String getTableName();
TableCreateBuilder setTableName(@NotNull String tableName);
@NotNull String getTableSettings();
TableCreateBuilder setTableSettings(@NotNull String settings);
SQLUpdateAction build();
default TableCreateBuilder addColumn(@NotNull String columnName, @NotNull String settings) {
return addColumn("`" + columnName + "` " + settings);
}
TableCreateBuilder addColumn(@NotNull String column);
TableCreateBuilder setColumns(@NotNull String... columns);
default TableCreateBuilder defaultTablesSettings() {
return setTableSettings("ENGINE=InnoDB DEFAULT CHARSET=utf8");
}
}
@@ -1,12 +0,0 @@
package cc.carm.lib.easysql.api.builder;
import cc.carm.lib.easysql.api.action.query.PreparedQueryAction;
import org.jetbrains.annotations.NotNull;
public interface TableQueryBuilder extends ConditionalBuilder<PreparedQueryAction> {
@NotNull String getTableName();
TableQueryBuilder selectColumns(@NotNull String... columnNames);
}
@@ -1,20 +0,0 @@
package cc.carm.lib.easysql.api.builder;
import cc.carm.lib.easysql.api.action.PreparedSQLUpdateAction;
import java.util.LinkedHashMap;
public interface UpdateBuilder extends ConditionalBuilder<PreparedSQLUpdateAction> {
String getTableName();
UpdateBuilder setColumnValues(LinkedHashMap<String, Object> columnData);
UpdateBuilder setColumnValues(String[] columnNames, Object[] columnValues);
default UpdateBuilder setColumnValues(String columnName, Object columnValue) {
return setColumnValues(new String[]{columnName}, new Object[]{columnValue});
}
}
@@ -1,4 +0,0 @@
package cc.carm.lib.easysql.api.builder;
public interface UpsertBuilder {
}
@@ -1,108 +0,0 @@
package cc.carm.lib.easysql.api.util;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TimeDateUtils {
public static DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public TimeDateUtils() {
}
/**
* 得到当前时间文本。
*
* @return 时间文本 格式{@link TimeDateUtils#getFormat()}
*/
public static String getCurrentTime() {
return getTimeString(System.currentTimeMillis());
}
/**
* 得到一个时间戳的文本
*
* @param timeMillis 时间戳
* @return 时间文本 格式{@link TimeDateUtils#getFormat()}
*/
public static String getTimeString(long timeMillis) {
return getFormat().format(new Date(timeMillis));
}
/**
* 得到一个日期时间的文本
*
* @param time 日期时间
* @return 时间文本 格式{@link TimeDateUtils#getFormat()}
*/
public static String getTimeString(Date time) {
return getFormat().format(time);
}
/**
* 得到一个时间文本的时间戳
*
* @param timeString 时间文本
* @return 时间戳 格式{@link TimeDateUtils#getFormat()}
*/
public static long parseTimeMillis(String timeString) {
if (timeString == null) {
return -1L;
} else {
try {
return format.parse(timeString).getTime();
} catch (ParseException var2) {
return -1L;
}
}
}
/**
* 得到一个时间文本的对应日期实例
*
* @param timeString 时间文本
* @return 日期实例 格式{@link TimeDateUtils#getFormat()}
*/
public static Date getTimeDate(String timeString) {
if (timeString == null) {
return null;
} else {
try {
return format.parse(timeString);
} catch (ParseException var2) {
return null;
}
}
}
/**
* 将秒数转化为 DD:hh:mm:ss 格式
*
* @param allSeconds 秒数
* @return DD:hh:mm:ss格式文本
*/
public static String toDHMSStyle(long allSeconds) {
long days = allSeconds / 86400L;
long hours = allSeconds % 86400L / 3600L;
long minutes = allSeconds % 3600L / 60L;
long seconds = allSeconds % 60L;
String DateTimes;
if (days > 0L) {
DateTimes = days + "" + (hours > 0L ? hours + "小时" : "") + (minutes > 0L ? minutes + "分钟" : "") + (seconds > 0L ? seconds + "" : "");
} else if (hours > 0L) {
DateTimes = hours + "小时" + (minutes > 0L ? minutes + "分钟" : "") + (seconds > 0L ? seconds + "" : "");
} else if (minutes > 0L) {
DateTimes = minutes + "分钟" + (seconds > 0L ? seconds + "" : "");
} else {
DateTimes = seconds + "";
}
return DateTimes;
}
public static DateFormat getFormat() {
return format;
}
}
@@ -1,15 +0,0 @@
package cc.carm.lib.easysql.api.util;
import java.util.UUID;
public class UUIDUtil {
public static UUID toUUID(String s) {
if (s.length() == 36) {
return UUID.fromString(s);
} else {
return UUID.fromString(s.substring(0, 8) + '-' + s.substring(8, 12) + '-' + s.substring(12, 16) + '-' + s.substring(16, 20) + '-' + s.substring(20));
}
}
}
-96
View File
@@ -1,96 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>easysql-parent</artifactId>
<groupId>cc.carm.lib</groupId>
<version>0.2.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>easysql-beecp</artifactId>
<packaging>jar</packaging>
<name>10-EasySQL-BeeCP</name>
<description>EasySQL的应用部分。此为BeeCP版本。</description>
<url>https://github.com/CarmJos/EasySQL</url>
<developers>
<developer>
<id>CarmJos</id>
<name>Carm Jos</name>
<email>carm@carm.cc</email>
<url>https://www.carm.cc</url>
<roles>
<role>Main Developer</role>
</roles>
</developer>
</developers>
<licenses>
<license>
<name>GNU General Public License v3.0</name>
<url>https://opensource.org/licenses/GPL-3.0</url>
</license>
</licenses>
<issueManagement>
<system>GitHub Issues</system>
<url>${project.url}/issues</url>
</issueManagement>
<ciManagement>
<system>GitHub Actions</system>
<url>${project.url}/actions/workflows/maven.yml</url>
</ciManagement>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</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>
</properties>
<dependencies>
<dependency>
<groupId>${project.parent.groupId}</groupId>
<artifactId>easysql-impl</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<!--项目地址 https://github.com/Chris2018998/BeeCP -->
<groupId>com.github.chris2018998</groupId>
<artifactId>beecp</artifactId>
<version>3.3.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
@@ -1,21 +0,0 @@
package cc.carm.lib.easysql;
import cc.carm.lib.easysql.manager.SQLManagerImpl;
import cn.beecp.BeeDataSource;
import cn.beecp.BeeDataSourceConfig;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class EasySQL {
public static SQLManagerImpl createManager(
@NotNull String driver, @NotNull String url,
@NotNull String username, @Nullable String password) {
return createManager(new BeeDataSourceConfig(driver, url, username, password));
}
public static SQLManagerImpl createManager(@NotNull BeeDataSourceConfig config) {
return new SQLManagerImpl(new BeeDataSource(config));
}
}
-80
View File
@@ -1,80 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>easysql-parent</artifactId>
<groupId>cc.carm.lib</groupId>
<version>0.2.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>easysql-demo</artifactId>
<packaging>jar</packaging>
<name>99-EasySQL-Demo</name>
<description>EasySQL的演示部分</description>
<url>https://github.com/CarmJos/EasySQL</url>
<developers>
<developer>
<id>CarmJos</id>
<name>Carm Jos</name>
<email>carm@carm.cc</email>
<url>https://www.carm.cc</url>
<roles>
<role>Main Developer</role>
</roles>
</developer>
</developers>
<licenses>
<license>
<name>GNU General Public License v3.0</name>
<url>https://opensource.org/licenses/GPL-3.0</url>
</license>
</licenses>
<issueManagement>
<system>GitHub Issues</system>
<url>${project.url}/issues</url>
</issueManagement>
<ciManagement>
<system>GitHub Actions</system>
<url>${project.url}/actions/workflows/maven.yml</url>
</ciManagement>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</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>
</properties>
<dependencies>
<dependency>
<groupId>${project.parent.groupId}</groupId>
<artifactId>easysql-impl</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
-113
View File
@@ -1,113 +0,0 @@
import cc.carm.lib.easysql.api.SQLManager;
import cc.carm.lib.easysql.api.action.query.SQLQuery;
import cc.carm.lib.easysql.api.util.TimeDateUtils;
import cc.carm.lib.easysql.api.util.UUIDUtil;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.UUID;
public class EasySQLDemo {
public void createTable(SQLManager sqlManager) {
// 同步创建表
sqlManager.createTable("users")
.addColumn("id", "INT(11) AUTO_INCREMENT NOT NULL PRIMARY KEY")
.addColumn("uuid", "VARCHAR(32) NOT NULL UNIQUE KEY")
.addColumn("username", "VARCHAR(16) NOT NULL UNIQUE KEY")
.addColumn("age", "INT(3) NOT NULL DEFAULT 1")
.addColumn("email", "VARCHAR(32)")
.addColumn("phone", "VARCHAR(16)")
.addColumn("registerTime", "DATETIME NOT NULL")
.build().execute(null /* 不处理错误 */);
}
public void sqlQuery(SQLManager sqlManager) {
// 同步SQL查询
try (SQLQuery query = sqlManager.createQuery()
.inTable("users") // 在users表中查询
.selectColumns("id", "name") // 选中 id 与 name列
.addCondition("age", ">", 18) // 限定 age 要大于5
.addCondition("email", null) // 限定查询 email 字段为空
.addNotNullCondition("phone") // 限定 phone 字段不为空
.addTimeCondition("registerTime", // 时间字段
System.currentTimeMillis() - 100000, //限制开始时间
-1//不限制结束时间
).build().execute()) {
ResultSet resultSet = query.getResultSet();
//do something
} catch (SQLException exception) {
exception.printStackTrace();
}
UUID userUUID = sqlManager.createQuery()
.inTable("users") // 在users表中查询
.selectColumns("uuid")
.addCondition("id", 5) // 限定 id 为 5
.setLimit(1) // 只取出一个数据
.build().execute(query -> {
//可以直接进行数据处理
ResultSet result = query.getResultSet();
try {
if (result != null && result.next()) {
return UUIDUtil.toUUID(result.getString("uuid"));
}
} catch (SQLException ignored) {
}
return null;
}, (exception, action) -> {
// 处理异常,不想处理直接填null
});
}
public void sqlQueryAsync(SQLManager sqlManager) {
// 异步SQL查询
sqlManager.createQuery()
.inTable("users") // 在users表中查询
.addCondition("id", 5) // 限定 id 为 5
.setLimit(1) // 只取出一个数据
.build().executeAsync(success -> {
ResultSet resultSet = success.getResultSet();
try {
if (resultSet != null && resultSet.next()) {
String username = resultSet.getString("username");
}
} catch (SQLException e) {
e.printStackTrace();
}
}, (exception, action) -> {
//do something
long createTIme = action.getCreateTime();
String shortID = action.getShortID();
String sqlContent = action.getSQLContent();
});
}
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())
.setKeyIndex(1) // 设定自增主键的index,将会在后续返回自增主键
.execute((exception, action) -> {
// 处理异常
System.out.println("#" + action.getShortID() + " -> " + action.getSQLContent());
exception.printStackTrace();
});
try {
Integer userID = sqlManager.createInsert("users")
.setColumnNames("username", "phone", "email", "registerTime")
.setParams("CarmJos", "18888888888", "carm@carm.cc", TimeDateUtils.getCurrentTime())
.setKeyIndex(1) // 设定自增主键的index,将会在后续返回自增主键
.execute();
System.out.println("新用户的ID为 " + userID);
} catch (SQLException exception) {
exception.printStackTrace();
}
}
}
@@ -1,32 +0,0 @@
package easysql;
import cc.carm.lib.easysql.manager.SQLManagerImpl;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Properties;
public class EasySQL {
public static SQLManagerImpl createManager(
@NotNull String driver, @NotNull String url,
@NotNull String username, @Nullable String password) {
HikariConfig config = new HikariConfig();
config.setDriverClassName(driver);
config.setJdbcUrl(url);
config.setUsername(username);
config.setPassword(password);
return createManager(config);
}
public static SQLManagerImpl createManager(@NotNull Properties properties) {
return createManager(new HikariConfig(properties));
}
public static SQLManagerImpl createManager(@NotNull HikariConfig config) {
return new SQLManagerImpl(new HikariDataSource(config));
}
}
@@ -1,95 +0,0 @@
package cc.carm.lib.easysql.action;
import cc.carm.lib.easysql.api.SQLAction;
import cc.carm.lib.easysql.manager.SQLManagerImpl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.sql.SQLException;
import java.util.UUID;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
public abstract class AbstractSQLAction<T> implements SQLAction<T> {
private final @NotNull SQLManagerImpl sqlManager;
private final @NotNull UUID uuid;
private final long createTime;
protected @NotNull String sqlContent;
protected @Nullable BiConsumer<SQLException, SQLAction<T>> exceptionHandler = null;
public AbstractSQLAction(@NotNull SQLManagerImpl manager, @NotNull String sql) {
this(manager, sql, System.currentTimeMillis());
}
public AbstractSQLAction(@NotNull SQLManagerImpl manager, @NotNull String sql, @NotNull UUID uuid) {
this(manager, sql, uuid, System.currentTimeMillis());
}
public AbstractSQLAction(@NotNull SQLManagerImpl manager, @NotNull String sql, long createTime) {
this(manager, sql, UUID.randomUUID(), createTime);
}
public AbstractSQLAction(@NotNull SQLManagerImpl manager, @NotNull String sql,
@NotNull UUID uuid, long createTime) {
this.sqlManager = manager;
this.sqlContent = sql;
this.uuid = uuid;
this.createTime = createTime;
}
@Override
public @NotNull UUID getActionUUID() {
return this.uuid;
}
@Override
public @NotNull String getShortID() {
return getActionUUID().toString().substring(0, 8);
}
@Override
public long getCreateTime() {
return this.createTime;
}
@Override
public @NotNull String getSQLContent() {
return this.sqlContent.trim();
}
@Override
public @NotNull SQLManagerImpl getManager() {
return this.sqlManager;
}
protected void outputDebugMessage() {
getManager().debug("#" + getShortID() + " ->" + getSQLContent());
}
public void handleException(SQLException exception) {
if (this.exceptionHandler == null) {
defaultExceptionHandler().accept(exception, this);
} else {
this.exceptionHandler.accept(exception, this);
}
}
@Override
public void executeAsync(Consumer<T> success, BiConsumer<SQLException, SQLAction<T>> failure) {
getManager().getExecutorPool().submit(() -> {
try {
T returnedValue = execute();
if (success != null) success.accept(returnedValue);
} catch (SQLException e) {
(failure == null ? defaultExceptionHandler() : failure).accept(e, this);
}
});
}
}
@@ -1,75 +0,0 @@
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.util.StatementUtil;
import org.jetbrains.annotations.NotNull;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collectors;
public class PreparedSQLBatchUpdateActionImpl extends SQLUpdateBatchActionImpl implements PreparedSQLUpdateBatchAction {
int keyIndex = -1;
List<Object[]> allParams;
public PreparedSQLBatchUpdateActionImpl(@NotNull SQLManagerImpl manager, @NotNull String sql) {
super(manager, sql);
this.allParams = new ArrayList<>();
}
@Override
public PreparedSQLUpdateBatchAction setAllParams(Iterable<Object[]> allParams) {
List<Object[]> paramsList = new ArrayList<>();
allParams.forEach(paramsList::add);
this.allParams = paramsList;
return this;
}
@Override
public PreparedSQLUpdateBatchAction addParamsBatch(Object[] params) {
this.allParams.add(params);
return this;
}
@Override
public PreparedSQLUpdateBatchAction setKeyIndex(int keyColumnIndex) {
this.keyIndex = keyColumnIndex;
return this;
}
@Override
public @NotNull List<Integer> execute() throws SQLException {
List<Integer> returnedValues;
Connection connection = getManager().getConnection();
PreparedStatement statement = StatementUtil.createPrepareStatementBatch(
connection, getSQLContent(), allParams, keyIndex > 0
);
outputDebugMessage();
if (keyIndex > 0) {
List<Integer> generatedKeys = new ArrayList<>();
ResultSet resultSet = statement.getGeneratedKeys();
if (resultSet != null) {
while (resultSet.next()) generatedKeys.add(resultSet.getInt(keyIndex));
resultSet.close();
}
returnedValues = generatedKeys;
} else {
int[] executed = statement.executeBatch();
returnedValues = Arrays.stream(executed).boxed().collect(Collectors.toList());
}
statement.close();
connection.close();
return returnedValues;
}
}
@@ -1,77 +0,0 @@
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.util.StatementUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class PreparedSQLUpdateActionImpl extends SQLUpdateActionImpl implements PreparedSQLUpdateAction {
Object[] params;
public PreparedSQLUpdateActionImpl(@NotNull SQLManagerImpl manager, @NotNull String sql) {
this(manager, 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 String sql,
@Nullable Object[] params) {
super(manager, sql);
this.params = params;
}
@Override
public PreparedSQLUpdateActionImpl setParams(Object[] params) {
this.params = params;
return this;
}
@Override
public PreparedSQLUpdateAction setParams(@Nullable Iterable<Object> params) {
if (params == null) {
return setParams((Object[]) null);
} else {
List<Object> paramsList = new ArrayList<>();
params.forEach(paramsList::add);
return setParams(paramsList.toArray());
}
}
@Override
public @NotNull Integer execute() throws SQLException {
int value = -1;
Connection connection = getManager().getConnection();
PreparedStatement statement = StatementUtil.createPrepareStatement(
connection, getSQLContent(), params, keyIndex > 0
);
outputDebugMessage();
if (keyIndex > 0) {
ResultSet resultSet = statement.getGeneratedKeys();
if (resultSet != null) {
if (resultSet.next()) value = resultSet.getInt(keyIndex);
resultSet.close();
}
} else {
value = statement.executeUpdate(getSQLContent());
}
statement.close();
connection.close();
return value;
}
}
@@ -1,53 +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;
import java.util.function.Consumer;
public class SQLUpdateActionImpl extends AbstractSQLAction<Integer> implements SQLUpdateAction {
int keyIndex = -1;
public SQLUpdateActionImpl(@NotNull SQLManagerImpl manager, @NotNull String sql) {
super(manager, sql);
}
@Override
public @NotNull Integer execute() throws SQLException {
int returnedValue = -1;
Connection connection = getManager().getConnection();
Statement statement = connection.createStatement();
outputDebugMessage();
if (keyIndex > 0) {
statement.executeUpdate(getSQLContent(), Statement.RETURN_GENERATED_KEYS);
ResultSet resultSet = statement.getGeneratedKeys();
if (resultSet != null) {
if (resultSet.next()) {
returnedValue = resultSet.getInt(keyIndex);
}
resultSet.close();
}
} else {
returnedValue = statement.executeUpdate(getSQLContent());
}
statement.close();
connection.close();
return returnedValue;
}
@Override
public SQLUpdateActionImpl setKeyIndex(int keyIndex) {
this.keyIndex = keyIndex;
return this;
}
}
@@ -1,54 +0,0 @@
package cc.carm.lib.easysql.action;
import cc.carm.lib.easysql.api.action.SQLUpdateBatchAction;
import cc.carm.lib.easysql.manager.SQLManagerImpl;
import org.jetbrains.annotations.NotNull;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class SQLUpdateBatchActionImpl extends AbstractSQLAction<List<Integer>> implements SQLUpdateBatchAction {
List<String> sqlContents = new ArrayList<>();
public SQLUpdateBatchActionImpl(@NotNull SQLManagerImpl manager, @NotNull String sql) {
super(manager, sql);
this.sqlContents.add(sql);
}
@Override
public @NotNull String getSQLContent() {
return this.sqlContents.stream()
.map(content -> "[" + content + "]" + " ")
.collect(Collectors.joining());
}
@Override
public SQLUpdateBatchAction addBatch(@NotNull String sql) {
this.sqlContents.add(sql);
return this;
}
@Override
public @NotNull List<Integer> execute() throws SQLException {
Connection connection = getManager().getConnection();
Statement statement = connection.createStatement();
outputDebugMessage();
for (String content : this.sqlContents) {
statement.addBatch(content);
}
int[] executed = statement.executeBatch();
List<Integer> returnedValues = Arrays.stream(executed).boxed().collect(Collectors.toList());
statement.close();
connection.close();
return returnedValues;
}
}
@@ -1,67 +0,0 @@
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.query.SQLQueryImpl;
import cc.carm.lib.easysql.util.StatementUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
public class PreparedQueryActionImpl extends QueryActionImpl implements PreparedQueryAction {
Consumer<PreparedStatement> handler;
Object[] params;
public PreparedQueryActionImpl(@NotNull SQLManagerImpl manager, @NotNull String sql) {
super(manager, sql);
}
@Override
public PreparedQueryActionImpl setParams(@Nullable Object[] params) {
this.params = params;
return this;
}
@Override
public PreparedQueryActionImpl setParams(@Nullable Iterable<Object> params) {
if (params == null) {
return setParams((Object[]) null);
} else {
List<Object> paramsList = new ArrayList<>();
params.forEach(paramsList::add);
return setParams(paramsList.toArray());
}
}
@Override
public PreparedQueryActionImpl handleStatement(@Nullable Consumer<PreparedStatement> statement) {
this.handler = statement;
return this;
}
@Override
public @NotNull SQLQueryImpl execute() throws SQLException {
Connection connection = getManager().getConnection();
getManager().debug("#" + getShortID() + " ->" + getSQLContent());
PreparedStatement preparedStatement;
if (handler == null) {
preparedStatement = StatementUtil.createPrepareStatement(connection, getSQLContent(), this.params);
} else {
preparedStatement = connection.prepareStatement(getSQLContent());
handler.accept(preparedStatement);
}
ResultSet resultSet = preparedStatement.executeQuery();
return new SQLQueryImpl(getManager(), this, connection, preparedStatement, resultSet);
}
}

Some files were not shown because too many files have changed in this diff Show More