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 41c49b2..05bb368 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 @@ -3,17 +3,19 @@ package group.flyfish.fluent.chain; import group.flyfish.fluent.chain.common.AfterJoinSqlChain; import group.flyfish.fluent.chain.common.HandleSqlChain; import group.flyfish.fluent.chain.common.PreSqlChain; -import group.flyfish.fluent.chain.execution.BoundEntity; +import group.flyfish.fluent.chain.execution.BoundEntitySpec; import group.flyfish.fluent.chain.execution.BoundProxy; -import group.flyfish.fluent.chain.execution.ReactiveBoundEntity; +import group.flyfish.fluent.chain.execution.ReactiveBoundEntitySpec; import group.flyfish.fluent.chain.select.AfterOrderSqlChain; import group.flyfish.fluent.chain.select.AfterWhereSqlChain; import group.flyfish.fluent.chain.select.PieceSqlChain; import group.flyfish.fluent.chain.update.AfterSetSqlChain; import group.flyfish.fluent.debug.FluentSqlDebugger; +import group.flyfish.fluent.entity.BoundSQLEntity; import group.flyfish.fluent.entity.DataPage; import group.flyfish.fluent.entity.SQLEntity; import group.flyfish.fluent.operations.FluentSQLOperations; +import group.flyfish.fluent.operations.ReactiveFluentSQLOperations; import group.flyfish.fluent.query.JoinCandidate; import group.flyfish.fluent.query.Parameterized; import group.flyfish.fluent.query.Query; @@ -48,6 +50,8 @@ final class SQLImpl extends ConcatSegment implements SQLOperations, Pre // 共享的操作 private static FluentSQLOperations SHARED_OPERATIONS; + private static ReactiveFluentSQLOperations SHARED_REACTIVE_OPERATIONS; + // 参数map,有序 private final List parameters = new ArrayList<>(); @@ -55,7 +59,7 @@ final class SQLImpl extends ConcatSegment implements SQLOperations, Pre private Class primaryClass; // sql实体提供者 - private final Supplier entity = wrap(this::toEntity); + private final Supplier entity = wrap(this::entity); /** * 绑定实现类 @@ -66,6 +70,16 @@ final class SQLImpl extends ConcatSegment implements SQLOperations, Pre SHARED_OPERATIONS = operations; } + + /** + * 绑定实现类 + * + * @param operations r2dbc操作 + */ + public static void bind(ReactiveFluentSQLOperations operations) { + SHARED_REACTIVE_OPERATIONS = operations; + } + /** * 查询起手 * @@ -172,8 +186,10 @@ final class SQLImpl extends ConcatSegment implements SQLOperations, Pre * @return 处理链 */ @Override - public BoundProxy next() { - return new DefaultBoundProxy<>(SQLEntity.of(primaryClass, this::sql, this::parsedParameters)); + @SuppressWarnings("unchecked") + public BoundProxy fetch() { + // 通过主类构建实体 + return new DefaultBoundProxy<>(BoundSQLEntity.of(this.entity, (Class) primaryClass)); } /** @@ -211,7 +227,7 @@ final class SQLImpl extends ConcatSegment implements SQLOperations, Pre */ @Override public BoundProxy as(Class type) { - return new DefaultBoundProxy<>(SQLEntity.of(type, wrap(this::sql), wrap(this::parsedParameters))); + return new DefaultBoundProxy<>(BoundSQLEntity.of(this.entity, type)); } /** @@ -254,6 +270,15 @@ final class SQLImpl extends ConcatSegment implements SQLOperations, Pre return false; } + /** + * 将本实体转换为sql实体 + * + * @return 转换结果 + */ + private SQLEntity entity() { + return SQLEntity.of(wrap(this::sql), wrap(this::parsedParameters)); + } + @Override public PieceSqlChain limit(int count) { return concat("LIMIT").concat(String.valueOf(count)); @@ -267,16 +292,16 @@ final class SQLImpl extends ConcatSegment implements SQLOperations, Pre @RequiredArgsConstructor private static class DefaultBoundProxy implements BoundProxy { - private final SQLEntity entity; + private final BoundSQLEntity entity; @Override - public BoundEntity block() { - return new DefaultBoundEntity<>(); + public BoundEntitySpec block() { + return new DefaultBoundEntitySpec<>(entity); } @Override - public ReactiveBoundEntity reactive() { - return new DefaultReactiveBoundEntity<>(); + public ReactiveBoundEntitySpec reactive() { + return new DefaultReactiveBoundEntitySpec<>(entity); } } @@ -285,49 +310,60 @@ final class SQLImpl extends ConcatSegment implements SQLOperations, Pre * * @param */ - private static class DefaultBoundEntity implements BoundEntity { + @RequiredArgsConstructor + private static class DefaultBoundEntitySpec implements BoundEntitySpec { + + private final BoundSQLEntity entity; @Override public T one() { - return null; + return SHARED_OPERATIONS.selectOne(entity); } @Override public List all() { - return List.of(); + return SHARED_OPERATIONS.select(entity); } @Override public DataPage page() { - return null; + return SHARED_OPERATIONS.selectPage(entity); } @Override public int execute() { - return 0; + return SHARED_OPERATIONS.execute(entity); } } - private static class DefaultReactiveBoundEntity implements ReactiveBoundEntity { + /** + * 默认的异步绑定实体 + * + * @param 泛型 + */ + @RequiredArgsConstructor + private static class DefaultReactiveBoundEntitySpec implements ReactiveBoundEntitySpec { + + private final BoundSQLEntity entity; @Override public Mono one() { - return null; + return SHARED_REACTIVE_OPERATIONS.selectOne(entity); } @Override public Flux all() { - return null; + return SHARED_REACTIVE_OPERATIONS.select(entity); } @Override public Mono> page() { - return null; + return SHARED_REACTIVE_OPERATIONS.selectPage(entity); } @Override public Mono execute() { - return null; + return SHARED_REACTIVE_OPERATIONS.execute(entity); } } } diff --git a/fluent-sql-core/src/main/java/group/flyfish/fluent/chain/common/ExecutableSql.java b/fluent-sql-core/src/main/java/group/flyfish/fluent/chain/common/ExecutableSql.java index c5d0bf6..92e1a40 100644 --- a/fluent-sql-core/src/main/java/group/flyfish/fluent/chain/common/ExecutableSql.java +++ b/fluent-sql-core/src/main/java/group/flyfish/fluent/chain/common/ExecutableSql.java @@ -1,6 +1,5 @@ package group.flyfish.fluent.chain.common; -import group.flyfish.fluent.chain.execution.BoundProxy; /** * 可执行的sql @@ -9,11 +8,5 @@ import group.flyfish.fluent.chain.execution.BoundProxy; */ public interface ExecutableSql { - /** - * 进入下一步,以主表作为输出结果 - * - * @param 泛型 - * @return 绑定操作 - */ - BoundProxy next(); + } diff --git a/fluent-sql-core/src/main/java/group/flyfish/fluent/chain/execution/BoundEntity.java b/fluent-sql-core/src/main/java/group/flyfish/fluent/chain/execution/BoundEntitySpec.java similarity index 96% rename from fluent-sql-core/src/main/java/group/flyfish/fluent/chain/execution/BoundEntity.java rename to fluent-sql-core/src/main/java/group/flyfish/fluent/chain/execution/BoundEntitySpec.java index 6bd6212..244e031 100644 --- a/fluent-sql-core/src/main/java/group/flyfish/fluent/chain/execution/BoundEntity.java +++ b/fluent-sql-core/src/main/java/group/flyfish/fluent/chain/execution/BoundEntitySpec.java @@ -11,8 +11,7 @@ import java.util.List; * * @author wangyu */ -public interface BoundEntity { - +public interface BoundEntitySpec { /** * 执行一条sql,并且序列化为对象 diff --git a/fluent-sql-core/src/main/java/group/flyfish/fluent/chain/execution/BoundProxy.java b/fluent-sql-core/src/main/java/group/flyfish/fluent/chain/execution/BoundProxy.java index 782498f..23265a5 100644 --- a/fluent-sql-core/src/main/java/group/flyfish/fluent/chain/execution/BoundProxy.java +++ b/fluent-sql-core/src/main/java/group/flyfish/fluent/chain/execution/BoundProxy.java @@ -12,13 +12,13 @@ public interface BoundProxy { * * @return 结果 */ - BoundEntity block(); + BoundEntitySpec block(); /** * 异步数据库逻辑 * * @return 结果 */ - ReactiveBoundEntity reactive(); + ReactiveBoundEntitySpec reactive(); } diff --git a/fluent-sql-core/src/main/java/group/flyfish/fluent/chain/execution/ReactiveBoundEntity.java b/fluent-sql-core/src/main/java/group/flyfish/fluent/chain/execution/ReactiveBoundEntitySpec.java similarity index 95% rename from fluent-sql-core/src/main/java/group/flyfish/fluent/chain/execution/ReactiveBoundEntity.java rename to fluent-sql-core/src/main/java/group/flyfish/fluent/chain/execution/ReactiveBoundEntitySpec.java index bac1f09..075be2d 100644 --- a/fluent-sql-core/src/main/java/group/flyfish/fluent/chain/execution/ReactiveBoundEntity.java +++ b/fluent-sql-core/src/main/java/group/flyfish/fluent/chain/execution/ReactiveBoundEntitySpec.java @@ -11,7 +11,7 @@ import reactor.core.publisher.Mono; * * @author wangyu */ -public interface ReactiveBoundEntity { +public interface ReactiveBoundEntitySpec { /** * 执行一条sql,并且序列化为对象 diff --git a/fluent-sql-core/src/main/java/group/flyfish/fluent/chain/select/FetchSqlChain.java b/fluent-sql-core/src/main/java/group/flyfish/fluent/chain/select/FetchSqlChain.java index 0df60d4..94047e6 100644 --- a/fluent-sql-core/src/main/java/group/flyfish/fluent/chain/select/FetchSqlChain.java +++ b/fluent-sql-core/src/main/java/group/flyfish/fluent/chain/select/FetchSqlChain.java @@ -3,13 +3,21 @@ package group.flyfish.fluent.chain.select; import group.flyfish.fluent.chain.common.ExecutableSql; import group.flyfish.fluent.chain.execution.BoundProxy; -import java.util.List; - public interface FetchSqlChain extends ExecutableSql { + /** + * 使用主表进行下一步操作 + * + * @param 泛型 + * @return 结果 + */ + BoundProxy fetch(); + /** * 转换为SQL实体 * + * @param type 具体结果类型 + * @param 泛型 * @return 结果 */ BoundProxy as(Class type); diff --git a/fluent-sql-core/src/main/java/group/flyfish/fluent/entity/BoundSQLEntity.java b/fluent-sql-core/src/main/java/group/flyfish/fluent/entity/BoundSQLEntity.java new file mode 100644 index 0000000..4d20a36 --- /dev/null +++ b/fluent-sql-core/src/main/java/group/flyfish/fluent/entity/BoundSQLEntity.java @@ -0,0 +1,37 @@ +package group.flyfish.fluent.entity; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.springframework.lang.NonNull; + +import java.util.function.Supplier; + +@RequiredArgsConstructor(access = AccessLevel.PRIVATE) +public class BoundSQLEntity implements Supplier { + + @NonNull + private final Supplier entity; + + // 结果类型 + @NonNull + @Getter + private final Class resultType; + + public static BoundSQLEntity of(Supplier entity, Class resultType) { + return new BoundSQLEntity<>(entity, resultType); + } + + @Override + public String get() { + return entity.get().getSql(); + } + + public String getSql() { + return entity.get().getSql(); + } + + public Object[] getParameters() { + return entity.get().getParameters(); + } +} diff --git a/fluent-sql-core/src/main/java/group/flyfish/fluent/entity/SQLEntity.java b/fluent-sql-core/src/main/java/group/flyfish/fluent/entity/SQLEntity.java index 943c483..f65020e 100644 --- a/fluent-sql-core/src/main/java/group/flyfish/fluent/entity/SQLEntity.java +++ b/fluent-sql-core/src/main/java/group/flyfish/fluent/entity/SQLEntity.java @@ -1,6 +1,5 @@ package group.flyfish.fluent.entity; -import lombok.Getter; import org.springframework.lang.NonNull; import java.util.function.Supplier; @@ -8,10 +7,9 @@ import java.util.function.Supplier; /** * sql运行实体 * - * @param 结果类型泛型 * @author wangyu */ -public class SQLEntity { +public class SQLEntity { private static final Supplier EMPTY_PARAMETERS = () -> new Object[]{}; @@ -22,23 +20,17 @@ public class SQLEntity { // sql参数表提供者 private final Supplier parameters; - // 结果类型 - @NonNull - @Getter - private final Class resultType; - - private SQLEntity(Class resultType, Supplier sql, Supplier parameters) { - this.resultType = resultType; + private SQLEntity(Supplier sql, Supplier parameters) { this.sql = sql; this.parameters = parameters; } - public static SQLEntity of(Class resultType, Supplier sqlProvider) { - return of(resultType, sqlProvider, EMPTY_PARAMETERS); + public static SQLEntity of(Supplier sqlProvider) { + return of(sqlProvider, EMPTY_PARAMETERS); } - public static SQLEntity of(Class resultType, Supplier sql, Supplier parameters) { - return new SQLEntity(resultType, sql, parameters); + public static SQLEntity of(Supplier sql, Supplier parameters) { + return new SQLEntity(sql, parameters); } public String getSql() { diff --git a/fluent-sql-core/src/main/java/group/flyfish/fluent/operations/FluentSQLOperations.java b/fluent-sql-core/src/main/java/group/flyfish/fluent/operations/FluentSQLOperations.java index 06f8581..e87479b 100644 --- a/fluent-sql-core/src/main/java/group/flyfish/fluent/operations/FluentSQLOperations.java +++ b/fluent-sql-core/src/main/java/group/flyfish/fluent/operations/FluentSQLOperations.java @@ -1,7 +1,7 @@ package group.flyfish.fluent.operations; +import group.flyfish.fluent.entity.BoundSQLEntity; import group.flyfish.fluent.entity.DataPage; -import group.flyfish.fluent.entity.SQLEntity; import org.springframework.lang.Nullable; import java.util.List; @@ -23,7 +23,7 @@ public interface FluentSQLOperations { * @return 查询结果 */ @Nullable - T selectOne(SQLEntity entity); + T selectOne(BoundSQLEntity entity); /** * 执行一条sql,并且查询出所有行 @@ -32,7 +32,7 @@ public interface FluentSQLOperations { * @param 目标泛型 * @return 返回的列表 */ - List select(SQLEntity entity); + List select(BoundSQLEntity entity); /** * 分页查询 @@ -41,7 +41,7 @@ public interface FluentSQLOperations { * @param 目标泛型 * @return 返回的分页对象 */ - DataPage selectPage(SQLEntity entity); + DataPage selectPage(BoundSQLEntity entity); /** * 直接执行sql,根据update count返回更新行数,如果是查询,永远返回0 @@ -49,5 +49,5 @@ public interface FluentSQLOperations { * @param entity sql实体 * @return 更新行数 */ - int execute(SQLEntity entity); + int execute(BoundSQLEntity entity); } diff --git a/fluent-sql-core/src/main/java/group/flyfish/fluent/operations/ReactiveFluentSQLOperations.java b/fluent-sql-core/src/main/java/group/flyfish/fluent/operations/ReactiveFluentSQLOperations.java index f6568f2..a42c94f 100644 --- a/fluent-sql-core/src/main/java/group/flyfish/fluent/operations/ReactiveFluentSQLOperations.java +++ b/fluent-sql-core/src/main/java/group/flyfish/fluent/operations/ReactiveFluentSQLOperations.java @@ -1,5 +1,6 @@ package group.flyfish.fluent.operations; +import group.flyfish.fluent.entity.BoundSQLEntity; import group.flyfish.fluent.entity.DataPage; import group.flyfish.fluent.entity.SQLEntity; import org.springframework.lang.Nullable; @@ -23,7 +24,7 @@ public interface ReactiveFluentSQLOperations { * @return 查询结果 */ @Nullable - Mono selectOne(SQLEntity entity); + Mono selectOne(BoundSQLEntity entity); /** * 执行一条sql,并且查询出所有行 @@ -32,7 +33,7 @@ public interface ReactiveFluentSQLOperations { * @param 目标泛型 * @return 返回的列表 */ - Flux select(SQLEntity entity); + Flux select(BoundSQLEntity entity); /** * 分页查询 @@ -41,7 +42,7 @@ public interface ReactiveFluentSQLOperations { * @param 目标泛型 * @return 返回的分页对象 */ - Mono> selectPage(SQLEntity entity); + Mono> selectPage(BoundSQLEntity entity); /** * 直接执行sql,根据update count返回更新行数,如果是查询,永远返回0 @@ -49,5 +50,5 @@ public interface ReactiveFluentSQLOperations { * @param entity sql实体 * @return 更新行数 */ - Mono execute(SQLEntity entity); + Mono execute(BoundSQLEntity entity); } 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 deleted file mode 100644 index 7cd1c18..0000000 --- a/fluent-sql-core/src/main/java/group/flyfish/fluent/utils/cache/BoundObject.java +++ /dev/null @@ -1,20 +0,0 @@ -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 index e155d15..95586f9 100644 --- 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 @@ -4,6 +4,7 @@ import java.util.function.Supplier; /** * 缓存的supplier + * 组件内部通过该核心逻辑缓存编译的sql * * @author wangyu */ @@ -20,4 +21,22 @@ public interface CachedWrapper { BoundObject object = new BoundObject<>(); return () -> object.computeIfAbsent(supplier); } + + /** + * 绑定的单值对象 + * + * @param 泛型 + */ + class BoundObject { + + private T object; + + public T computeIfAbsent(Supplier supplier) { + if (null == object) { + object = supplier.get(); + } + return object; + } + } + } diff --git a/fluent-sql-spring/src/main/java/group/flyfish/fluent/mapping/.gitkeep b/fluent-sql-spring/src/main/java/group/flyfish/fluent/mapping/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/fluent-sql-spring/src/main/java/group/flyfish/fluent/mapping/MappingBean.java b/fluent-sql-spring/src/main/java/group/flyfish/fluent/mapping/MappingBean.java new file mode 100644 index 0000000..29d51d5 --- /dev/null +++ b/fluent-sql-spring/src/main/java/group/flyfish/fluent/mapping/MappingBean.java @@ -0,0 +1,112 @@ +package group.flyfish.fluent.mapping; + +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.BeanWrapper; +import org.springframework.beans.BeanWrapperImpl; +import org.springframework.core.convert.ConversionService; +import org.springframework.core.convert.support.DefaultConversionService; +import org.springframework.util.ClassUtils; +import org.springframework.util.StringUtils; + +import java.beans.PropertyDescriptor; +import java.util.function.BiFunction; +import java.util.function.Supplier; +import java.util.function.UnaryOperator; + +/** + * 映射中的bean + */ +@Setter +@Slf4j +class MappingBean { + + private final T instance; + + private final MappingDescriptor descriptor; + + private final BeanWrapper bw; + + private boolean logged; + + private Supplier conversionService = DefaultConversionService::getSharedInstance; + + private UnaryOperator propertyTransformer = UnaryOperator.identity(); + + private BiFunction transformer = (column, value) -> value; + + /** + * 创建实例 + * + * @return 结果 + */ + static MappingBean create(MappingDescriptor descriptor) { + T instance = BeanUtils.instantiateClass(descriptor.getMappedClass()); + return new MappingBean<>(instance, descriptor); + } + + private MappingBean(T instance, MappingDescriptor descriptor) { + this.instance = instance; + this.descriptor = descriptor; + this.bw = new BeanWrapperImpl(instance); + initBeanWrapper(bw); + } + + /** + * 初始化bean wrapper + * + * @param bw bean包装器 + */ + protected void initBeanWrapper(BeanWrapper bw) { + ConversionService cs = conversionService.get(); + if (cs != null) { + bw.setConversionService(cs); + } + } + + /** + * 设置bean的值 + * + * @param column 属性名 + * @param value 值 + */ + void setValue(String column, ValueProvider value) throws Exception { + String findName = getProperty(column); + if (StringUtils.hasText(findName)) { + PropertyDescriptor pd = descriptor.getMappedFields().get(findName); + if (null == pd) return; + String name = pd.getName(); + if (!logged) { + logged = true; + if (log.isDebugEnabled()) { + log.debug("Mapping column '{}' to property '{}' of type '{}'", column, name, + ClassUtils.getQualifiedName(pd.getPropertyType())); + } + } + // 尝试获取值 + Object mappedValue = transformer.apply(name, value.get(pd.getPropertyType())); + // 尝试设置 + bw.setPropertyValue(name, mappedValue); + } + } + + /** + * 获取真正的列名 + * + * @param column 列 + * @return 结果 + */ + String getProperty(String column) { + return propertyTransformer.apply(column); + } + + /** + * 获取设置后的实体 + * + * @return 结果 + */ + T get() { + return instance; + } +} diff --git a/fluent-sql-spring/src/main/java/group/flyfish/fluent/mapping/MappingDescriptor.java b/fluent-sql-spring/src/main/java/group/flyfish/fluent/mapping/MappingDescriptor.java new file mode 100644 index 0000000..0d2e8d2 --- /dev/null +++ b/fluent-sql-spring/src/main/java/group/flyfish/fluent/mapping/MappingDescriptor.java @@ -0,0 +1,187 @@ +package group.flyfish.fluent.mapping; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import group.flyfish.fluent.binding.Alias; +import group.flyfish.fluent.binding.JSONInject; +import group.flyfish.fluent.utils.data.ObjectMappers; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.core.annotation.MergedAnnotations; +import org.springframework.dao.InvalidDataAccessApiUsageException; +import org.springframework.util.Assert; +import org.springframework.util.ReflectionUtils; +import org.springframework.util.StringUtils; + +import java.beans.PropertyDescriptor; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +/** + * 特定类型的映射解释器 + * + * @param 泛型 + */ +@Getter +@Slf4j +class MappingDescriptor { + + private final ObjectMapper objectMapper = ObjectMappers.shared(); + + /** + * The class we are mapping to. + */ + private Class mappedClass; + /** + * Map of the fields we provide mapping for. + */ + private final Map mappedFields; + + /** + * Map of the fields which need json convert + */ + private final Map> jsonFields; + + static MappingDescriptor of(Class mappedClass) { + return new MappingDescriptor<>(mappedClass); + } + + private MappingDescriptor(Class mappedClass) { + Assert.state(mappedClass != null, "Mapped class was not specified"); + this.mappedClass = mappedClass; + this.mappedFields = new HashMap<>(); + this.jsonFields = new HashMap<>(); + initialize(); + } + + private void initialize() { + Map fieldAnnotations = new HashMap<>(); + ReflectionUtils.doWithFields(mappedClass, field -> fieldAnnotations.put(field.getName(), MergedAnnotations.from(field))); + + for (PropertyDescriptor pd : BeanUtils.getPropertyDescriptors(mappedClass)) { + if (pd.getWriteMethod() != null) { + MergedAnnotations annotations = fieldAnnotations.get(pd.getName()); + String lowerCaseName; + if (annotations.isPresent(Alias.class)) { + String rawName = annotations.get(Alias.class).synthesize().value(); + lowerCaseName = lowerCaseName(rawName.replace("_", "")); + } else { + lowerCaseName = lowerCaseName(pd.getName()); + } + this.mappedFields.put(lowerCaseName, pd); + String underscoreName = underscoreName(pd.getName()); + if (!lowerCaseName.equals(underscoreName)) { + this.mappedFields.put(underscoreName, pd); + } + // 添加json字段 + if (annotations.isPresent(JSONInject.class)) { + this.jsonFields.put(pd.getName(), pd.getPropertyType()); + } + } + } + } + + MappingBean create() { + MappingBean bean = MappingBean.create(this); + bean.setTransformer(this::convertPropertyIfNeed); + bean.setPropertyTransformer(this::lowerCaseName); + return bean; + } + + /** + * Remove the specified property from the mapped fields. + * + * @param propertyName the property name (as used by property descriptors) + * @since 5.3.9 + */ + private void suppressProperty(String propertyName) { + if (this.mappedFields != null) { + this.mappedFields.remove(lowerCaseName(propertyName)); + this.mappedFields.remove(underscoreName(propertyName)); + } + } + + + /** + * Convert the given name to lower case. + * By default, conversions will happen within the US locale. + * + * @param name the original name + * @return the converted name + * @since 4.2 + */ + private String lowerCaseName(String name) { + return StringUtils.delete(name, " ").toLowerCase(Locale.US); + } + + /** + * Convert a name in camelCase to an underscored name in lower case. + * Any upper case letters are converted to lower case with a preceding underscore. + * + * @param name the original name + * @return the converted name + * @see #lowerCaseName + * @since 4.2 + */ + private String underscoreName(String name) { + if (!StringUtils.hasLength(name)) { + return ""; + } + + StringBuilder result = new StringBuilder(); + result.append(Character.toLowerCase(name.charAt(0))); + for (int i = 1; i < name.length(); i++) { + char c = name.charAt(i); + if (Character.isUpperCase(c)) { + result.append('_').append(Character.toLowerCase(c)); + } else { + result.append(c); + } + } + return result.toString(); + } + + /** + * Set the class that each row should be mapped to. + */ + void setMappedClass(Class mappedClass) { + if (this.mappedClass == null) { + this.mappedClass = mappedClass; + initialize(); + } else { + if (this.mappedClass != mappedClass) { + throw new InvalidDataAccessApiUsageException("The mapped class can not be reassigned to map to " + + mappedClass + " since it is already providing mapping for " + this.mappedClass); + } + } + } + + private Object convertPropertyIfNeed(String name, Object value) { + if (jsonFields.containsKey(name)) { + value = convert(value, jsonFields.get(name)); + } + return value; + } + + /** + * 转换json对象 + * + * @param type 目标类型 + * @param value 值 + * @return 结果 + */ + private Object convert(Object value, Class type) { + if (value instanceof String) { + try { + return objectMapper.readValue((String) value, type); + } catch (JsonProcessingException e) { + log.error("转换json为对象时出错!{}", e.getMessage()); + return null; + } + } + return value; + } + +} diff --git a/fluent-sql-spring/src/main/java/group/flyfish/fluent/mapping/ReactiveSQLMappedRowMapper.java b/fluent-sql-spring/src/main/java/group/flyfish/fluent/mapping/ReactiveSQLMappedRowMapper.java new file mode 100644 index 0000000..59294bf --- /dev/null +++ b/fluent-sql-spring/src/main/java/group/flyfish/fluent/mapping/ReactiveSQLMappedRowMapper.java @@ -0,0 +1,62 @@ +package group.flyfish.fluent.mapping; + +import io.r2dbc.spi.Row; +import io.r2dbc.spi.RowMetadata; +import org.springframework.dao.DataRetrievalFailureException; + +import java.util.function.BiFunction; + +/** + * 异步支持的sql映射,支持json映射 + * + * @param 泛型 + */ +public class ReactiveSQLMappedRowMapper implements BiFunction { + + /** + * the actual logic for conversation + */ + private final MappingDescriptor descriptor; + + /** + * Create a new {@code BeanPropertyRowMapper}, accepting unpopulated + * properties in the target bean. + * + * @param mappedClass the class that each row should be mapped to + */ + private ReactiveSQLMappedRowMapper(Class mappedClass) { + this.descriptor = MappingDescriptor.of(mappedClass); + } + + /** + * Static factory method to create a new {@code BeanPropertyRowMapper}. + * + * @param mappedClass the class that each row should be mapped to + */ + public static ReactiveSQLMappedRowMapper newInstance(Class mappedClass) { + return new ReactiveSQLMappedRowMapper<>(mappedClass); + } + + /** + * Applies this function to the given arguments. + * + * @param row the first function argument + * @param rowMetadata the second function argument + * @return the function result + */ + @Override + public T apply(Row row, RowMetadata rowMetadata) { + MappingBean bean = descriptor.create(); + + for (String column : rowMetadata.getColumnNames()) { + try { + bean.setValue(column, type -> row.get(column, type)); + } catch (Exception ex) { + throw new DataRetrievalFailureException( + "Unable to map column '" + column + "' to property '" + bean.getProperty(column) + "'", ex); + } + } + + return bean.get(); + } +} diff --git a/fluent-sql-spring/src/main/java/group/flyfish/fluent/mapping/SQLMappedRowMapper.java b/fluent-sql-spring/src/main/java/group/flyfish/fluent/mapping/SQLMappedRowMapper.java index 8312abb..0bf5b58 100644 --- a/fluent-sql-spring/src/main/java/group/flyfish/fluent/mapping/SQLMappedRowMapper.java +++ b/fluent-sql-spring/src/main/java/group/flyfish/fluent/mapping/SQLMappedRowMapper.java @@ -1,32 +1,14 @@ package group.flyfish.fluent.mapping; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import group.flyfish.fluent.binding.Alias; -import group.flyfish.fluent.binding.JSONInject; -import group.flyfish.fluent.utils.data.ObjectMappers; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.*; -import org.springframework.core.annotation.MergedAnnotations; -import org.springframework.core.convert.ConversionService; -import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.dao.DataRetrievalFailureException; -import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.support.JdbcUtils; import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; -import org.springframework.util.ReflectionUtils; -import org.springframework.util.StringUtils; -import java.beans.PropertyDescriptor; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; /** * 基于SQL映射的行映射器 @@ -37,27 +19,10 @@ import java.util.Map; @Slf4j public class SQLMappedRowMapper implements RowMapper { - private final ObjectMapper objectMapper = ObjectMappers.shared(); - /** - * The class we are mapping to. + * the actual logic for conversation */ - @Nullable - private Class mappedClass; - /** - * ConversionService for binding JDBC values to bean properties. - */ - @Nullable - private ConversionService conversionService = DefaultConversionService.getSharedInstance(); - /** - * Map of the fields we provide mapping for. - */ - @Nullable - private Map mappedFields; - /** - * Map of the fields which need json convert - */ - private Map> jsonFields; + private final MappingDescriptor descriptor; /** * Create a new {@code BeanPropertyRowMapper}, accepting unpopulated @@ -66,171 +31,18 @@ public class SQLMappedRowMapper implements RowMapper { * @param mappedClass the class that each row should be mapped to */ public SQLMappedRowMapper(Class mappedClass) { - initialize(mappedClass); + this.descriptor = MappingDescriptor.of(mappedClass); } /** * Static factory method to create a new {@code BeanPropertyRowMapper}. * * @param mappedClass the class that each row should be mapped to - * @see #newInstance(Class, ConversionService) */ public static SQLMappedRowMapper newInstance(Class mappedClass) { return new SQLMappedRowMapper<>(mappedClass); } - /** - * Static factory method to create a new {@code BeanPropertyRowMapper}. - * - * @param mappedClass the class that each row should be mapped to - * @param conversionService the {@link ConversionService} for binding - * JDBC values to bean properties, or {@code null} for none - * @see #newInstance(Class) - * @see #setConversionService - * @since 5.2.3 - */ - public static SQLMappedRowMapper newInstance( - Class mappedClass, @Nullable ConversionService conversionService) { - - SQLMappedRowMapper rowMapper = newInstance(mappedClass); - rowMapper.setConversionService(conversionService); - return rowMapper; - } - - /** - * Get the class that we are mapping to. - */ - @Nullable - public final Class getMappedClass() { - return this.mappedClass; - } - - /** - * Set the class that each row should be mapped to. - */ - public void setMappedClass(Class mappedClass) { - if (this.mappedClass == null) { - initialize(mappedClass); - } else { - if (this.mappedClass != mappedClass) { - throw new InvalidDataAccessApiUsageException("The mapped class can not be reassigned to map to " + - mappedClass + " since it is already providing mapping for " + this.mappedClass); - } - } - } - - /** - * Return a {@link ConversionService} for binding JDBC values to bean properties, - * or {@code null} if none. - * - * @since 4.3 - */ - @Nullable - public ConversionService getConversionService() { - return this.conversionService; - } - - /** - * Set a {@link ConversionService} for binding JDBC values to bean properties, - * or {@code null} for none. - *

