diff --git a/src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSL.java b/src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSL.java index 8dda9b10c..3724e5395 100644 --- a/src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSL.java @@ -27,7 +27,6 @@ import org.mybatis.dynamic.sql.common.OrderByModel; import org.mybatis.dynamic.sql.configuration.StatementConfiguration; import org.mybatis.dynamic.sql.util.Buildable; -import org.mybatis.dynamic.sql.util.Utilities; import org.mybatis.dynamic.sql.where.AbstractWhereFinisher; import org.mybatis.dynamic.sql.where.AbstractWhereStarter; import org.mybatis.dynamic.sql.where.EmbeddedWhereModel; @@ -51,7 +50,7 @@ private DeleteDSL(SqlTable table, @Nullable String tableAlias, Function columns) { return this; } - public LimitFinisher limit(long limit) { + public MultiSelectDSL.LimitFinisher limit(long limit) { return limitWhenPresent(limit); } - public LimitFinisher limitWhenPresent(@Nullable Long limit) { + public MultiSelectDSL.LimitFinisher limitWhenPresent(@Nullable Long limit) { this.limit = limit; return new LimitFinisher(); } - public OffsetFirstFinisher offset(long offset) { + public MultiSelectDSL.OffsetFirstFinisher offset(long offset) { return offsetWhenPresent(offset); } - public OffsetFirstFinisher offsetWhenPresent(@Nullable Long offset) { + public MultiSelectDSL.OffsetFirstFinisher offsetWhenPresent(@Nullable Long offset) { this.offset = offset; return new OffsetFirstFinisher(); } - public FetchFirstFinisher fetchFirst(long fetchFirstRows) { + public MultiSelectDSL.FetchFirstFinisher fetchFirst(long fetchFirstRows) { return fetchFirstWhenPresent(fetchFirstRows); } - public FetchFirstFinisher fetchFirstWhenPresent(@Nullable Long fetchFirstRows) { + public MultiSelectDSL.FetchFirstFinisher fetchFirstWhenPresent(@Nullable Long fetchFirstRows) { this.fetchFirstRows = fetchFirstRows; return new FetchFirstFinisher(); } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java index afb6cda0c..b61f5e98a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java @@ -37,7 +37,6 @@ import org.mybatis.dynamic.sql.select.join.JoinSpecification; import org.mybatis.dynamic.sql.select.join.JoinType; import org.mybatis.dynamic.sql.util.Buildable; -import org.mybatis.dynamic.sql.util.Utilities; import org.mybatis.dynamic.sql.where.AbstractWhereFinisher; import org.mybatis.dynamic.sql.where.AbstractWhereStarter; import org.mybatis.dynamic.sql.where.EmbeddedWhereModel; @@ -70,7 +69,7 @@ protected QueryExpressionDSL(FromGatherer fromGatherer, SqlTable table, Strin @Override public QueryExpressionWhereBuilder where() { - whereBuilder = Utilities.buildIfNecessary(whereBuilder, QueryExpressionWhereBuilder::new); + whereBuilder = Objects.requireNonNullElseGet(whereBuilder, QueryExpressionWhereBuilder::new); return whereBuilder; } @@ -86,7 +85,7 @@ public QueryExpressionDSL configureStatement(Consumer * @return The having builder */ protected QueryExpressionHavingBuilder having() { - havingBuilder = Utilities.buildIfNecessary(havingBuilder, QueryExpressionHavingBuilder::new); + havingBuilder = Objects.requireNonNullElseGet(havingBuilder, QueryExpressionHavingBuilder::new); return havingBuilder; } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java index 6b52d3c3f..2c2963772 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java @@ -110,29 +110,29 @@ void orderBy(Collection columns) { orderByModel = OrderByModel.of(columns); } - public LimitFinisher limit(long limit) { + public SelectDSL.LimitFinisher limit(long limit) { return limitWhenPresent(limit); } - public LimitFinisher limitWhenPresent(@Nullable Long limit) { + public SelectDSL.LimitFinisher limitWhenPresent(@Nullable Long limit) { this.limit = limit; return new LimitFinisher(); } - public OffsetFirstFinisher offset(long offset) { + public SelectDSL.OffsetFirstFinisher offset(long offset) { return offsetWhenPresent(offset); } - public OffsetFirstFinisher offsetWhenPresent(@Nullable Long offset) { + public SelectDSL.OffsetFirstFinisher offsetWhenPresent(@Nullable Long offset) { this.offset = offset; return new OffsetFirstFinisher(); } - public FetchFirstFinisher fetchFirst(long fetchFirstRows) { + public SelectDSL.FetchFirstFinisher fetchFirst(long fetchFirstRows) { return fetchFirstWhenPresent(fetchFirstRows); } - public FetchFirstFinisher fetchFirstWhenPresent(@Nullable Long fetchFirstRows) { + public SelectDSL.FetchFirstFinisher fetchFirstWhenPresent(@Nullable Long fetchFirstRows) { this.fetchFirstRows = fetchFirstRows; return new FetchFirstFinisher(); } diff --git a/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java b/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java index c6fcd50d7..f33bbc074 100644 --- a/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java @@ -39,7 +39,6 @@ import org.mybatis.dynamic.sql.util.NullMapping; import org.mybatis.dynamic.sql.util.SelectMapping; import org.mybatis.dynamic.sql.util.StringConstantMapping; -import org.mybatis.dynamic.sql.util.Utilities; import org.mybatis.dynamic.sql.util.ValueMapping; import org.mybatis.dynamic.sql.util.ValueOrNullMapping; import org.mybatis.dynamic.sql.util.ValueWhenPresentMapping; @@ -71,7 +70,7 @@ public SetClauseFinisher set(SqlColumn column) { @Override public UpdateWhereBuilder where() { - whereBuilder = Utilities.buildIfNecessary(whereBuilder, UpdateWhereBuilder::new); + whereBuilder = Objects.requireNonNullElseGet(whereBuilder, UpdateWhereBuilder::new); return whereBuilder; } diff --git a/src/main/java/org/mybatis/dynamic/sql/update/render/UpdateRenderer.java b/src/main/java/org/mybatis/dynamic/sql/update/render/UpdateRenderer.java index 2a3599788..ee0f74961 100644 --- a/src/main/java/org/mybatis/dynamic/sql/update/render/UpdateRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/update/render/UpdateRenderer.java @@ -15,7 +15,6 @@ */ package org.mybatis.dynamic.sql.update.render; -import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; @@ -77,23 +76,15 @@ private FragmentAndParameters calculateUpdateStatementStart() { } private FragmentAndParameters calculateSetPhrase() { - List> fragmentsAndParameters = updateModel.columnMappings() + FragmentCollector fragmentCollector = updateModel.columnMappings() .map(m -> m.accept(visitor)) - .toList(); - - Validator.assertFalse(fragmentsAndParameters.stream().noneMatch(Optional::isPresent), - "ERROR.18"); //$NON-NLS-1$ - - FragmentCollector fragmentCollector = fragmentsAndParameters.stream() .flatMap(Optional::stream) .collect(FragmentCollector.collect()); - return toSetPhrase(fragmentCollector); - } + Validator.assertFalse(fragmentCollector.isEmpty(), "ERROR.18"); //$NON-NLS-1$ - private FragmentAndParameters toSetPhrase(FragmentCollector fragmentCollector) { return fragmentCollector.toFragmentAndParameters( - Collectors.joining(", ", "set ", "")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + Collectors.joining(", ", "set ", "")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } private Optional calculateWhereClause() { diff --git a/src/main/java/org/mybatis/dynamic/sql/util/FragmentCollector.java b/src/main/java/org/mybatis/dynamic/sql/util/FragmentCollector.java index bdf7371ba..410d7a035 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/FragmentCollector.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/FragmentCollector.java @@ -16,6 +16,7 @@ package org.mybatis.dynamic.sql.util; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -23,7 +24,8 @@ import java.util.stream.Collector; public class FragmentCollector { - final List fragments = new ArrayList<>(); + final List fragments = new ArrayList<>(); + final Map parameters = new HashMap<>(); public FragmentCollector() { super(); @@ -34,20 +36,22 @@ private FragmentCollector(FragmentAndParameters initialFragment) { } public void add(FragmentAndParameters fragmentAndParameters) { - fragments.add(fragmentAndParameters); + fragments.add(fragmentAndParameters.fragment()); + parameters.putAll(fragmentAndParameters.parameters()); } public FragmentCollector merge(FragmentCollector other) { fragments.addAll(other.fragments); + parameters.putAll(other.parameters); return this; } public Optional firstFragment() { - return fragments.stream().findFirst().map(FragmentAndParameters::fragment); + return fragments.stream().findFirst(); } public String collectFragments(Collector fragmentCollector) { - return fragments.stream().map(FragmentAndParameters::fragment).collect(fragmentCollector); + return fragments.stream().collect(fragmentCollector); } public FragmentAndParameters toFragmentAndParameters(Collector fragmentCollector) { @@ -57,9 +61,7 @@ public FragmentAndParameters toFragmentAndParameters(Collector parameters() { - return fragments.stream() - .map(FragmentAndParameters::parameters) - .collect(HashMap::new, HashMap::putAll, HashMap::putAll); + return Collections.unmodifiableMap(parameters); } public boolean hasMultipleFragments() { diff --git a/src/main/java/org/mybatis/dynamic/sql/util/Utilities.java b/src/main/java/org/mybatis/dynamic/sql/util/Utilities.java index e0aa47bc0..87ea18e12 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/Utilities.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/Utilities.java @@ -17,17 +17,12 @@ import java.util.Collection; import java.util.Objects; -import java.util.function.Supplier; import java.util.stream.Stream; import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; public interface Utilities { - static T buildIfNecessary(@Nullable T current, @NonNull Supplier builder) { - return current == null ? builder.get() : current; - } - static long safelyUnbox(@Nullable Long l) { return l == null ? 0 : l; } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/render/ColumnAndConditionRenderer.java b/src/main/java/org/mybatis/dynamic/sql/where/render/ColumnAndConditionRenderer.java index 73f456981..6035c143b 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/render/ColumnAndConditionRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/ColumnAndConditionRenderer.java @@ -15,45 +15,43 @@ */ package org.mybatis.dynamic.sql.where.render; -import static org.mybatis.dynamic.sql.util.StringUtilities.spaceBefore; - import java.util.Objects; +import java.util.stream.Collectors; import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.VisitableCondition; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.FragmentAndParameters; +import org.mybatis.dynamic.sql.util.FragmentCollector; public class ColumnAndConditionRenderer { private final BindableColumn column; private final VisitableCondition condition; private final RenderingContext renderingContext; + private final DefaultConditionVisitor visitor; private ColumnAndConditionRenderer(Builder builder) { column = Objects.requireNonNull(builder.column); condition = Objects.requireNonNull(builder.condition); renderingContext = Objects.requireNonNull(builder.renderingContext); - } - - public FragmentAndParameters render() { - FragmentAndParameters renderedLeftColumn = column.alias() - .map(FragmentAndParameters::fromFragment) - .orElseGet(() -> column.render(renderingContext)); - - DefaultConditionVisitor visitor = DefaultConditionVisitor.withColumn(column) + visitor = DefaultConditionVisitor.withColumn(column) .withRenderingContext(renderingContext) .build(); + } - FragmentAndParameters renderedCondition = condition.accept(visitor); - - String finalFragment = condition.overrideRenderedLeftColumn(renderedLeftColumn.fragment()) - + spaceBefore(renderedCondition.fragment()); + public FragmentAndParameters render() { + FragmentCollector fc = new FragmentCollector(); + fc.add(renderLeftColumn()); + fc.add(condition.accept(visitor)); + return fc.toFragmentAndParameters(Collectors.joining(" ")); //$NON-NLS-1$ + } - return FragmentAndParameters.withFragment(finalFragment) - .withParameters(renderedLeftColumn.parameters()) - .withParameters(renderedCondition.parameters()) - .build(); + private FragmentAndParameters renderLeftColumn() { + return column.alias() + .map(FragmentAndParameters::fromFragment) + .orElseGet(() -> column.render(renderingContext)) + .mapFragment(condition::overrideRenderedLeftColumn); } public static class Builder { diff --git a/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java b/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java index 6a3fb038d..78bbc81e7 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java @@ -47,19 +47,10 @@ private DefaultConditionVisitor(Builder builder) { @Override public FragmentAndParameters visit(AbstractListValueCondition condition) { - FragmentCollector fc = condition.values() - .map(this::toFragmentAndParameters) - .collect(FragmentCollector.collect()); - - String joinedFragments = - fc.collectFragments(Collectors.joining(",", "(", ")")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - String finalFragment = condition.operator() - + spaceBefore(joinedFragments); - - return FragmentAndParameters - .withFragment(finalFragment) - .withParameters(fc.parameters()) - .build(); + return condition.values().map(this::toFragmentAndParameters) + .collect(FragmentCollector.collect()) + .toFragmentAndParameters(Collectors.joining(",", //$NON-NLS-1$ + condition.operator() + " (", ")")); //$NON-NLS-1$ //$NON-NLS-2$ } @Override