Skip to content

Commit e89fd77

Browse files
authored
Merge pull request #842 from jeffgbutler/new-join-syntax
Add new flexible syntax for coding join specifications
2 parents 3057702 + 0f1ad9c commit e89fd77

31 files changed

+2605
-639
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ Other important changes:
3131
With this change, the exception thrown is more predictable and the error is caught before sending the SQL to the
3232
database.
3333
- All the paging methods (limit, offset, fetchFirst) now have "WhenPresent" variations that will drop the phrase from
34-
rendering if a null value is passed in
34+
rendering if a null value is passed in
35+
- The JOIN syntax is updated and now allows full boolean expressions like a WHERE clause. The prior JOIN syntax
36+
is deprecated and will be removed in a future release.
3537

3638
## Release 1.5.2 - June 3, 2024
3739

src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,6 @@
5656
import org.mybatis.dynamic.sql.select.function.Substring;
5757
import org.mybatis.dynamic.sql.select.function.Subtract;
5858
import org.mybatis.dynamic.sql.select.function.Upper;
59-
import org.mybatis.dynamic.sql.select.join.EqualTo;
60-
import org.mybatis.dynamic.sql.select.join.EqualToValue;
61-
import org.mybatis.dynamic.sql.select.join.JoinCondition;
62-
import org.mybatis.dynamic.sql.select.join.JoinCriterion;
6359
import org.mybatis.dynamic.sql.update.UpdateDSL;
6460
import org.mybatis.dynamic.sql.update.UpdateModel;
6561
import org.mybatis.dynamic.sql.util.Buildable;
@@ -433,20 +429,36 @@ static AndOrCriteriaGroup and(List<AndOrCriteriaGroup> subCriteria) {
433429
}
434430