Default is a {@link DefaultConversionService}, as of Spring 4.3. This - * provides support for {@code java.time} conversion and other special types. - * - * @see #initBeanWrapper(BeanWrapper) - * @since 4.3 - */ - public void setConversionService(@Nullable ConversionService conversionService) { - this.conversionService = conversionService; - } - - /** - * Initialize the mapping meta-data for the given class. - * - * @param mappedClass the mapped class - */ - protected void initialize(Class mappedClass) { - this.mappedClass = mappedClass; - this.mappedFields = new HashMap<>(); - this.jsonFields = new HashMap<>(); - - Map fieldAnnotations = new HashMap<>(); - ReflectionUtils.doWithFields(mappedClass, field -> fieldAnnotations.put(field.getName(), MergedAnnotations.from(field))); - - for (PropertyDescriptor pd : BeanUtils.getPropertyDescriptors(mappedClass)) { - if (pd.getWriteMethod() != null) { - MergedAnnotations annotations = fieldAnnotations.get(pd.getName()); - String lowerCaseName; - if (annotations.isPresent(Alias.class)) { - String rawName = annotations.get(Alias.class).synthesize().value(); - lowerCaseName = lowerCaseName(rawName.replace("_", "")); - } else { - lowerCaseName = lowerCaseName(pd.getName()); - } - this.mappedFields.put(lowerCaseName, pd); - String underscoreName = underscoreName(pd.getName()); - if (!lowerCaseName.equals(underscoreName)) { - this.mappedFields.put(underscoreName, pd); - } - // 添加json字段 - if (annotations.isPresent(JSONInject.class)) { - this.jsonFields.put(pd.getName(), pd.getPropertyType()); - } - } - } - } - - /** - * Remove the specified property from the mapped fields. - * - * @param propertyName the property name (as used by property descriptors) - * @since 5.3.9 - */ - protected void suppressProperty(String propertyName) { - if (this.mappedFields != null) { - this.mappedFields.remove(lowerCaseName(propertyName)); - this.mappedFields.remove(underscoreName(propertyName)); - } - } - - /** - * Convert the given name to lower case. - * By default, conversions will happen within the US locale. - * - * @param name the original name - * @return the converted name - * @since 4.2 - */ - protected String lowerCaseName(String name) { - return name.toLowerCase(Locale.US); - } - - /** - * Convert a name in camelCase to an underscored name in lower case. - * Any upper case letters are converted to lower case with a preceding underscore. - * - * @param name the original name - * @return the converted name - * @see #lowerCaseName - * @since 4.2 - */ - protected String underscoreName(String name) { - if (!StringUtils.hasLength(name)) { - return ""; - } - - StringBuilder result = new StringBuilder(); - result.append(Character.toLowerCase(name.charAt(0))); - for (int i = 1; i < name.length(); i++) { - char c = name.charAt(i); - if (Character.isUpperCase(c)) { - result.append('_').append(Character.toLowerCase(c)); - } else { - result.append(c); - } - } - return result.toString(); - } - /** * Extract the values for all columns in the current row. *

