From 4f8384ee883f3aa4cd2fb92315cff5a5f2cc833e Mon Sep 17 00:00:00 2001 From: wangyu <727842003@qq.com> Date: Wed, 1 Mar 2023 11:12:28 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E7=BC=93=E5=AD=98?= =?UTF-8?q?=E6=9C=BA=E5=88=B6=EF=BC=8Csql=E5=9C=A8=E7=94=9F=E5=91=BD?= =?UTF-8?q?=E5=91=A8=E6=9C=9F=E5=86=85=E4=BB=85=E6=9E=84=E5=BB=BA=E4=B8=80?= =?UTF-8?q?=E6=AC=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../group/flyfish/fluent/chain/SQLImpl.java | 12 +++++-- .../chain/select/AfterOrderSqlChain.java | 5 ++- .../fluent/utils/cache/BoundObject.java | 20 ++++++++++++ .../fluent/utils/cache/CachedWrapper.java | 23 ++++++++++++++ .../flyfish/fluent/utils/sql/SqlMethod.java | 18 +++++++++++ .../flyfish/framework/FluentJdbcTest.java | 11 ++++--- .../framework/cases/AbstractTestCase.java | 17 +++++----- .../framework/cases/FluentSqlTestCase.java | 31 +++++++++++-------- 8 files changed, 107 insertions(+), 30 deletions(-) create mode 100644 fluent-sql-core/src/main/java/group/flyfish/fluent/utils/cache/BoundObject.java create mode 100644 fluent-sql-core/src/main/java/group/flyfish/fluent/utils/cache/CachedWrapper.java create mode 100644 fluent-sql-core/src/main/java/group/flyfish/fluent/utils/sql/SqlMethod.java diff --git a/fluent-sql-core/src/main/java/group/flyfish/fluent/chain/SQLImpl.java b/fluent-sql-core/src/main/java/group/flyfish/fluent/chain/SQLImpl.java index ed6e01d..c79e2ac 100644 --- a/fluent-sql-core/src/main/java/group/flyfish/fluent/chain/SQLImpl.java +++ b/fluent-sql-core/src/main/java/group/flyfish/fluent/chain/SQLImpl.java @@ -14,6 +14,7 @@ import group.flyfish.fluent.query.Parameterized; import group.flyfish.fluent.query.Query; import group.flyfish.fluent.update.Update; import group.flyfish.fluent.update.UpdateImpl; +import group.flyfish.fluent.utils.cache.CachedWrapper; import group.flyfish.fluent.utils.context.AliasComposite; import group.flyfish.fluent.utils.data.ParameterUtils; import group.flyfish.fluent.utils.sql.ConcatSegment; @@ -25,6 +26,7 @@ import org.springframework.util.Assert; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.function.Supplier; import java.util.stream.Collectors; /** @@ -42,6 +44,9 @@ final class SQLImpl extends ConcatSegment implements SQLOperations, Pre // 主表class,默认是第一个from的表为主表 private Class primaryClass; + // sql实体提供者 + private final Supplier entity = CachedWrapper.wrap(this::entity); + /** * 绑定实现类 * @@ -190,7 +195,7 @@ final class SQLImpl extends ConcatSegment implements SQLOperations, Pre * @param 泛型 */ public T one(Class clazz) { - return SHARED_OPERATIONS.selectOne(entity(), clazz); + return SHARED_OPERATIONS.selectOne(entity.get(), clazz); } @Override @@ -206,7 +211,7 @@ final class SQLImpl extends ConcatSegment implements SQLOperations, Pre */ @Override public List list(Class clazz) { - return SHARED_OPERATIONS.select(entity(), clazz); + return SHARED_OPERATIONS.select(entity.get(), clazz); } /** @@ -265,6 +270,7 @@ final class SQLImpl extends ConcatSegment implements SQLOperations, Pre * @return 转换结果 */ private SQLEntity entity() { - return SQLEntity.of(this::sql, this::parsedParameters); + return SQLEntity.of(CachedWrapper.wrap(this::sql), this::parsedParameters); } + } diff --git a/fluent-sql-core/src/main/java/group/flyfish/fluent/chain/select/AfterOrderSqlChain.java b/fluent-sql-core/src/main/java/group/flyfish/fluent/chain/select/AfterOrderSqlChain.java index c0673e0..c3d94d0 100644 --- a/fluent-sql-core/src/main/java/group/flyfish/fluent/chain/select/AfterOrderSqlChain.java +++ b/fluent-sql-core/src/main/java/group/flyfish/fluent/chain/select/AfterOrderSqlChain.java @@ -14,7 +14,7 @@ public interface AfterOrderSqlChain extends ExecutableSql { /** * 执行并获取结果 * - * @param 泛型 + * @param 泛型 * @return 单一结果值 */ T one(); @@ -31,7 +31,7 @@ public interface AfterOrderSqlChain extends ExecutableSql { /** * 执行并获取多条结果,以主表class为结果 * - * @param 结果泛型 + * @param 结果泛型 * @return 结果列表 */ List list(); @@ -44,5 +44,4 @@ public interface AfterOrderSqlChain extends ExecutableSql { * @return 结果列表 */ List list(Class clazz); - } diff --git a/fluent-sql-core/src/main/java/group/flyfish/fluent/utils/cache/BoundObject.java b/fluent-sql-core/src/main/java/group/flyfish/fluent/utils/cache/BoundObject.java new file mode 100644 index 0000000..7cd1c18 --- /dev/null +++ b/fluent-sql-core/src/main/java/group/flyfish/fluent/utils/cache/BoundObject.java @@ -0,0 +1,20 @@ +package group.flyfish.fluent.utils.cache; + +import java.util.function.Supplier; + +/** + * 绑定的单值对象 + * + * @param 泛型 + */ +public class BoundObject { + + private T object; + + public T computeIfAbsent(Supplier supplier) { + if (null == object) { + object = supplier.get(); + } + return object; + } +} diff --git a/fluent-sql-core/src/main/java/group/flyfish/fluent/utils/cache/CachedWrapper.java b/fluent-sql-core/src/main/java/group/flyfish/fluent/utils/cache/CachedWrapper.java new file mode 100644 index 0000000..e155d15 --- /dev/null +++ b/fluent-sql-core/src/main/java/group/flyfish/fluent/utils/cache/CachedWrapper.java @@ -0,0 +1,23 @@ +package group.flyfish.fluent.utils.cache; + +import java.util.function.Supplier; + +/** + * 缓存的supplier + * + * @author wangyu + */ +public interface CachedWrapper { + + /** + * 包装简单的supplier + * + * @param supplier 提供者 + * @param 泛型 + * @return 结果 + */ + static Supplier wrap(Supplier supplier) { + BoundObject object = new BoundObject<>(); + return () -> object.computeIfAbsent(supplier); + } +} diff --git a/fluent-sql-core/src/main/java/group/flyfish/fluent/utils/sql/SqlMethod.java b/fluent-sql-core/src/main/java/group/flyfish/fluent/utils/sql/SqlMethod.java new file mode 100644 index 0000000..972ffd1 --- /dev/null +++ b/fluent-sql-core/src/main/java/group/flyfish/fluent/utils/sql/SqlMethod.java @@ -0,0 +1,18 @@ +package group.flyfish.fluent.utils.sql; + +/** + * sql方法,用于缓存执行 + * + * @param 返回值泛型 + */ +@FunctionalInterface +public interface SqlMethod { + + /** + * 执行方法 + * + * @param parameters 参数 + * @return 结果 + */ + R execute(Object... parameters); +} diff --git a/fluent-sql-spring-jdbc/src/test/java/group/flyfish/framework/FluentJdbcTest.java b/fluent-sql-spring-jdbc/src/test/java/group/flyfish/framework/FluentJdbcTest.java index e1ae872..dd32b55 100644 --- a/fluent-sql-spring-jdbc/src/test/java/group/flyfish/framework/FluentJdbcTest.java +++ b/fluent-sql-spring-jdbc/src/test/java/group/flyfish/framework/FluentJdbcTest.java @@ -37,18 +37,21 @@ public class FluentJdbcTest { new Driver(), "jdbc:mysql://127.0.0.1:3306/epi_project?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=Asia/Shanghai", "root", - "oI3WtMO8h%mSYARp" + "Unicom#2018" // "oI3WtMO8h%mSYARp" ); // 准备待测试用例 List> cases = Arrays.asList( + // jdbc测试 new JdbcTestCase(dataSource), + // Mybatis测试 new MybatisTestCase(dataSource), - new FluentSqlTestCase(dataSource) + // FluentSQL测试 + new FluentSqlTestCase(dataSource), + // 单表测试 + new SingleTableTestCase() ); // 执行测试 cases.forEach(TestCase::test); - // 单表测试 - new SingleTableTestCase().test(); } /** diff --git a/fluent-sql-spring-jdbc/src/test/java/group/flyfish/framework/cases/AbstractTestCase.java b/fluent-sql-spring-jdbc/src/test/java/group/flyfish/framework/cases/AbstractTestCase.java index 695e62c..13e69d1 100644 --- a/fluent-sql-spring-jdbc/src/test/java/group/flyfish/framework/cases/AbstractTestCase.java +++ b/fluent-sql-spring-jdbc/src/test/java/group/flyfish/framework/cases/AbstractTestCase.java @@ -43,20 +43,23 @@ public abstract class AbstractTestCase implements TestCase { Name anno = getClass().getAnnotation(Name.class); assert anno != null; String name = anno.value(); - long current = System.currentTimeMillis(); - T result = null; + print("=====准备执行任务《{0}》=====", name); try { - result = run(); + long current = System.currentTimeMillis(); + T result = run(); print("【初次执行】执行任务《{0}》用时:{1}ms", name, System.currentTimeMillis() - current); - current = System.currentTimeMillis(); - result = run(); + for (int i = 0; i < 10; i ++) { + current = System.currentTimeMillis(); + result = run(); + print("【正常执行】执行任务《{0}》用时:{1}ms", name, System.currentTimeMillis() - current); + } + printResult(result); return result; } catch (Exception e) { print("执行失败!{0}", e.getMessage()); throw new RuntimeException(e); } finally { - print("【正常执行】执行任务《{0}》用时:{1}ms", name, System.currentTimeMillis() - current); - printResult(result); + print("=====完成执行任务《{0}》====="); } } } diff --git a/fluent-sql-spring-jdbc/src/test/java/group/flyfish/framework/cases/FluentSqlTestCase.java b/fluent-sql-spring-jdbc/src/test/java/group/flyfish/framework/cases/FluentSqlTestCase.java index f4acd9b..209e63b 100644 --- a/fluent-sql-spring-jdbc/src/test/java/group/flyfish/framework/cases/FluentSqlTestCase.java +++ b/fluent-sql-spring-jdbc/src/test/java/group/flyfish/framework/cases/FluentSqlTestCase.java @@ -1,7 +1,8 @@ package group.flyfish.framework.cases; -import group.flyfish.fluent.debug.FluentSqlDebugger; +import group.flyfish.fluent.chain.select.AfterWhereSqlChain; import group.flyfish.fluent.operations.JdbcTemplateFluentSQLOperations; +import group.flyfish.fluent.utils.cache.CachedWrapper; import group.flyfish.framework.TestCase; import group.flyfish.framework.entity.SaasOrder; import group.flyfish.framework.entity.SaasPlan; @@ -11,6 +12,7 @@ import org.springframework.jdbc.core.JdbcTemplate; import javax.sql.DataSource; import java.util.List; +import java.util.function.Supplier; import static group.flyfish.fluent.chain.SQL.select; import static group.flyfish.fluent.chain.select.SelectComposite.composite; @@ -19,6 +21,8 @@ import static group.flyfish.fluent.query.Query.where; @TestCase.Name("使用fluent-sql") public class FluentSqlTestCase extends AbstractTestCase> { + private AfterWhereSqlChain sql; + public FluentSqlTestCase(DataSource dataSource) { super(dataSource); } @@ -32,6 +36,18 @@ public class FluentSqlTestCase extends AbstractTestCase> { public void initialize() throws Exception { // 基于构造器自动绑定注册,在实际应用中使用@Bean声明即可,可参考下面的demo new JdbcTemplateFluentSQLOperations(new JdbcTemplate(dataSource)); + // 缓存构建结果 + this.sql = select( + // 查询租户全量字段 + composite(SaasTenant::getId, SaasTenant::getName, SaasTenant::getIdentifier, SaasTenant::getDatasource, + SaasTenant::getStorage, SaasTenant::getStatus, SaasTenant::getEnable), + // 查询套餐 + composite(SaasOrder::getQuotaConfig, SaasOrder::getOrderTime, SaasOrder::getExpireTime, + SaasOrder::getOrderType)) + .from(SaasTenant.class) + .leftJoin(SaasOrder.class).on(where(SaasOrder::getTenantId).eq(SaasTenant::getId)) + .leftJoin(SaasPlan.class).on(where(SaasPlan::getId).eq(SaasOrder::getPlanId)) + .matching(where(SaasTenant::getEnable).eq(true)); // 启用调试 // FluentSqlDebugger.enable(); } @@ -45,17 +61,6 @@ public class FluentSqlTestCase extends AbstractTestCase> { @Override public List run() throws Exception { // 一个平平无奇的查询 - return select( - // 查询租户全量字段 - composite(SaasTenant::getId, SaasTenant::getName, SaasTenant::getIdentifier, SaasTenant::getDatasource, - SaasTenant::getStorage, SaasTenant::getStatus, SaasTenant::getEnable), - // 查询套餐 - composite(SaasOrder::getQuotaConfig, SaasOrder::getOrderTime, SaasOrder::getExpireTime, - SaasOrder::getOrderType)) - .from(SaasTenant.class) - .leftJoin(SaasOrder.class).on(where(SaasOrder::getTenantId).eq(SaasTenant::getId)) - .leftJoin(SaasPlan.class).on(where(SaasPlan::getId).eq(SaasOrder::getPlanId)) - .matching(where(SaasTenant::getEnable).eq(true)) - .list(TenantContext.class); + return sql.list(TenantContext.class); } }