mirror of
https://github.com/CarmJos/EasySQL.git
synced 2026-06-16 12:41:15 +08:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2c3818ea41 |
@@ -1,23 +0,0 @@
|
|||||||
# 欢迎使用 EasySQL !
|
|
||||||
|
|
||||||
这个项目刚刚创建,详细的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)
|
|
||||||
@@ -1,288 +0,0 @@
|
|||||||
> 本文档由 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 终究能找到继续生活下去的办法 :)
|
|
||||||
|
|
||||||
@@ -1,161 +0,0 @@
|
|||||||
> 本文档由 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) {
|
|
||||||
// 提示异常
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
```
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
# EasySQL Javadoc
|
|
||||||
|
|
||||||
基于 [Github Pages](https://pages.github.com/) 搭建,请访问 [JavaDoc](https://carmjos.github.io/EasySQL) 。
|
|
||||||
|
|
||||||
## 如何实现?
|
|
||||||
|
|
||||||
若您也想通过 [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) 。
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# 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/' }
|
|
||||||
}
|
|
||||||
```
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
github: [ CarmJos ]
|
|
||||||
custom: [ 'https://donate.carm.cc' ]
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
---
|
|
||||||
name: 问题提交
|
|
||||||
about: 描述问题并提交,帮助我们对其进行检查与修复。
|
|
||||||
title: ''
|
|
||||||
labels: bug
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### **问题简述**
|
|
||||||
|
|
||||||
用简短的话语描述一下大概问题。
|
|
||||||
|
|
||||||
### **问题来源**
|
|
||||||
|
|
||||||
描述一下通过哪些操作才发现的问题,如:
|
|
||||||
|
|
||||||
1. 使用了 '...'
|
|
||||||
2. 输入了 '....'
|
|
||||||
3. 出现了报错 '....'
|
|
||||||
|
|
||||||
### **预期结果** (可选)
|
|
||||||
|
|
||||||
如果问题不发生,应该是什么情况
|
|
||||||
|
|
||||||
### **问题截图/问题报错**
|
|
||||||
|
|
||||||
如果有报错或输出,请提供截图。
|
|
||||||
|
|
||||||
### **操作环境**
|
|
||||||
|
|
||||||
- 系统环境: `Windows 10` / `Ubuntu` / `...`
|
|
||||||
- Java版本: `JDK11` / `OPENJDK8` / `JRE8` / `...`
|
|
||||||
|
|
||||||
### **其他补充**
|
|
||||||
|
|
||||||
如有其他补充,可以在这里描述。
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
---
|
|
||||||
name: 功能需求
|
|
||||||
about: 希望我们提供更多的功能。
|
|
||||||
title: ''
|
|
||||||
labels: enhancement
|
|
||||||
assignees: ''
|
|
||||||
---
|
|
||||||
|
|
||||||
### **功能简述**
|
|
||||||
|
|
||||||
简单的描述一下你想要的功能
|
|
||||||
|
|
||||||
### **需求来源**
|
|
||||||
|
|
||||||
简单的描述一下为什么需要这个功能。
|
|
||||||
|
|
||||||
### **功能参考**(可选)
|
|
||||||
|
|
||||||
如果有相关功能的参考,如文本、截图,请提供给我们。
|
|
||||||
|
|
||||||
### **附加内容**
|
|
||||||
|
|
||||||
如果有什么小细节需要重点注意,请在这里告诉我们。
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
# 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"
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
-----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-----
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
# 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@v6
|
|
||||||
|
|
||||||
# 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@30783d03e758713bb5ed7b79292cfb14b9dd9a4a
|
|
||||||
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@v4
|
|
||||||
with:
|
|
||||||
sarif_file: results.sarif
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
# For most projects, this workflow file will not need changing; you simply need
|
|
||||||
# to commit it to your repository.
|
|
||||||
#
|
|
||||||
# You may wish to alter this file to override the set of languages analyzed,
|
|
||||||
# or to provide custom queries or build logic.
|
|
||||||
#
|
|
||||||
# ******** NOTE ********
|
|
||||||
# We have attempted to detect the languages in your repository. Please check
|
|
||||||
# the `language` matrix defined below to confirm you have the correct set of
|
|
||||||
# supported CodeQL languages.
|
|
||||||
#
|
|
||||||
name: "CodeQL Analysis"
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ master ]
|
|
||||||
pull_request:
|
|
||||||
# The branches below must be a subset of the branches above
|
|
||||||
branches: [ master ]
|
|
||||||
schedule:
|
|
||||||
- cron: '45 12 * * 1'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
analyze:
|
|
||||||
name: Analyze
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
actions: read
|
|
||||||
contents: read
|
|
||||||
security-events: write
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
language: [ 'java' ]
|
|
||||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
|
||||||
# Learn more about CodeQL language support at https://git.io/codeql-language-support
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v6
|
|
||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
|
||||||
- name: Initialize CodeQL
|
|
||||||
uses: github/codeql-action/init@v4
|
|
||||||
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@v4
|
|
||||||
|
|
||||||
# ℹ️ 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
|
|
||||||
|
|
||||||
#- run: |
|
|
||||||
# make bootstrap
|
|
||||||
# make release
|
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
|
||||||
uses: github/codeql-action/analyze@v4
|
|
||||||
@@ -1,138 +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: "Project Deploy"
|
|
||||||
|
|
||||||
on:
|
|
||||||
# 支持手动触发构建
|
|
||||||
workflow_dispatch:
|
|
||||||
release:
|
|
||||||
# 创建release的时候触发
|
|
||||||
types: [ published ]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
packages-deploy:
|
|
||||||
name: "Publish Project (GitHub Packages)"
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
- name: "Set up JDK"
|
|
||||||
uses: actions/setup-java@v5
|
|
||||||
with:
|
|
||||||
java-version: '11'
|
|
||||||
distribution: 'adopt'
|
|
||||||
cache: maven
|
|
||||||
server-id: github
|
|
||||||
server-username: MAVEN_USERNAME
|
|
||||||
server-password: MAVEN_TOKEN
|
|
||||||
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_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }}
|
|
||||||
|
|
||||||
central-deploy:
|
|
||||||
name: "Deploy Project (Central Repository)"
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
- name: "Set up JDK"
|
|
||||||
uses: actions/setup-java@v5
|
|
||||||
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@v6
|
|
||||||
- name: "Set up JDK"
|
|
||||||
uses: actions/setup-java@v5
|
|
||||||
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
|
|
||||||
@@ -1,32 +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: Project Build & Tests
|
|
||||||
|
|
||||||
on:
|
|
||||||
# 支持手动触发构建
|
|
||||||
workflow_dispatch:
|
|
||||||
pull_request:
|
|
||||||
push:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
- name: "Set up JDK"
|
|
||||||
uses: actions/setup-java@v5
|
|
||||||
with:
|
|
||||||
java-version: '11'
|
|
||||||
distribution: 'adopt'
|
|
||||||
- name: "Package"
|
|
||||||
run: mvn -B package --file pom.xml -Dgpg.skip
|
|
||||||
- name: "Target Stage"
|
|
||||||
run: mkdir staging && cp */target/*.jar staging
|
|
||||||
- name: "Upload artifact"
|
|
||||||
uses: actions/upload-artifact@v7
|
|
||||||
with:
|
|
||||||
name: Artifact
|
|
||||||
path: staging
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
/.idea/
|
|
||||||
**/target/
|
|
||||||
**.iml
|
|
||||||
demo/logs
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
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.
|
|
||||||
@@ -1,225 +1,27 @@
|
|||||||
```text
|
# EasySQL Repository
|
||||||
______ _____ ____ __
|
|
||||||
/ ____/___ ________ __ / ___// __ \ / /
|
|
||||||
/ __/ / __ `/ ___/ / / / \__ \/ / / / / /
|
|
||||||
/ /___/ /_/ (__ ) /_/ / ___/ / /_/ / / /___
|
|
||||||
/_____/\__,_/____/\__, / /____/\___\_\/_____/
|
|
||||||
/____/
|
|
||||||
```
|
|
||||||
|
|
||||||
# EasySQL
|
采用github的repo分支进行依赖,随项目发布而自动更新。
|
||||||
|
|
||||||
[](https://github.com/CarmJos/EasySQL/releases)
|
其他依赖方式见主页介绍。
|
||||||
[](https://opensource.org/licenses/MIT)
|
|
||||||
[](https://github.com/CarmJos/EasySQL/actions/workflows/maven.yml)
|
|
||||||
[](https://www.codefactor.io/repository/github/carmjos/easysql)
|
|
||||||

|
|
||||||

|
|
||||||
|
|
||||||
简单便捷的数据库操作工具,可自定义连接池来源。
|
## 依赖方式
|
||||||
|
|
||||||
随项目分别提供 [BeeCP](https://github.com/Chris2018998/BeeCP) 与 [Hikari](https://github.com/brettwooldridge/HikariCP)
|
### Maven
|
||||||
两个连接池的版本。
|
|
||||||
|
|
||||||
## 优势
|
|
||||||
|
|
||||||
- 基于JDBC开发,可自选连接池、JDBC驱动。
|
|
||||||
- 简单便捷的增删改查接口,无需手写SQL语句。
|
|
||||||
- 额外提供部分常用情况的SQL操作
|
|
||||||
- 自动关闭数据流
|
|
||||||
- 支持同步操作与异步操作
|
|
||||||
|
|
||||||
## 开发
|
|
||||||
|
|
||||||
详细开发介绍请 [点击这里](.documentation/README.md) , JavaDoc(最新Release) 请 [点击这里](https://carmjos.github.io/EasySQL) 。
|
|
||||||
|
|
||||||
### 示例代码
|
|
||||||
|
|
||||||
您可以 [点击这里](demo/src/main/java/EasySQLDemo.java) 查看部分代码演示,更多演示详见 [开发介绍](.documentation/README.md) 。
|
|
||||||
|
|
||||||
### 依赖方式
|
|
||||||
|
|
||||||
#### Maven 依赖
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>远程库配置</summary>
|
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
|
<repositories>
|
||||||
<project>
|
<repository>
|
||||||
<repositories>
|
<id>EasySQL</id>
|
||||||
|
<name>GitHub Branch Repository</name>
|
||||||
<repository>
|
<url>https://github.com/CarmJos/EasySQL/blob/repo/</url>
|
||||||
<!--采用Maven中心库,安全稳定,但版本更新需要等待同步-->
|
</repository>
|
||||||
<id>maven</id>
|
</repositories>
|
||||||
<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>
|
### Gradle
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>原生依赖</summary>
|
|
||||||
|
|
||||||
```xml
|
|
||||||
|
|
||||||
<project>
|
|
||||||
<dependencies>
|
|
||||||
<!--对于需要提供公共接口的项目,可以仅打包API部分,方便他人调用-->
|
|
||||||
<dependency>
|
|
||||||
<groupId>cc.carm.lib</groupId>
|
|
||||||
<artifactId>easysql-api</artifactId>
|
|
||||||
<version>[LATEST RELEASE]</version>
|
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!--如需自定义连接池,则可以仅打包实现部分,自行创建SQLManager-->
|
|
||||||
<dependency>
|
|
||||||
<groupId>cc.carm.lib</groupId>
|
|
||||||
<artifactId>easysql-impl</artifactId>
|
|
||||||
<version>[LATEST RELEASE]</version>
|
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
</dependencies>
|
|
||||||
</project>
|
|
||||||
```
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>含连接池版本</summary>
|
|
||||||
|
|
||||||
```xml
|
|
||||||
|
|
||||||
<project>
|
|
||||||
<dependencies>
|
|
||||||
<!--也可直接选择打包了连接池的版本-->
|
|
||||||
<dependency>
|
|
||||||
<groupId>cc.carm.lib</groupId>
|
|
||||||
<artifactId>easysql-beecp</artifactId>
|
|
||||||
<version>[LATEST VERSION]</version>
|
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>cc.carm.lib</groupId>
|
|
||||||
<artifactId>easysql-hikaricp</artifactId>
|
|
||||||
<version>[LATEST VERSION]</version>
|
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</project>
|
|
||||||
```
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
#### Gradle 依赖
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>远程库配置</summary>
|
|
||||||
|
|
||||||
```groovy
|
```groovy
|
||||||
repositories {
|
repositories {
|
||||||
|
|
||||||
// 采用Maven中心库,安全稳定,但版本更新需要等待同步
|
|
||||||
mavenCentral()
|
|
||||||
|
|
||||||
// 采用github的repo分支依赖,实时更新。 (推荐)
|
|
||||||
maven { url 'https://github.com/CarmJos/EasySQL/blob/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>
|
|
||||||
|
|
||||||
## 支持与捐赠
|
|
||||||
|
|
||||||
若您觉得本插件做的不错,您可以通过捐赠支持我!
|
|
||||||
|
|
||||||
感谢您对开源项目的支持!
|
|
||||||
|
|
||||||
## 开源协议
|
|
||||||
|
|
||||||
本项目源码采用 [The MIT License](https://opensource.org/licenses/MIT) 开源协议。
|
|
||||||
<details>
|
|
||||||
<summary>关于 MIT 协议</summary>
|
|
||||||
|
|
||||||
> MIT 协议可能是几大开源协议中最宽松的一个,核心条款是:
|
|
||||||
>
|
|
||||||
> 该软件及其相关文档对所有人免费,可以任意处置,包括使用,复制,修改,合并,发表,分发,再授权,或者销售。唯一的限制是,软件中必须包含上述版 权和许可提示。
|
|
||||||
>
|
|
||||||
> 这意味着:
|
|
||||||
> - 你可以自由使用,复制,修改,可以用于自己的项目。
|
|
||||||
> - 可以免费分发或用来盈利。
|
|
||||||
> - 唯一的限制是必须包含许可声明。
|
|
||||||
>
|
|
||||||
> MIT 协议是所有开源许可中最宽松的一个,除了必须包含许可声明外,再无任何限制。
|
|
||||||
>
|
|
||||||
> *以上文字来自 [五种开源协议GPL,LGPL,BSD,MIT,Apache](https://www.oschina.net/question/54100_9455) 。*
|
|
||||||
</details>
|
|
||||||
@@ -1,254 +0,0 @@
|
|||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,31 +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 {
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,324 +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.SQLUpdateAction;
|
|
||||||
import cc.carm.lib.easysql.api.action.SQLUpdateBatchAction;
|
|
||||||
import cc.carm.lib.easysql.api.builder.*;
|
|
||||||
import cc.carm.lib.easysql.api.function.SQLBiFunction;
|
|
||||||
import cc.carm.lib.easysql.api.function.SQLDebugHandler;
|
|
||||||
import cc.carm.lib.easysql.api.function.SQLExceptionHandler;
|
|
||||||
import cc.carm.lib.easysql.api.function.SQLFunction;
|
|
||||||
import cc.carm.lib.easysql.api.migrate.SQLMigrate;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.DatabaseMetaData;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SQLManager 是EasySQL的核心类,用于管理数据库连接,提供数据库操作的方法。
|
|
||||||
*
|
|
||||||
* @author CarmJos
|
|
||||||
*/
|
|
||||||
public interface SQLManager {
|
|
||||||
|
|
||||||
Logger getLogger();
|
|
||||||
|
|
||||||
boolean isDebugMode();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取用于执行 {@link SQLAction#executeAsync()} 的线程池。
|
|
||||||
* <br> 默认线程池为 {@link #defaultExecutorPool(String)} 。
|
|
||||||
*
|
|
||||||
* @return {@link ExecutorService}
|
|
||||||
*/
|
|
||||||
@NotNull ExecutorService getExecutorPool();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设定用于执行 {@link SQLAction#executeAsync()} 的线程池.
|
|
||||||
* <br> 默认线程池为 {@link #defaultExecutorPool(String)} 。
|
|
||||||
*
|
|
||||||
* @param executorPool {@link ExecutorService}
|
|
||||||
*/
|
|
||||||
void setExecutorPool(@NotNull ExecutorService executorPool);
|
|
||||||
|
|
||||||
static ExecutorService defaultExecutorPool(String threadName) {
|
|
||||||
return Executors.newFixedThreadPool(4, r -> {
|
|
||||||
Thread thread = new Thread(r, threadName);
|
|
||||||
thread.setDaemon(true);
|
|
||||||
return thread;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设定是否启用调试模式。
|
|
||||||
* 启用调试模式后,会在每次执行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);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取并操作 {@link DatabaseMetaData} 以得到需要的数据库消息。
|
|
||||||
*
|
|
||||||
* @param reader 操作与读取的方法
|
|
||||||
* @param <R> 最终结果的返回类型
|
|
||||||
* @return 最终结果,通过 {@link CompletableFuture#get()} 可阻塞并等待结果返回。
|
|
||||||
*/
|
|
||||||
default <R> CompletableFuture<R> fetchMetadata(@NotNull SQLFunction<DatabaseMetaData, R> reader) {
|
|
||||||
return fetchMetadata((meta, conn) -> reader.apply(meta));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取并操作 {@link DatabaseMetaData} 提供的指定 {@link ResultSet} 以得到需要的数据库消息。
|
|
||||||
* <br> 该方法会自动关闭 {@link ResultSet} 。
|
|
||||||
*
|
|
||||||
* @param supplier 操作 {@link DatabaseMetaData} 以提供信息所在的 {@link ResultSet}
|
|
||||||
* @param reader 读取 {@link ResultSet} 中指定信息的方法
|
|
||||||
* @param <R> 最终结果的返回类型
|
|
||||||
* @return 最终结果,通过 {@link CompletableFuture#get()} 可阻塞并等待结果返回。
|
|
||||||
* @throws NullPointerException 当 supplier 提供的 {@link ResultSet} 为NULL时抛出
|
|
||||||
*/
|
|
||||||
default <R> CompletableFuture<R> fetchMetadata(@NotNull SQLFunction<DatabaseMetaData, ResultSet> supplier,
|
|
||||||
@NotNull SQLFunction<@NotNull ResultSet, R> reader) {
|
|
||||||
return fetchMetadata((meta, conn) -> supplier.apply(meta), reader);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取并操作 {@link DatabaseMetaData} 以得到需要的数据库消息。
|
|
||||||
*
|
|
||||||
* @param reader 操作与读取的方法
|
|
||||||
* @param <R> 最终结果的返回类型
|
|
||||||
* @return 最终结果,通过 {@link CompletableFuture#get()} 可阻塞并等待结果返回。
|
|
||||||
*/
|
|
||||||
<R> CompletableFuture<R> fetchMetadata(@NotNull SQLBiFunction<DatabaseMetaData, Connection, R> reader);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取并操作 {@link DatabaseMetaData} 提供的指定 {@link ResultSet} 以得到需要的数据库消息。
|
|
||||||
* <br> 该方法会自动关闭 {@link ResultSet} 。
|
|
||||||
*
|
|
||||||
* @param supplier 操作 {@link DatabaseMetaData} 以提供信息所在的 {@link ResultSet}
|
|
||||||
* @param reader 读取 {@link ResultSet} 中指定信息的方法
|
|
||||||
* @param <R> 最终结果的返回类型
|
|
||||||
* @return 最终结果,通过 {@link CompletableFuture#get()} 可阻塞并等待结果返回。
|
|
||||||
* @throws NullPointerException 当 supplier 提供的 {@link ResultSet} 为NULL时抛出
|
|
||||||
*/
|
|
||||||
<R> CompletableFuture<R> fetchMetadata(@NotNull SQLBiFunction<DatabaseMetaData, Connection, ResultSet> supplier,
|
|
||||||
@NotNull SQLFunction<@NotNull ResultSet, R> reader);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 在库中创建一个表。
|
|
||||||
*
|
|
||||||
* @param tableName 表名
|
|
||||||
* @return {@link TableCreateBuilder}
|
|
||||||
*/
|
|
||||||
TableCreateBuilder createTable(@NotNull String tableName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 对库中的某个表执行更改。
|
|
||||||
*
|
|
||||||
* @param tableName 表名
|
|
||||||
* @return {@link TableAlterBuilder}
|
|
||||||
*/
|
|
||||||
TableAlterBuilder alterTable(@NotNull String tableName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 快速获取表的部分元数据。
|
|
||||||
* <br> 当需要获取其他元数据时,请使用 {@link #fetchMetadata(SQLFunction, SQLFunction)} 方法。
|
|
||||||
*
|
|
||||||
* @param tablePattern 表名通配符
|
|
||||||
* @return {@link TableMetadataBuilder}
|
|
||||||
*/
|
|
||||||
TableMetadataBuilder fetchTableMetadata(@NotNull String tablePattern);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新建一个查询。
|
|
||||||
*
|
|
||||||
* @return {@link QueryBuilder}
|
|
||||||
*/
|
|
||||||
QueryBuilder createQuery();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新建一个迁移操作。
|
|
||||||
*
|
|
||||||
* @return {@link SQLMigrate}
|
|
||||||
*/
|
|
||||||
SQLMigrate createMigrate();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建一条插入操作。
|
|
||||||
*
|
|
||||||
* @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);
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
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.SQLException;
|
|
||||||
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();
|
|
||||||
|
|
||||||
default boolean containsResult(String columnName) throws SQLException {
|
|
||||||
return getResultSet() != null && getResultSet().getObject(columnName) != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 得到设定的SQL语句
|
|
||||||
*
|
|
||||||
* @return SQL语句
|
|
||||||
*/
|
|
||||||
String getSQLContent();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 关闭所有内容
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
void close();
|
|
||||||
|
|
||||||
Statement getStatement();
|
|
||||||
|
|
||||||
Connection getConnection();
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,149 +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.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());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
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);
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
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);
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
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);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
package cc.carm.lib.easysql.api.action;
|
|
||||||
|
|
||||||
import cc.carm.lib.easysql.api.SQLAction;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@SuppressWarnings("UnusedReturnValue")
|
|
||||||
public interface SQLUpdateBatchAction extends SQLAction<List<Integer>> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加一条批量执行的SQL语句
|
|
||||||
*
|
|
||||||
* @param sql SQL语句
|
|
||||||
* @return {@link SQLUpdateBatchAction}
|
|
||||||
*/
|
|
||||||
SQLUpdateBatchAction addBatch(@NotNull String sql);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default @NotNull String getSQLContent() {
|
|
||||||
return getSQLContents().get(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull List<String> getSQLContents();
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
package cc.carm.lib.easysql.api.action.query;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
public interface PreparedQueryAction extends QueryAction {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设定SQL语句中所有 ? 对应的参数
|
|
||||||
*
|
|
||||||
* @param params 参数内容
|
|
||||||
* @return {@link PreparedQueryAction}
|
|
||||||
*/
|
|
||||||
PreparedQueryAction setParams(@Nullable Object... params);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设定SQL语句中所有 ? 对应的参数
|
|
||||||
*
|
|
||||||
* @param params 参数内容
|
|
||||||
* @return {@link PreparedQueryAction}
|
|
||||||
*/
|
|
||||||
PreparedQueryAction setParams(@Nullable Iterable<Object> params);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 直接对 {@link PreparedStatement} 进行处理
|
|
||||||
*
|
|
||||||
* @param statement {@link Consumer} 处理操作
|
|
||||||
* 若为空则不进行处理
|
|
||||||
* @return {@link PreparedQueryAction}
|
|
||||||
*/
|
|
||||||
PreparedQueryAction handleStatement(@Nullable Consumer<PreparedStatement> statement);
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
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);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
package cc.carm.lib.easysql.api.builder;
|
|
||||||
|
|
||||||
import cc.carm.lib.easysql.api.SQLAction;
|
|
||||||
|
|
||||||
public interface DeleteBuilder extends ConditionalBuilder<DeleteBuilder, SQLAction<Integer>> {
|
|
||||||
|
|
||||||
String getTableName();
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,37 +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语句创建查询。
|
|
||||||
* 该方法使用 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);
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,129 +0,0 @@
|
|||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,256 +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 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=utf8mb4";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
package cc.carm.lib.easysql.api.builder;
|
|
||||||
|
|
||||||
import cc.carm.lib.easysql.api.SQLBuilder;
|
|
||||||
import cc.carm.lib.easysql.api.function.SQLFunction;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.annotations.Unmodifiable;
|
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
|
|
||||||
public interface TableMetadataBuilder extends SQLBuilder {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return 本表是否存在
|
|
||||||
*/
|
|
||||||
CompletableFuture<Boolean> validateExist();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 对表内的数据列元数据进行读取
|
|
||||||
*
|
|
||||||
* @param columnPattern 列的名称匹配表达式, 为空则匹配所有列
|
|
||||||
* @param reader 读取的方法
|
|
||||||
* @param <R> 结果类型
|
|
||||||
* @return 读取结果
|
|
||||||
*/
|
|
||||||
<R> CompletableFuture<R> fetchColumns(@Nullable String columnPattern,
|
|
||||||
@NotNull SQLFunction<ResultSet, R> reader);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param columnPattern 需要判断的列名表达式
|
|
||||||
* @return 对应列是否存在
|
|
||||||
*/
|
|
||||||
CompletableFuture<Boolean> isColumnExists(@NotNull String columnPattern);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 列出所有表内的全部列。
|
|
||||||
*
|
|
||||||
* @return 表内全部数据列的列名
|
|
||||||
*/
|
|
||||||
default CompletableFuture<@Unmodifiable Set<String>> listColumns() {
|
|
||||||
return listColumns(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 列出所有满足表达式的列。
|
|
||||||
*
|
|
||||||
* @param columnPattern 列名表达式,为空则列出全部
|
|
||||||
* @return 所有满足表达式的列名
|
|
||||||
*/
|
|
||||||
CompletableFuture<@Unmodifiable Set<String>> listColumns(@Nullable String columnPattern);
|
|
||||||
|
|
||||||
// More coming soon.
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,37 +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<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);
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
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});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
package cc.carm.lib.easysql.api.builder;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 存在则更新,不存在则插入。
|
|
||||||
*
|
|
||||||
* @see ReplaceBuilder
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public interface UpsertBuilder {
|
|
||||||
|
|
||||||
String getTableName();
|
|
||||||
|
|
||||||
default UpsertBuilder setColumnNames(String[] columnNames, String updateColumn) {
|
|
||||||
throw new UnsupportedOperationException("Please use REPLACE .");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
package cc.carm.lib.easysql.api.enums;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 2022/11/28<br>
|
|
||||||
* EasySQL<br>
|
|
||||||
*
|
|
||||||
* @author huanmeng_qwq
|
|
||||||
*/
|
|
||||||
public class MigrateResult {
|
|
||||||
/**
|
|
||||||
* 旧表不存在
|
|
||||||
*/
|
|
||||||
public static final MigrateResult OLD_TABLE_NOT_EXIST = new MigrateResult(true);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新表已存在
|
|
||||||
*/
|
|
||||||
public static final MigrateResult NEW_TABLE_EXIST = new MigrateResult(false);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新表字段为空
|
|
||||||
*/
|
|
||||||
public static final MigrateResult NEW_COLUMN_EMPTY = new MigrateResult(false);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 旧表字段为在新表这设置对应的字段名
|
|
||||||
*/
|
|
||||||
public static final MigrateResult COLUMN_NOT_SET = new MigrateResult(false);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 迁移成功
|
|
||||||
*/
|
|
||||||
public static final MigrateResult SUCCESS = new MigrateResult(true);
|
|
||||||
|
|
||||||
private final boolean success;
|
|
||||||
private Throwable error;
|
|
||||||
|
|
||||||
MigrateResult(boolean success) {
|
|
||||||
this.success = success;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MigrateResult(boolean success, Throwable error) {
|
|
||||||
this.success = success;
|
|
||||||
this.error = error;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MigrateResult from(MigrateResult migrateResult, Throwable error) {
|
|
||||||
return new MigrateResult(migrateResult.success, error);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean success() {
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Throwable error() {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
package cc.carm.lib.easysql.api.enums;
|
|
||||||
|
|
||||||
public enum NumberType {
|
|
||||||
|
|
||||||
TINYINT,
|
|
||||||
SMALLINT,
|
|
||||||
MEDIUMINT,
|
|
||||||
INT,
|
|
||||||
BIGINT
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
package cc.carm.lib.easysql.api.function;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface SQLBiFunction<T, U, R> {
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
R apply(@NotNull T t, @NotNull U u) throws SQLException;
|
|
||||||
|
|
||||||
default <V> SQLBiFunction<T, U, V> then(@NotNull SQLFunction<? super R, ? extends V> after) {
|
|
||||||
Objects.requireNonNull(after);
|
|
||||||
return (T t, U u) -> {
|
|
||||||
R r = apply(t, u);
|
|
||||||
if (r == null) return null;
|
|
||||||
else return after.apply(r);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,100 +0,0 @@
|
|||||||
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("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
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) -> {
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
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);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
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);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
package cc.carm.lib.easysql.api.migrate;
|
|
||||||
|
|
||||||
import cc.carm.lib.easysql.api.enums.IndexType;
|
|
||||||
import cc.carm.lib.easysql.api.enums.MigrateResult;
|
|
||||||
import org.jetbrains.annotations.Contract;
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将现有的表结构与数据迁移之新的表中
|
|
||||||
*
|
|
||||||
* @author huanmeng_qwq
|
|
||||||
* @since 0.4.7
|
|
||||||
*/
|
|
||||||
public interface SQLMigrate {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 为迁移工作定义前后的表名信息
|
|
||||||
*
|
|
||||||
* @param oldTableName 旧表名
|
|
||||||
* @param newTableName 新表名
|
|
||||||
* @param newTableSettings 新表的设置
|
|
||||||
* @return {@link SQLMigrate}
|
|
||||||
*/
|
|
||||||
@Contract("null,_,_ -> fail;!null,_,_ -> this")
|
|
||||||
SQLMigrate tableName(String oldTableName, String newTableName, String newTableSettings);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 为迁移工作定义前后的列名信息
|
|
||||||
*
|
|
||||||
* @param oldColumnName 旧列名
|
|
||||||
* @param newColumnName 新列名
|
|
||||||
* @param newColumnSettings 新列的设置
|
|
||||||
* @return {@link SQLMigrate}
|
|
||||||
*/
|
|
||||||
@Contract("null,_,_ -> fail;!null,_,_ -> this")
|
|
||||||
default SQLMigrate column(String oldColumnName, String newColumnName, String newColumnSettings) {
|
|
||||||
return column(oldColumnName, newColumnName, newColumnSettings, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 为迁移工作定义前后的列名信息
|
|
||||||
*
|
|
||||||
* @param oldColumnName 旧列名
|
|
||||||
* @param newColumnName 新列名
|
|
||||||
* @param newColumnSettings 新列的设置
|
|
||||||
* @param indexType 索引类型
|
|
||||||
* @return {@link SQLMigrate}
|
|
||||||
*/
|
|
||||||
@Contract("null,_,_,_ -> fail;!null,_,_,_ -> this")
|
|
||||||
SQLMigrate column(String oldColumnName, String newColumnName, String newColumnSettings, IndexType indexType);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 为迁移工作定义前后的自增列名信息
|
|
||||||
*
|
|
||||||
* @param oldColumnName 旧列名
|
|
||||||
* @param newColumnName 新列名
|
|
||||||
* @return {@link SQLMigrate}
|
|
||||||
*/
|
|
||||||
@Contract("null,_->fail;!null,_ -> this")
|
|
||||||
SQLMigrate autoIncrementColumn(String oldColumnName, String newColumnName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 迁移数据
|
|
||||||
*
|
|
||||||
* @return {@link MigrateResult}
|
|
||||||
*/
|
|
||||||
MigrateResult migrate() throws SQLException;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
|||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iQGzBAABCgAdFiEEL6NL2WG27xbAlAIkh337tzeYbfcFAmQR4TsACgkQh337tzeY
|
||||||
|
bfdEBAv+IpWEqBosXCAlOHmZQiHn86RpfNCum/AG6Io7f/fidglnRPii83R0wTdR
|
||||||
|
0wGsDCmnfFUJ8U+aqPpYofin/eYuXHLrVmbZrcdugTuIiRoZPcRr1jEcoPXjVuj2
|
||||||
|
PzAryNBHnMvfVjE3hrBRqz8tgO8wt+pASPkdr4eodE0t6Ad9UKRE3pJ4Dadq4eqQ
|
||||||
|
exKxBYkJPiA+O1d38bLgd+GkLa9GjW4DmbtyPXmKt2BND/8QJhbwffdboaRprkyl
|
||||||
|
jM9kpDwt9N03x+FEOBjR6C/vRCawo/0BcF5Wk3QwptcNg+/0K6FLPhTKY9JhalC6
|
||||||
|
+D5cUx786piMTQRjunbiiXRp2Vv1WVFBZfCMl77/edTwq68ts2yfhJFl5cjYUqGP
|
||||||
|
avFJUcdIiPqpySOIBaGG8SnADcWk2TpHI/dnURa/vlXqOJj7ryvyPst3OMZrZDyg
|
||||||
|
X9lLsXYRT0f2MOGfp9TMjej2yI+ho2xaOP2cVOcuLoTX1S/xqVK4IINUVXxGGq0I
|
||||||
|
i+D0Bgdq
|
||||||
|
=y6Y6
|
||||||
|
-----END PGP SIGNATURE-----
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
baea323749589ae57aa84eb8d88b5f47
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
52cc39c8c8e3e5abbddfdfd8b88ded2b81f33c8a
|
||||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
|||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iQGzBAABCgAdFiEEL6NL2WG27xbAlAIkh337tzeYbfcFAmQR4ToACgkQh337tzeY
|
||||||
|
bfdfBAv+J3z4x6JXlKUarpvj9wKHVFlgj+4mlruiXHyMpRXhFdbzSrrDQHXQZp82
|
||||||
|
IGU/ubWOM3luE18MM0v+J0UjbREvVSrwFHVRctGCckOiJFy6ieQiMyG2/usz8Wcl
|
||||||
|
7uE2H7EyHK2gau32rC4yvGK2bE7Gh9dQvg9FGRatm+MHpEqCJdkf4LIM0K9JtlX6
|
||||||
|
zFwhkz6pctn4hQmfi0+F3rGgCfVdtakG1Lgv0wLxJ3jeOaa/GwY4miuS0EQbgn6y
|
||||||
|
0CyVORCdrBYEvPKDAyCizOhG5vQTyZqqUIWk5krhvFsX5T/QhzOuMyZn0GEE34tb
|
||||||
|
Xqf9MxDLanMVjbmMJoNrPltdEJU2o+KpLlzS/ksKmrUa4+A+x6ojbktAa9gwhMXT
|
||||||
|
eFkVvFzP/Ah8mRWd+rf9I0DozUT5GikNJvrMM/wMh5ecIECT01b/oTKUvH6aJLRn
|
||||||
|
JAJcs+Vm2wHIFzY772IHmyaL2YWuMpjeBakWuI63d9KD6DYARWHbdoHbg/xS5D6s
|
||||||
|
mI+QB3Zw
|
||||||
|
=ORtM
|
||||||
|
-----END PGP SIGNATURE-----
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
04f2334d79fd4a74468dba3a116ef033
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
b5fff16b0b091dcf4a649d2e70294bac7d2f2f80
|
||||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
|||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iQGzBAABCgAdFiEEL6NL2WG27xbAlAIkh337tzeYbfcFAmQR4ToACgkQh337tzeY
|
||||||
|
bff4ogv/S6JdIaUGohI8ZbzE0GxUPt2tW+DDw6b/MAvSY56MSfZXMYSXU2CiTMor
|
||||||
|
zsS4YxY783A8uF2VrV3uep6G2cPjerDqVLkclr3CclP7UIeTpx/NZflAWaLvXmzS
|
||||||
|
yXAqy9fL6mLAPQmlDqIzVmt+xS0Q5ZKzN/Z3Eq/dQcKhCkLhVDNisEz9xQWIIsFp
|
||||||
|
QxNLtdBAcozHod9YclJfH/PjwQcBJHmq5Heq1ulAQOz8FlrGqEhT9pnXDTRjEHWT
|
||||||
|
uQtuQr1lFZCR07aD4Ykvoj58jIkOrWW1h6HxTghGvJralnW808duBWYxZcaDx9E/
|
||||||
|
VUMjdlQ7AjdADS7ONr15norFNXSz57ubw1VVan6/djfZ2I62unNHZfe2uqhZwC8J
|
||||||
|
bcQdsBegS9EWnj/ecPHXRXqMOPhTgtoXIm8WW3h6u/zbOnPxDKQKsJrIQwwTrr+X
|
||||||
|
9f+J56ykJoT/gjm1KhEpXJOobeb3bSZDOJe/wLoXo+4mcqRWu4ZFXacTfRJHbA7p
|
||||||
|
RIHlC+l/
|
||||||
|
=TWDQ
|
||||||
|
-----END PGP SIGNATURE-----
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
bf49fdc1ccd87629a4b46b77d8d40777
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
cccfddf8a8b1a56bc9daa95aae2999a2d34755aa
|
||||||
@@ -56,7 +56,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>slf4j-api</artifactId>
|
<artifactId>slf4j-api</artifactId>
|
||||||
<version>2.0.17</version>
|
<version>1.7.36</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iQGzBAABCgAdFiEEL6NL2WG27xbAlAIkh337tzeYbfcFAmQR4ToACgkQh337tzeY
|
||||||
|
bfdvNQv+KPzCF72SRCAHt6XxtOkUey9oO6JFtJWkBy/h8ofGrVRwUuwcomCW8wfw
|
||||||
|
w2XlFXLKrTXj2oisjKWXGD1jwIKmS2nXrFCn2XiU6tyq6d9x4n9BA3od7fyS6QDP
|
||||||
|
BiG1Vf9h3klhpijBAot4uMDLVtfPlJp+5ZkCNK/AmwHjvja3PI/Ls+neohz+Dwxv
|
||||||
|
bSIq1dVeaWCaMwnLgkyn2sIzPv/tUC07EsurN+HF5TuTJy7f9WVFxpDJe7LjOBXj
|
||||||
|
UUW/4wPLz/tTXSObZivdFL/i7zNavQTqFIuCXPmS6wz4fO1382qZCOnmL03+WxE9
|
||||||
|
UQaPRa9tRW+Ft1bwsb8cFppylXtWBk94CuUux9vlZTIDbpYkKmw4eI7vFi069tUG
|
||||||
|
y0a5tOx41r1Sg0LC7DpuNES7mOeKzCOkmI8A150JXeoq0tHXyxlPu/CDzNJJHWPU
|
||||||
|
aYhrCAUR35Qs+KsDI0NHHT4CetnA81bKms9tmvlbovKngb/sRrTGy9s13+7RCpNc
|
||||||
|
tTwJjZFo
|
||||||
|
=jF85
|
||||||
|
-----END PGP SIGNATURE-----
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
f53956b9b0d8fc24a4867438cbcd56b5
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
7169aa1fafd3b401fe7892507ee3102d75e5acc3
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<metadata>
|
||||||
|
<groupId>cc.carm.lib</groupId>
|
||||||
|
<artifactId>easysql-api</artifactId>
|
||||||
|
<versioning>
|
||||||
|
<release>0.4.7</release>
|
||||||
|
<versions>
|
||||||
|
<version>0.4.7</version>
|
||||||
|
</versions>
|
||||||
|
<lastUpdated>20230315151602</lastUpdated>
|
||||||
|
</versioning>
|
||||||
|
</metadata>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
ed01effdd37438850973af46c8b83c3a
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
21ebe62b5d39ea00935d5c53800ed49425bdf845
|
||||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
|||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iQGzBAABCgAdFiEEL6NL2WG27xbAlAIkh337tzeYbfcFAmQR4UUACgkQh337tzeY
|
||||||
|
bffcNQv+JMHnQWdldkBEDcfRGWn4LxgM7fY9JpsDdevGtg+jS7FGmINeNDKC08Ll
|
||||||
|
Yc216FwatElgWG7+InXg7CVUZfmWTCGje+dm6wEQZEIYDgVtZ+t/xZ5GCmY3r72T
|
||||||
|
Yq4vSliq16zHr3C9TOD71jS0CkyCmvuFfV1c1YPjFwZRV3JI2eyLdIL6sP3h20dC
|
||||||
|
9Um1hYttBEuczbxaJbxw5fuxg10czLccgvFzLYbhARzg5ORum7UaGbecNWa1MHTy
|
||||||
|
aQGufwUDx+W9h9YC90c1PYEiGAxDGSdbc8GaF4+id2ekxefjMnGx34DYODy17vdq
|
||||||
|
I66f/SkQr5Ry0ETGFoIEXYcbxVK1JP+pSKSeWy9EYLEfCEQL1nMtkfLZhGJJD8Rx
|
||||||
|
RDWU5wBCl/N2hQPqXDMedcQRD3CaHnAnVmouitRFPMsszOfvrlr84SIcPpbGzxkM
|
||||||
|
+1C0n9ipNqUMX8reRm/Ny6fzsncvdrz+huv9+/as4SHY7PtFtg4REsWtaOsuLIOE
|
||||||
|
jul+iYdu
|
||||||
|
=P7Q3
|
||||||
|
-----END PGP SIGNATURE-----
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
9e9fde86918063f650fcfa3e479db37c
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
e475311b2169a097573cd90deec3f76476d35461
|
||||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
|||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iQGzBAABCgAdFiEEL6NL2WG27xbAlAIkh337tzeYbfcFAmQR4UUACgkQh337tzeY
|
||||||
|
bffUvwv/UoqhWFreHGNlUcqOxHyRGmwp5HI3crNrZMkYrN33AfX4sS2Z4qTPOjAQ
|
||||||
|
gnWcyVU+oq/Vl6x+gsO+aA8fEMNjEax728DNl4mJY79tgo7ink0cnOqePJAbqGzq
|
||||||
|
fY4/+6rsYpAhU+V9HnHyGdQoFbI4O2LN3NRUu+kvw1+PvAehyqDGOhagjufWuPtR
|
||||||
|
62AuQM8N0rIHW4aOiYdp1VcPlXl0e5pSLEksKnhOUQxrJPff/DDyxXZ5GtougzFd
|
||||||
|
AqmZwKFYtW7ePA7xcIUiCodE212dGsKA+bdrooBhSVd7xMYhhn0O3FRejd6qufx2
|
||||||
|
S2HO6xJpNHbxdo+QtZL97zburxH4WMcZlcagHLDVleqwr2Ywn3MIlhOKnSYeIIt2
|
||||||
|
aKa65oY01o13gdbStZsWvu1My63KNKdPAZdL/Q6n36EUlaxvIX4NismfV4l1zwYc
|
||||||
|
n0cH/PKJzF1bBop66YYQ73q9E0leJTX87HN1B4XCHhXzZrSwSJkLUazS4S8FmHit
|
||||||
|
J0lLibXG
|
||||||
|
=Z6i5
|
||||||
|
-----END PGP SIGNATURE-----
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
3ba40442139ac03bba0e08fcf54975a7
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
4f7a5625063af8b1a57ae7f75244a69c4d148dfa
|
||||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
|||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iQGzBAABCgAdFiEEL6NL2WG27xbAlAIkh337tzeYbfcFAmQR4UQACgkQh337tzeY
|
||||||
|
bfdw6wv+IlqUCIEEURElEq1iGSiGpyQCjMtDJ8daIZLXOinZTWYTxi90kW6hbSec
|
||||||
|
qiJC+Izr9Ijq0lpXSjTFtnBj+ubFiunht6axpCvNsEPxgaOZT2hruJYJcP7M8qcw
|
||||||
|
5IYcPH749sArG6uWiN28KvA2Gcd5L/TFM1QWcU+muLPK0HcwUKANJbqt8Qd6HXsA
|
||||||
|
QRfek9f00Ke98UbXUH6q7gSLdSL5rZPpvOb3ngRoR6hgek1Wx+nh3z3jhHfk6kgK
|
||||||
|
cgzQqAavbdZiZ43RAa0EiQ9139c5AseCqRugGa934iBFhthW3I1ZeXNK9hLAlpyB
|
||||||
|
qcheh6s7MT5ySNQnC/2L1s2Fcj8uMZSbS7T5z0WKhuqoI9O39H7dBZcBF5981yD9
|
||||||
|
8/jwfPOZNE57Hzy4UToVnHtJAzYWj0XJ1c1TZf1SmgRBH2AhRBi1K3T5h8fGaco+
|
||||||
|
PaSg7HL7BRFO4EKGkT1a2m/bc+MuVpolFSG9bmp3rvbCKDHFpowvxOCet0sB/hQp
|
||||||
|
cAzC+aPT
|
||||||
|
=VguQ
|
||||||
|
-----END PGP SIGNATURE-----
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
a29290293f9d58737e715895a7530691
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
fc1f9ee5138b302ab29cb3ab7434c713d5e41696
|
||||||
@@ -79,7 +79,7 @@
|
|||||||
<!--项目地址 https://github.com/Chris2018998/BeeCP -->
|
<!--项目地址 https://github.com/Chris2018998/BeeCP -->
|
||||||
<groupId>com.github.chris2018998</groupId>
|
<groupId>com.github.chris2018998</groupId>
|
||||||
<artifactId>beecp</artifactId>
|
<artifactId>beecp</artifactId>
|
||||||
<version>5.2.2</version>
|
<version>3.4.0</version>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
@@ -107,7 +107,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
<version>3.6.2</version>
|
<version>3.4.1</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<phase>package</phase>
|
<phase>package</phase>
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iQGzBAABCgAdFiEEL6NL2WG27xbAlAIkh337tzeYbfcFAmQR4UUACgkQh337tzeY
|
||||||
|
bfedgwv/fpxnWaRw4Go+AUoFxvM1TT4rM4qYB7xkhs0JoOBjbltw9lDKjwo8ZEX5
|
||||||
|
ENgkddVh86FtY9I6yLcDhsWs5ryWuXoGV9iHPQfunu0lPkag3q3rP9ZBUHWek/2H
|
||||||
|
Vn7Dl+o4DIwRBZkQcQgPeD0bLM3QzPz0hc2JFda3sGfQTvrppE4QBfel1/t04og4
|
||||||
|
K4WfP6dSfRRxtkPURORo6b/oW1JzzqfIs8q/OW+o3xpg39u2gG+/gzj9AME6wwos
|
||||||
|
iiqjMh0VUCkhjkYrjvty5AcamVfnKi/wkb09Bt+PGKHJMtRanXq9AC4w3+QgNdbF
|
||||||
|
mPn5RXzvt+LjreO8ATM8hGHKup+1eoxqO9AR0uED8oTHx0GRQkJGMVS/KSlRXRvr
|
||||||
|
BxvaN+X8cPpAmT+pz2gOa/AdcU21IrpF81/hJGMaAyrwgjfg0PfC5uPbcH/mI3bx
|
||||||
|
kvCcaTKuYWrO/R7WhsFYHMwGMVdOPR/uENHnCDYs2Q827cQesZY/kVhtf8LNxuMs
|
||||||
|
MArPSe29
|
||||||
|
=Lisk
|
||||||
|
-----END PGP SIGNATURE-----
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
06b886006846456247460368fccb29d0
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
f878ef57af4f68bc60fb8eabee3c37d7d2202c1a
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<metadata>
|
||||||
|
<groupId>cc.carm.lib</groupId>
|
||||||
|
<artifactId>easysql-beecp</artifactId>
|
||||||
|
<versioning>
|
||||||
|
<release>0.4.7</release>
|
||||||
|
<versions>
|
||||||
|
<version>0.4.7</version>
|
||||||
|
</versions>
|
||||||
|
<lastUpdated>20230315151602</lastUpdated>
|
||||||
|
</versioning>
|
||||||
|
</metadata>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
b8fdc0aa7e3c407f3290a1c2e5470e97
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
3b20670ad7051c1de44968818674bf639099a003
|
||||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
|||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iQGzBAABCgAdFiEEL6NL2WG27xbAlAIkh337tzeYbfcFAmQR4UoACgkQh337tzeY
|
||||||
|
bff70Qv9Fte5R2qW59TqkVJ+XoqUlz4D7ITZ05lPZums+5VCHyajmR8/ARVo8scC
|
||||||
|
vV0LbdnEtd8bZoOhuGt0JrAMZiHYFn09XXr8pvbKP/5aIXe3nHnm0f0nYDZeHiJc
|
||||||
|
weEJcq4Tu8IlVZzc5TVsuGpsAufU33aSdPvlbV6gNGkGFh3DbcDmjzpOWGAFpK+C
|
||||||
|
p4knA12fU8l0NB1RIlRTbnbAG9/4mGOQ2oa6dpsEidKzoS5gI1JB1f31fmsiEJ/c
|
||||||
|
dwH7RVz+o77cRmOcOlwhzNXL058lAMkMXF4BcdRH1MSlAGniyk6557FrMdlgu0fm
|
||||||
|
8H6IjFz85qcQhGU/fim39jTZPo8eEE0ioTmQ8DiqKHUSH0WGx8w0ycoFWtowptly
|
||||||
|
FMJyBsGNmz59br6inIVv1hzTCwdGoNEY7l5gZuET4T6C75H5Q+zKYmxH2o4QGPhe
|
||||||
|
5LluNj5EZ4qW/WCyW1Tx0/BqpmY6i66PWzypJvqZswpcbySzQ1NZ4m3xbEf7wUQB
|
||||||
|
7UbT3Rwl
|
||||||
|
=lA7G
|
||||||
|
-----END PGP SIGNATURE-----
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
6bf6d1dad3cc645311a377cee092854b
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
555424db5e9c0ef525f866da660fbe04d7cbfd98
|
||||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
|||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iQGzBAABCgAdFiEEL6NL2WG27xbAlAIkh337tzeYbfcFAmQR4UoACgkQh337tzeY
|
||||||
|
bfdm6gwArbsV6vmRD07bzKomu3ved6033uSJdpgbdIhH32hnXNFe/R6Cr1iZO1ft
|
||||||
|
r6uirBUOUOOhy3KFANlu5xK9Bc49BUig7ysxtWybOOrt2CUBDF6Qmu4IMvmlG+rd
|
||||||
|
RjLf+FUVPqeEv4KuLLi3Cd2FcNliaBE2uKd4Kc4+6avHq9eifpKNgMBg4peN1X5J
|
||||||
|
iCt/9irFJHR8oe8xqQhihZ5hY+wsRvkjyngKWq7Ua+1fM+Vw7IpmWNjQEB+nEh1F
|
||||||
|
4UAbktMd1jqM3bGtxYtk3H5fqfh5+WsdZVZHVT5m1uIDV1q9bQQ8HUCvXKxXWcIp
|
||||||
|
XNAw7903OMhiuW1ZbwrrY0KSDWkKnEyYpYXvb2lQRZWxC6SckA0n3fYxToJbyr2q
|
||||||
|
bK9RraofunY0PBVt66nSa6Q1VIgyzP/D7gnWHae1+jOG+uMOQw03fDlUPdAjUoPX
|
||||||
|
b3dUlIj/kFImYya7VxT6fnYiOHmX7/Jm8ZLPOW4setw1wtE9IuIMzqtiJSHL6mOO
|
||||||
|
JG6DphEN
|
||||||
|
=JpXU
|
||||||
|
-----END PGP SIGNATURE-----
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
d85f800d68d3c979785cc1c49487f788
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
313014723857ca21c41867a0c7b70089a1e3b0c7
|
||||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
|||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iQGzBAABCgAdFiEEL6NL2WG27xbAlAIkh337tzeYbfcFAmQR4UkACgkQh337tzeY
|
||||||
|
bfe9dgwAsxn1rxt7jhC1RVcVuXI4lpmQNbQd85YbfB2DssOlt0Nq1G91dbrZDMHy
|
||||||
|
s7Z5xwjA0W75PPQaeQUO8k8MhhGyq7PSPHd45ZZQr9FMEMBo6T7pNCzhrelKcOji
|
||||||
|
1gl2oDmY+IEtCAbcmcVl36YhekzQxiIaUlKXoH8dzyX2DTZ0ESID6jRdPMLHaJVx
|
||||||
|
h15sD/Ya5oxXrjur178sbJ4Rxc1m6NiJjGJ6ZqzjQcXFYwMHHegPRH/5esbxRjUK
|
||||||
|
SmM9v/fMfpcsJ0c9IHo3TwZVFw7nnWL8052CrONNOWtkZ8HKV0NF9Wwq/ZH5dCGb
|
||||||
|
7MGa1hzBEkl+nNK9Y886+JhXnD23JsqNRvJU06Qb/kNqf7/kWNOcshz+XAk9Rl7l
|
||||||
|
swgj1YPwMR2sp4W85DbzHwoXubQNxx4c9CJ/XhTwTx3M3RnjKwZKQ0135Ice5xJ2
|
||||||
|
eJpIFOxrzwgYp/bc6QjibKVK9PtkK0pxicGPw0045hy46i3pzZMJHXBiQt13TzW/
|
||||||
|
xDvIsWyY
|
||||||
|
=4TQu
|
||||||
|
-----END PGP SIGNATURE-----
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user