435431
// join support
436-
static <T> JoinCriterion<T> and(BindableColumn<T> joinColumn, JoinCondition<T> joinCondition) {
437-
return new JoinCriterion.Builder<T>()
438-
.withConnector("and") //$NON-NLS-1$
439-
.withJoinColumn(joinColumn)
440-
.withJoinCondition(joinCondition)
432+
static <T> ColumnAndConditionCriterion<T> on(BindableColumn<T> joinColumn, VisitableCondition<T> joinCondition) {
433+
return ColumnAndConditionCriterion.withColumn(joinColumn)
434+
.withCondition(joinCondition)
441435
.build();
442436
}
443437

444-
static <T> JoinCriterion<T> on(BindableColumn<T> joinColumn, JoinCondition<T> joinCondition) {
445-
return new JoinCriterion.Builder<T>()
446-
.withConnector("on") //$NON-NLS-1$
447-
.withJoinColumn(joinColumn)
448-
.withJoinCondition(joinCondition)
449-
.build();
438+
/**
439+
* Starting in version 2.0.0, this function is a synonym for {@link SqlBuilder#isEqualTo(BasicColumn)}.
440+
*
441+
* @param column the column
442+
* @param <T> the column type
443+
* @return an IsEqualToColumn condition
444+
* @deprecated since 2.0.0. Please replace with isEqualTo(column)
445+
*/
446+
@Deprecated(since = "2.0.0", forRemoval = true)
447+
static <T> IsEqualToColumn<T> equalTo(BindableColumn<T> column) {
448+
return isEqualTo(column);
449+
}
450+
451+
/**
452+
* Starting in version 2.0.0, this function is a synonym for {@link SqlBuilder#isEqualTo(Object)}.
453+
*
454+
* @param value the value
455+
* @param <T> the column type
456+
* @return an IsEqualTo condition
457+
* @deprecated since 2.0.0. Please replace with isEqualTo(value)
458+
*/
459+
@Deprecated(since = "2.0.0", forRemoval = true)
460+
static <T> IsEqualTo<T> equalTo(T value) {
461+
return isEqualTo(value);
450462
}
451463

452464
// case expressions
@@ -460,14 +472,6 @@ static SearchedCaseDSL case_() {
460472
return SearchedCaseDSL.searchedCase();
461473
}
462474

463-
static <T> EqualTo<T> equalTo(BindableColumn<T> column) {
464-
return new EqualTo<>(column);
465-
}
466-
467-
static <T> EqualToValue<T> equalTo(T value) {
468-
return new EqualToValue<>(value);
469-
}
470-
471475
// aggregate support
472476
static CountAll count() {
473477
return new CountAll();

src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSL.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@
3232
import org.mybatis.dynamic.sql.where.AbstractWhereStarter;
3333
import org.mybatis.dynamic.sql.where.EmbeddedWhereModel;
3434

35-
public class DeleteDSL<R> extends AbstractWhereStarter<DeleteDSL<R>.DeleteWhereBuilder, DeleteDSL<R>>
36-
implements Buildable<R> {
35+
public class DeleteDSL<R> implements AbstractWhereStarter<DeleteDSL<R>.DeleteWhereBuilder, DeleteDSL<R>>,
36+
Buildable<R> {
3737

3838
private final Function<DeleteModel, R> adapterFunction;
3939
private final SqlTable table;

src/main/java/org/mybatis/dynamic/sql/select/AbstractQueryExpressionDSL.java

Lines changed: 68 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@
2323
import java.util.Map;
2424
import java.util.Objects;
2525
import java.util.Optional;
26+
import java.util.function.Supplier;
2627

28+
import org.mybatis.dynamic.sql.AndOrCriteriaGroup;
29+
import org.mybatis.dynamic.sql.SqlCriterion;
2730
import org.mybatis.dynamic.sql.SqlTable;
2831
import org.mybatis.dynamic.sql.TableExpression;
2932
import org.mybatis.dynamic.sql.exception.DuplicateTableAliasException;
30-
import org.mybatis.dynamic.sql.select.join.JoinCriterion;
3133
import org.mybatis.dynamic.sql.select.join.JoinModel;
3234
import org.mybatis.dynamic.sql.select.join.JoinSpecification;
3335
import org.mybatis.dynamic.sql.select.join.JoinType;
@@ -37,9 +39,9 @@
3739

3840
public abstract class AbstractQueryExpressionDSL<W extends AbstractWhereFinisher<?>,
3941
T extends AbstractQueryExpressionDSL<W, T>>
40-
extends AbstractWhereStarter<W, T> {
42+
implements AbstractWhereStarter<W, T> {
4143

42-
private final List<JoinSpecification.Builder> joinSpecificationBuilders = new ArrayList<>();
44+
private final List<Supplier<JoinSpecification>> joinSpecificationSuppliers = new ArrayList<>();
4345
private final Map<SqlTable, String> tableAliases = new HashMap<>();
4446
private final TableExpression table;
4547

@@ -51,151 +53,151 @@ public TableExpression table() {
5153
return table;
5254
}
5355

54-
public T join(SqlTable joinTable, JoinCriterion<?> onJoinCriterion,
55-
JoinCriterion<?>... andJoinCriteria) {
56-
addJoinSpecificationBuilder(joinTable, onJoinCriterion, JoinType.INNER, Arrays.asList(andJoinCriteria));
56+
public T join(SqlTable joinTable, SqlCriterion onJoinCriterion,
57+
AndOrCriteriaGroup... andJoinCriteria) {
58+
addJoinSpecificationSupplier(joinTable, onJoinCriterion, JoinType.INNER, Arrays.asList(andJoinCriteria));
5759
return getThis();
5860
}
5961

60-
public T join(SqlTable joinTable, String tableAlias, JoinCriterion<?> onJoinCriterion,
61-
JoinCriterion<?>... andJoinCriteria) {
62+
public T join(SqlTable joinTable, String tableAlias, SqlCriterion onJoinCriterion,
63+
AndOrCriteriaGroup... andJoinCriteria) {
6264
addTableAlias(joinTable, tableAlias);
6365
return join(joinTable, onJoinCriterion, andJoinCriteria);
6466
}
6567

66-
public T join(SqlTable joinTable, JoinCriterion<?> onJoinCriterion,
67-
List<JoinCriterion<?>> andJoinCriteria) {
68-
addJoinSpecificationBuilder(joinTable, onJoinCriterion, JoinType.INNER, andJoinCriteria);
68+
public T join(SqlTable joinTable, SqlCriterion onJoinCriterion,
69+
List<AndOrCriteriaGroup> andJoinCriteria) {
70+
addJoinSpecificationSupplier(joinTable, onJoinCriterion, JoinType.INNER, andJoinCriteria);
6971
return getThis();
7072
}
7173

72-
public T join(SqlTable joinTable, String tableAlias, JoinCriterion<?> onJoinCriterion,
73-
List<JoinCriterion<?>> andJoinCriteria) {
74+
public T join(SqlTable joinTable, String tableAlias, SqlCriterion onJoinCriterion,
75+
List<AndOrCriteriaGroup> andJoinCriteria) {
7476
addTableAlias(joinTable, tableAlias);
7577
return join(joinTable, onJoinCriterion, andJoinCriteria);
7678
}
7779

78-
public T join(Buildable<SelectModel> subQuery, String tableAlias, JoinCriterion<?> onJoinCriterion,
79-
List<JoinCriterion<?>> andJoinCriteria) {
80-
addJoinSpecificationBuilder(buildSubQuery(subQuery, tableAlias), onJoinCriterion, JoinType.INNER,
80+
public T join(Buildable<SelectModel> subQuery, String tableAlias, SqlCriterion onJoinCriterion,
81+
List<AndOrCriteriaGroup> andJoinCriteria) {
82+
addJoinSpecificationSupplier(buildSubQuery(subQuery, tableAlias), onJoinCriterion, JoinType.INNER,
8183
andJoinCriteria);
8284
return getThis();
8385
}
8486

85-
public T leftJoin(SqlTable joinTable, JoinCriterion<?> onJoinCriterion,
86-
JoinCriterion<?>... andJoinCriteria) {
87-
addJoinSpecificationBuilder(joinTable, onJoinCriterion, JoinType.LEFT, Arrays.asList(andJoinCriteria));
87+
public T leftJoin(SqlTable joinTable, SqlCriterion onJoinCriterion,
88+
AndOrCriteriaGroup... andJoinCriteria) {
89+
addJoinSpecificationSupplier(joinTable, onJoinCriterion, JoinType.LEFT, Arrays.asList(andJoinCriteria));
8890
return getThis();
8991
}
9092

91-
public T leftJoin(SqlTable joinTable, String tableAlias, JoinCriterion<?> onJoinCriterion,
92-
JoinCriterion<?>... andJoinCriteria) {
93+
public T leftJoin(SqlTable joinTable, String tableAlias, SqlCriterion onJoinCriterion,
94+
AndOrCriteriaGroup... andJoinCriteria) {
9395
addTableAlias(joinTable, tableAlias);
9496
return leftJoin(joinTable, onJoinCriterion, andJoinCriteria);
9597
}
9698

97-
public T leftJoin(SqlTable joinTable, JoinCriterion<?> onJoinCriterion,
98-
List<JoinCriterion<?>> andJoinCriteria) {
99-
addJoinSpecificationBuilder(joinTable, onJoinCriterion, JoinType.LEFT, andJoinCriteria);
99+
public T leftJoin(SqlTable joinTable, SqlCriterion onJoinCriterion,
100+
List<AndOrCriteriaGroup> andJoinCriteria) {
101+
addJoinSpecificationSupplier(joinTable, onJoinCriterion, JoinType.LEFT, andJoinCriteria);
100102
return getThis();
101103
}
102104

103-
public T leftJoin(SqlTable joinTable, String tableAlias, JoinCriterion<?> onJoinCriterion,
104-
List<JoinCriterion<?>> andJoinCriteria) {
105+
public T leftJoin(SqlTable joinTable, String tableAlias, SqlCriterion onJoinCriterion,
106+
List<AndOrCriteriaGroup> andJoinCriteria) {
105107
addTableAlias(joinTable, tableAlias);
106108
return leftJoin(joinTable, onJoinCriterion, andJoinCriteria);
107109
}
108110

109-
public T leftJoin(Buildable<SelectModel> subQuery, String tableAlias, JoinCriterion<?> onJoinCriterion,
110-
List<JoinCriterion<?>> andJoinCriteria) {
111-
addJoinSpecificationBuilder(buildSubQuery(subQuery, tableAlias), onJoinCriterion, JoinType.LEFT,
111+
public T leftJoin(Buildable<SelectModel> subQuery, String tableAlias, SqlCriterion onJoinCriterion,
112+
List<AndOrCriteriaGroup> andJoinCriteria) {
113+
addJoinSpecificationSupplier(buildSubQuery(subQuery, tableAlias), onJoinCriterion, JoinType.LEFT,
112114
andJoinCriteria);
113115
return getThis();
114116
}
115117

116-
public T rightJoin(SqlTable joinTable, JoinCriterion<?> onJoinCriterion,
117-
JoinCriterion<?>... andJoinCriteria) {
118-
addJoinSpecificationBuilder(joinTable, onJoinCriterion, JoinType.RIGHT, Arrays.asList(andJoinCriteria));
118+
public T rightJoin(SqlTable joinTable, SqlCriterion onJoinCriterion,
119+
AndOrCriteriaGroup... andJoinCriteria) {
120+
addJoinSpecificationSupplier(joinTable, onJoinCriterion, JoinType.RIGHT, Arrays.asList(andJoinCriteria));
119121
return getThis();
120122
}
121123

122-
public T rightJoin(SqlTable joinTable, String tableAlias, JoinCriterion<?> onJoinCriterion,
123-
JoinCriterion<?>... andJoinCriteria) {
124+
public T rightJoin(SqlTable joinTable, String tableAlias, SqlCriterion onJoinCriterion,
125+
AndOrCriteriaGroup... andJoinCriteria) {
124126
addTableAlias(joinTable, tableAlias);
125127
return rightJoin(joinTable, onJoinCriterion, andJoinCriteria);
126128
}
127129

128-
public T rightJoin(SqlTable joinTable, JoinCriterion<?> onJoinCriterion,
129-
List<JoinCriterion<?>> andJoinCriteria) {
130-
addJoinSpecificationBuilder(joinTable, onJoinCriterion, JoinType.RIGHT, andJoinCriteria);
130+
public T rightJoin(SqlTable joinTable, SqlCriterion onJoinCriterion,
131+
List<AndOrCriteriaGroup> andJoinCriteria) {
132+
addJoinSpecificationSupplier(joinTable, onJoinCriterion, JoinType.RIGHT, andJoinCriteria);
131133
return getThis();
132134
}
133135

134-
public T rightJoin(SqlTable joinTable, String tableAlias, JoinCriterion<?> onJoinCriterion,
135-
List<JoinCriterion<?>> andJoinCriteria) {
136+
public T rightJoin(SqlTable joinTable, String tableAlias, SqlCriterion onJoinCriterion,
137+
List<AndOrCriteriaGroup> andJoinCriteria) {
136138
addTableAlias(joinTable, tableAlias);
137139
return rightJoin(joinTable, onJoinCriterion, andJoinCriteria);
138140
}
139141

140-
public T rightJoin(Buildable<SelectModel> subQuery, String tableAlias, JoinCriterion<?> onJoinCriterion,
141-
List<JoinCriterion<?>> andJoinCriteria) {
142-
addJoinSpecificationBuilder(buildSubQuery(subQuery, tableAlias), onJoinCriterion, JoinType.RIGHT,
142+
public T rightJoin(Buildable<SelectModel> subQuery, String tableAlias, SqlCriterion onJoinCriterion,
143+
List<AndOrCriteriaGroup> andJoinCriteria) {
144+
addJoinSpecificationSupplier(buildSubQuery(subQuery, tableAlias), onJoinCriterion, JoinType.RIGHT,
143145
andJoinCriteria);
144146
return getThis();
145147
}
146148

147-
public T fullJoin(SqlTable joinTable, JoinCriterion<?> onJoinCriterion,
148-
JoinCriterion<?>... andJoinCriteria) {
149-
addJoinSpecificationBuilder(joinTable, onJoinCriterion, JoinType.FULL, Arrays.asList(andJoinCriteria));
149+
public T fullJoin(SqlTable joinTable, SqlCriterion onJoinCriterion,
150+
AndOrCriteriaGroup... andJoinCriteria) {
151+
addJoinSpecificationSupplier(joinTable, onJoinCriterion, JoinType.FULL, Arrays.asList(andJoinCriteria));
150152
return getThis();
151153
}
152154

153-
public T fullJoin(SqlTable joinTable, String tableAlias, JoinCriterion<?> onJoinCriterion,
154-
JoinCriterion<?>... andJoinCriteria) {
155+
public T fullJoin(SqlTable joinTable, String tableAlias, SqlCriterion onJoinCriterion,
156+
AndOrCriteriaGroup... andJoinCriteria) {
155157
addTableAlias(joinTable, tableAlias);
156158
return fullJoin(joinTable, onJoinCriterion, andJoinCriteria);
157159
}
158160

159-
public T fullJoin(SqlTable joinTable, JoinCriterion<?> onJoinCriterion,
160-
List<JoinCriterion<?>> andJoinCriteria) {
161-
addJoinSpecificationBuilder(joinTable, onJoinCriterion, JoinType.FULL, andJoinCriteria);
161+
public T fullJoin(SqlTable joinTable, SqlCriterion onJoinCriterion,
162+
List<AndOrCriteriaGroup> andJoinCriteria) {
163+
addJoinSpecificationSupplier(joinTable, onJoinCriterion, JoinType.FULL, andJoinCriteria);
162164
return getThis();
163165
}
164166

165-
public T fullJoin(SqlTable joinTable, String tableAlias, JoinCriterion<?> onJoinCriterion,
166-
List<JoinCriterion<?>> andJoinCriteria) {
167+
public T fullJoin(SqlTable joinTable, String tableAlias, SqlCriterion onJoinCriterion,
168+
List<AndOrCriteriaGroup> andJoinCriteria) {
167169
addTableAlias(joinTable, tableAlias);
168170
return fullJoin(joinTable, onJoinCriterion, andJoinCriteria);
169171
}
170172

171-
public T fullJoin(Buildable<SelectModel> subQuery, String tableAlias, JoinCriterion<?> onJoinCriterion,
172-
List<JoinCriterion<?>> andJoinCriteria) {
173-
addJoinSpecificationBuilder(buildSubQuery(subQuery, tableAlias), onJoinCriterion, JoinType.FULL,
173+
public T fullJoin(Buildable<SelectModel> subQuery, String tableAlias, SqlCriterion onJoinCriterion,
174+
List<AndOrCriteriaGroup> andJoinCriteria) {
175+
addJoinSpecificationSupplier(buildSubQuery(subQuery, tableAlias), onJoinCriterion, JoinType.FULL,
174176
andJoinCriteria);
175177
return getThis();
176178
}
177179

178-
private void addJoinSpecificationBuilder(TableExpression joinTable, JoinCriterion<?> onJoinCriterion,
179-
JoinType joinType, List<JoinCriterion<?>> andJoinCriteria) {
180-
joinSpecificationBuilders.add(new JoinSpecification.Builder()
180+
private void addJoinSpecificationSupplier(TableExpression joinTable, SqlCriterion onJoinCriterion,
181+
JoinType joinType, List<AndOrCriteriaGroup> andJoinCriteria) {
182+
joinSpecificationSuppliers.add(() -> new JoinSpecification.Builder()
181183
.withJoinTable(joinTable)
182184
.withJoinType(joinType)
183-
.withJoinCriterion(onJoinCriterion)
184-
.withJoinCriteria(andJoinCriteria));
185+
.withInitialCriterion(onJoinCriterion)
186+
.withSubCriteria(andJoinCriteria).build());
185187
}
186188

187-
protected void addJoinSpecificationBuilder(JoinSpecification.Builder builder) {
188-
joinSpecificationBuilders.add(builder);
189+
protected void addJoinSpecificationSupplier(Supplier<JoinSpecification> joinSpecificationSupplier) {
190+
joinSpecificationSuppliers.add(joinSpecificationSupplier);
189191
}
190192

191193
protected Optional<JoinModel> buildJoinModel() {
192-
if (joinSpecificationBuilders.isEmpty()) {
194+
if (joinSpecificationSuppliers.isEmpty()) {
193195
return Optional.empty();
194196
}
195197

196-
return Optional.of(JoinModel.of(joinSpecificationBuilders.stream()
197-
.map(JoinSpecification.Builder::build)
198-
.toList()));
198+
return Optional.of(JoinModel.of(joinSpecificationSuppliers.stream()
199+
.map(Supplier::get)
200+
.toList()));
199201
}
200202

201203
protected void addTableAlias(SqlTable table, String tableAlias) {

src/main/java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public OffsetFirstFinisher<MultiSelectModel> offsetWhenPresent(Long offset) {
7777
@Override
7878
public FetchFirstFinisher<MultiSelectModel> fetchFirstWhenPresent(Long fetchFirstRows) {
7979
this.fetchFirstRows = fetchFirstRows;
80-
return () -> MultiSelectDSL.this;
80+
return () -> this;
8181
}
8282

8383
@NotNull

0 commit comments

Comments
 (0)