Utilizes public setters and result set meta-data. @@ -239,124 +51,28 @@ public class SQLMappedRowMapper implements RowMapper { */ @Override public T mapRow(ResultSet rs, int rowNumber) throws SQLException { - BeanWrapperImpl bw = new BeanWrapperImpl(); - initBeanWrapper(bw); - - T mappedObject = constructMappedInstance(rs, bw); - bw.setBeanInstance(mappedObject); + MappingBean bean = descriptor.create(); ResultSetMetaData rsmd = rs.getMetaData(); int columnCount = rsmd.getColumnCount(); - for (int index = 1; index <= columnCount; index++) { - String column = JdbcUtils.lookupColumnName(rsmd, index); - String field = lowerCaseName(StringUtils.delete(column, " ")); - PropertyDescriptor pd = (this.mappedFields != null ? this.mappedFields.get(field) : null); - if (pd != null) { - try { - Object value = getColumnValue(rs, index, pd); - if (rowNumber == 0 && log.isDebugEnabled()) { - log.debug("Mapping column '" + column + "' to property '" + pd.getName() + - "' of type '" + ClassUtils.getQualifiedName(pd.getPropertyType()) + "'"); - } - if (jsonFields.containsKey(pd.getName())) { - value = convert(value, jsonFields.get(pd.getName())); - } - bw.setPropertyValue(pd.getName(), value); - } catch (NotWritablePropertyException ex) { - throw new DataRetrievalFailureException( - "Unable to map column '" + column + "' to property '" + pd.getName() + "'", ex); - } + for (int i = 1; i <= columnCount; i++) { + String column = JdbcUtils.lookupColumnName(rsmd, i); + try { + final int index = i; + bean.setValue(column, type -> getColumnValue(rs, index, type)); + } catch (Exception ex) { + throw new DataRetrievalFailureException( + "Unable to map column '" + column + "' to property '" + bean.getProperty(column) + "'", ex); } } - return mappedObject; + return bean.get(); } - /** - * Construct an instance of the mapped class for the current row. - * - * @param rs the ResultSet to map (pre-initialized for the current row) - * @param tc a TypeConverter with this RowMapper's conversion service - * @return a corresponding instance of the mapped class - * @throws SQLException if an SQLException is encountered - * @since 5.3 - */ - protected T constructMappedInstance(ResultSet rs, TypeConverter tc) throws SQLException { - Assert.state(this.mappedClass != null, "Mapped class was not specified"); - return BeanUtils.instantiateClass(this.mappedClass); - } - - /** - * Initialize the given BeanWrapper to be used for row mapping. - * To be called for each row. - *

The default implementation applies the configured {@link ConversionService}, - * if any. Can be overridden in subclasses. - * - * @param bw the BeanWrapper to initialize - * @see #getConversionService() - * @see BeanWrapper#setConversionService - */ - protected void initBeanWrapper(BeanWrapper bw) { - ConversionService cs = getConversionService(); - if (cs != null) { - bw.setConversionService(cs); - } - } - - /** - * Retrieve a JDBC object value for the specified column. - *

The default implementation delegates to - * {@link #getColumnValue(ResultSet, int, Class)}. - * - * @param rs is the ResultSet holding the data - * @param index is the column index - * @param pd the bean property that each result object is expected to match - * @return the Object value - * @throws SQLException in case of extraction failure - * @see #getColumnValue(ResultSet, int, Class) - */ - @Nullable - protected Object getColumnValue(ResultSet rs, int index, PropertyDescriptor pd) throws SQLException { - return JdbcUtils.getResultSetValue(rs, index, pd.getPropertyType()); - } - - /** - * Retrieve a JDBC object value for the specified column. - *

The default implementation calls - * {@link JdbcUtils#getResultSetValue(java.sql.ResultSet, int, Class)}. - * Subclasses may override this to check specific value types upfront, - * or to post-process values return from {@code getResultSetValue}. - * - * @param rs is the ResultSet holding the data - * @param index is the column index - * @param paramType the target parameter type - * @return the Object value - * @throws SQLException in case of extraction failure - * @see org.springframework.jdbc.support.JdbcUtils#getResultSetValue(java.sql.ResultSet, int, Class) - * @since 5.3 - */ @Nullable protected Object getColumnValue(ResultSet rs, int index, Class paramType) throws SQLException { return JdbcUtils.getResultSetValue(rs, index, paramType); } - /** - * 转换json对象 - * - * @param type 目标类型 - * @param value 值 - * @return 结果 - */ - private Object convert(Object value, Class type) { - if (value instanceof String) { - try { - return objectMapper.readValue((String) value, type); - } catch (JsonProcessingException e) { - log.error("转换json为对象时出错!{}", e.getMessage()); - return null; - } - } - return value; - } } diff --git a/fluent-sql-spring/src/main/java/group/flyfish/fluent/mapping/ValueProvider.java b/fluent-sql-spring/src/main/java/group/flyfish/fluent/mapping/ValueProvider.java new file mode 100644 index 0000000..4270678 --- /dev/null +++ b/fluent-sql-spring/src/main/java/group/flyfish/fluent/mapping/ValueProvider.java @@ -0,0 +1,17 @@ +package group.flyfish.fluent.mapping; + +/** + * 值提供者 + * + * @author wangyu + */ +interface ValueProvider { + + /** + * 通过具体类型获取值 + * + * @param type 类型 + * @return 结果 + */ + Object get(Class type) throws Exception; +} diff --git a/fluent-sql-spring/src/main/java/group/flyfish/fluent/operations/JdbcTemplateFluentSQLOperations.java b/fluent-sql-spring/src/main/java/group/flyfish/fluent/operations/JdbcTemplateFluentSQLOperations.java index ec22771..b567704 100644 --- a/fluent-sql-spring/src/main/java/group/flyfish/fluent/operations/JdbcTemplateFluentSQLOperations.java +++ b/fluent-sql-spring/src/main/java/group/flyfish/fluent/operations/JdbcTemplateFluentSQLOperations.java @@ -1,8 +1,8 @@ package group.flyfish.fluent.operations; import group.flyfish.fluent.chain.SQL; +import group.flyfish.fluent.entity.BoundSQLEntity; import group.flyfish.fluent.entity.DataPage; -import group.flyfish.fluent.entity.SQLEntity; import group.flyfish.fluent.mapping.SQLMappedRowMapper; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcOperations; @@ -40,13 +40,14 @@ public class JdbcTemplateFluentSQLOperations implements FluentSQLOperations { */ @Override @SuppressWarnings("all") - public T selectOne(SQLEntity entity, Class clazz) { + public T selectOne(BoundSQLEntity entity) { try { String sql = entity.getSql(); - if (ClassUtils.isPrimitiveOrWrapper(clazz)) { - return jdbcOperations.queryForObject(sql, clazz, entity.getParameters()); + Class type = entity.getResultType(); + if (ClassUtils.isPrimitiveOrWrapper(type)) { + return jdbcOperations.queryForObject(sql, type, entity.getParameters()); } - return jdbcOperations.queryForObject(sql, new SQLMappedRowMapper<>(clazz), entity.getParameters()); + return jdbcOperations.queryForObject(sql, SQLMappedRowMapper.newInstance(type), entity.getParameters()); } catch (EmptyResultDataAccessException e) { return null; } @@ -56,27 +57,26 @@ public class JdbcTemplateFluentSQLOperations implements FluentSQLOperations { * 执行一条sql,并且查询出所有行 * * @param entity sql实体 - * @param clazz 目标类型 * @return 返回的列表 */ @Override - public List select(SQLEntity entity, Class clazz) { + public List select(BoundSQLEntity entity) { String sql = entity.getSql(); - if (ClassUtils.isPrimitiveOrWrapper(clazz)) { - return jdbcOperations.queryForList(sql, clazz, entity.getParameters()); + Class type = entity.getResultType(); + if (ClassUtils.isPrimitiveOrWrapper(type)) { + return jdbcOperations.queryForList(sql, type, entity.getParameters()); } - return jdbcOperations.query(sql, new SQLMappedRowMapper<>(clazz), entity.getParameters()); + return jdbcOperations.query(sql, SQLMappedRowMapper.newInstance(type), entity.getParameters()); } /** * 分页查询 * * @param entity sql实体 - * @param clazz 目标类型 * @return 返回的分页对象 */ @Override - public DataPage selectPage(SQLEntity entity, Class clazz) { + public DataPage selectPage(BoundSQLEntity entity) { return null; } @@ -87,7 +87,7 @@ public class JdbcTemplateFluentSQLOperations implements FluentSQLOperations { * @return 更新行数 */ @Override - public int execute(SQLEntity entity) { + public int execute(BoundSQLEntity entity) { return jdbcOperations.update(entity.getSql(), entity.getParameters()); } } diff --git a/fluent-sql-spring/src/main/java/group/flyfish/fluent/operations/R2dbcFluentSQLOperations.java b/fluent-sql-spring/src/main/java/group/flyfish/fluent/operations/R2dbcFluentSQLOperations.java index 96ee6b7..2c83b9d 100644 --- a/fluent-sql-spring/src/main/java/group/flyfish/fluent/operations/R2dbcFluentSQLOperations.java +++ b/fluent-sql-spring/src/main/java/group/flyfish/fluent/operations/R2dbcFluentSQLOperations.java @@ -1,9 +1,11 @@ package group.flyfish.fluent.operations; +import group.flyfish.fluent.entity.BoundSQLEntity; import group.flyfish.fluent.entity.DataPage; -import group.flyfish.fluent.entity.SQLEntity; +import group.flyfish.fluent.mapping.ReactiveSQLMappedRowMapper; import lombok.RequiredArgsConstructor; import org.springframework.r2dbc.core.DatabaseClient; +import org.springframework.r2dbc.core.RowsFetchSpec; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -18,36 +20,34 @@ public class R2dbcFluentSQLOperations implements ReactiveFluentSQLOperations { * 如果没有结果,将返回null * * @param entity sql实体 - * @param clazz 目标类型 * @return 查询结果 */ @Override - public Mono selectOne(SQLEntity entity, Class clazz) { - return null; + public Mono selectOne(BoundSQLEntity entity) { + return forSelect(entity).one(); + } /** * 执行一条sql,并且查询出所有行 * * @param entity sql实体 - * @param clazz 目标类型 * @return 返回的列表 */ @Override - public Flux select(SQLEntity entity, Class clazz) { - return null; + public Flux select(BoundSQLEntity entity) { + return forSelect(entity).all(); } /** * 分页查询 * * @param entity sql实体 - * @param clazz 目标类型 * @return 返回的分页对象 */ @Override - public Mono> selectPage(SQLEntity entity, Class clazz) { - return null; + public Mono> selectPage(BoundSQLEntity entity) { + return Mono.empty(); } /** @@ -57,7 +57,29 @@ public class R2dbcFluentSQLOperations implements ReactiveFluentSQLOperations { * @return 更新行数 */ @Override - public Mono execute(SQLEntity entity) { - return null; + public Mono execute(BoundSQLEntity entity) { + return resolve(entity).fetch().rowsUpdated(); + } + + /** + * 解析sql实体 + * + * @param entity 实体信息 + * @return 结果 + */ + private DatabaseClient.GenericExecuteSpec resolve(BoundSQLEntity entity) { + DatabaseClient.GenericExecuteSpec spec = databaseClient.sql(entity); + Object[] parameters = entity.getParameters(); + if (null != parameters) { + for (int i = 0; i < parameters.length; i++) { + spec = spec.bind(i, parameters[i]); + } + } + return spec; + } + + private RowsFetchSpec forSelect(BoundSQLEntity entity) { + return resolve(entity) + .map(ReactiveSQLMappedRowMapper.newInstance(entity.getResultType())); } } diff --git a/fluent-sql-spring/src/test/java/group/flyfish/framework/cases/FluentSqlTestCase.java b/fluent-sql-spring/src/test/java/group/flyfish/framework/cases/FluentSqlTestCase.java index 209e63b..2a2c947 100644 --- a/fluent-sql-spring/src/test/java/group/flyfish/framework/cases/FluentSqlTestCase.java +++ b/fluent-sql-spring/src/test/java/group/flyfish/framework/cases/FluentSqlTestCase.java @@ -2,7 +2,6 @@ package group.flyfish.framework.cases; 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; @@ -12,7 +11,6 @@ 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; @@ -61,6 +59,6 @@ public class FluentSqlTestCase extends AbstractTestCase> { @Override public List run() throws Exception { // 一个平平无奇的查询 - return sql.list(TenantContext.class); + return sql.as(TenantContext.class).block().all(); } } diff --git a/fluent-sql-spring/src/test/java/group/flyfish/framework/cases/SingleTableTestCase.java b/fluent-sql-spring/src/test/java/group/flyfish/framework/cases/SingleTableTestCase.java index 740bea6..4f38bfe 100644 --- a/fluent-sql-spring/src/test/java/group/flyfish/framework/cases/SingleTableTestCase.java +++ b/fluent-sql-spring/src/test/java/group/flyfish/framework/cases/SingleTableTestCase.java @@ -1,5 +1,6 @@ package group.flyfish.framework.cases; +import group.flyfish.fluent.chain.execution.BoundProxy; import group.flyfish.framework.TestCase; import group.flyfish.framework.entity.SaasTenant; @@ -38,6 +39,7 @@ public class SingleTableTestCase extends AbstractTestCase> { @Override public List run() throws Exception { // 单表查询 - return select().from(SaasTenant.class).list(); + BoundProxy proxy = select().from(SaasTenant.class).fetch(); + return proxy.block().all(); } } diff --git a/pom.xml b/pom.xml index fcd053b..34c9632 100644 --- a/pom.xml +++ b/pom.xml @@ -38,8 +38,8 @@ 8 8 1.18.24 - 2.13.3 - 2.7.2 + 2.17.2 + 2.7.18 5.3.22