2121import java .util .List ;
2222import java .util .Map ;
2323import java .util .Objects ;
24+ import java .util .Optional ;
25+ import java .util .function .Supplier ;
2426
2527import org .mybatis .dynamic .sql .BasicColumn ;
2628import org .mybatis .dynamic .sql .BindableColumn ;
@@ -49,13 +51,15 @@ public class QueryExpressionDSL<R> implements Buildable<R> {
4951 private GroupByModel groupByModel ;
5052 private JoinModel joinModel ;
5153 private List <JoinSpecification > joinSpecifications = new ArrayList <>();
54+ private Supplier <R > buildDelegateMethod ;
5255
5356 private QueryExpressionDSL (FromGatherer <R > fromGatherer ) {
5457 connector = fromGatherer .connector ;
5558 selectList = Arrays .asList (fromGatherer .selectList );
5659 isDistinct = fromGatherer .isDistinct ;
5760 selectDSL = Objects .requireNonNull (fromGatherer .selectDSL );
5861 table = Objects .requireNonNull (fromGatherer .table );
62+ buildDelegateMethod = this ::internalBuild ;
5963 }
6064
6165 private QueryExpressionDSL (FromGatherer <R > fromGatherer , String tableAlias ) {
@@ -89,6 +93,10 @@ public <T> QueryExpressionWhereBuilder where(BindableColumn<T> column, Visitable
8993
9094 @ Override
9195 public R build () {
96+ return buildDelegateMethod .get ();
97+ }
98+
99+ private R internalBuild () {
92100 selectDSL .addQueryExpression (buildModel ());
93101 return selectDSL .build ();
94102 }
@@ -136,6 +144,7 @@ public GroupByFinisher groupBy(BasicColumn...columns) {
136144 }
137145
138146 public SelectDSL <R > orderBy (SortSpecification ...columns ) {
147+ buildDelegateMethod = selectDSL ::build ;
139148 selectDSL .addQueryExpression (buildModel ());
140149 selectDSL .setOrderByModel (OrderByModel .of (columns ));
141150 return selectDSL ;
@@ -164,16 +173,19 @@ protected QueryExpressionModel buildModel() {
164173 }
165174
166175 public SelectDSL <R >.LimitFinisher limit (long limit ) {
176+ buildDelegateMethod = selectDSL ::build ;
167177 selectDSL .addQueryExpression (buildModel ());
168178 return selectDSL .limit (limit );
169179 }
170180
171181 public SelectDSL <R >.OffsetFirstFinisher offset (long offset ) {
182+ buildDelegateMethod = selectDSL ::build ;
172183 selectDSL .addQueryExpression (buildModel ());
173184 return selectDSL .offset (offset );
174185 }
175186
176187 public SelectDSL <R >.FetchFirstFinisher fetchFirst (long fetchFirstRows ) {
188+ buildDelegateMethod = selectDSL ::build ;
177189 selectDSL .addQueryExpression (buildModel ());
178190 return selectDSL .fetchFirst (fetchFirstRows );
179191 }
@@ -184,29 +196,37 @@ public static class FromGatherer<R> {
184196 private SelectDSL <R > selectDSL ;
185197 private boolean isDistinct ;
186198 private SqlTable table ;
199+ private Optional <QueryExpressionDSL <R >> priorQuery ;
187200
188201 public FromGatherer (Builder <R > builder ) {
189202 this .connector = builder .connector ;
190203 this .selectList = Objects .requireNonNull (builder .selectList );
191204 this .selectDSL = Objects .requireNonNull (builder .selectDSL );
192205 this .isDistinct = builder .isDistinct ;
206+ this .priorQuery = Optional .ofNullable (builder .priorQuery );
193207 }
194208
195209 public QueryExpressionDSL <R > from (SqlTable table ) {
196210 this .table = table ;
197- return new QueryExpressionDSL <>(this );
211+ return setPriorBuildDelegate ( new QueryExpressionDSL <>(this ) );
198212 }
199213
200214 public QueryExpressionDSL <R > from (SqlTable table , String tableAlias ) {
201215 this .table = table ;
202- return new QueryExpressionDSL <>(this , tableAlias );
216+ return setPriorBuildDelegate (new QueryExpressionDSL <>(this , tableAlias ));
217+ }
218+
219+ private QueryExpressionDSL <R > setPriorBuildDelegate (QueryExpressionDSL <R > newQuery ) {
220+ priorQuery .ifPresent (pq -> pq .buildDelegateMethod = newQuery ::build );
221+ return newQuery ;
203222 }
204223
205224 public static class Builder <R > {
206225 private String connector ;
207226 private BasicColumn [] selectList ;
208227 private SelectDSL <R > selectDSL ;
209228 private boolean isDistinct ;
229+ private QueryExpressionDSL <R > priorQuery ;
210230
211231 public Builder <R > withConnector (String connector ) {
212232 this .connector = connector ;
@@ -228,6 +248,11 @@ public Builder<R> isDistinct() {
228248 return this ;
229249 }
230250
251+ public Builder <R > withPriorQuery (QueryExpressionDSL <R > priorQuery ) {
252+ this .priorQuery = priorQuery ;
253+ return this ;
254+ }
255+
231256 public FromGatherer <R > build () {
232257 return new FromGatherer <>(this );
233258 }
@@ -238,11 +263,13 @@ public class QueryExpressionWhereBuilder extends AbstractWhereDSL<QueryExpressio
238263 implements Buildable <R > {
239264 private <T > QueryExpressionWhereBuilder (BindableColumn <T > column , VisitableCondition <T > condition ) {
240265 super (column , condition );
266+ buildDelegateMethod = this ::internalBuild ;
241267 }
242268
243269 private <T > QueryExpressionWhereBuilder (BindableColumn <T > column , VisitableCondition <T > condition ,
244270 SqlCriterion <?>...subCriteria ) {
245271 super (column , condition , subCriteria );
272+ buildDelegateMethod = this ::internalBuild ;
246273 }
247274
248275 public UnionBuilder union () {
@@ -258,6 +285,7 @@ public UnionBuilder unionAll() {
258285 }
259286
260287 public SelectDSL <R > orderBy (SortSpecification ...columns ) {
288+ buildDelegateMethod = selectDSL ::build ;
261289 whereModel = buildWhereModel ();
262290 selectDSL .addQueryExpression (buildModel ());
263291 selectDSL .setOrderByModel (OrderByModel .of (columns ));
@@ -272,25 +300,32 @@ public GroupByFinisher groupBy(BasicColumn...columns) {
272300 }
273301
274302 public SelectDSL <R >.LimitFinisher limit (long limit ) {
303+ buildDelegateMethod = selectDSL ::build ;
275304 whereModel = buildWhereModel ();
276305 selectDSL .addQueryExpression (buildModel ());
277306 return selectDSL .limit (limit );
278307 }
279308
280309 public SelectDSL <R >.OffsetFirstFinisher offset (long offset ) {
310+ buildDelegateMethod = selectDSL ::build ;
281311 whereModel = buildWhereModel ();
282312 selectDSL .addQueryExpression (buildModel ());
283313 return selectDSL .offset (offset );
284314 }
285315
286316 public SelectDSL <R >.FetchFirstFinisher fetchFirst (long fetchFirstRows ) {
317+ buildDelegateMethod = selectDSL ::build ;
287318 whereModel = buildWhereModel ();
288319 selectDSL .addQueryExpression (buildModel ());
289320 return selectDSL .fetchFirst (fetchFirstRows );
290321 }
291322
292323 @ Override
293324 public R build () {
325+ return buildDelegateMethod .get ();
326+ }
327+
328+ private R internalBuild () {
294329 whereModel = buildWhereModel ();
295330 selectDSL .addQueryExpression (buildModel ());
296331 return selectDSL .build ();
@@ -322,7 +357,6 @@ public JoinSpecificationFinisher on(BasicColumn joinColumn, JoinCondition joinCo
322357 }
323358
324359 public class JoinSpecificationFinisher implements Buildable <R > {
325-
326360 private SqlTable joinTable ;
327361 private List <JoinCriterion > joinCriteria = new ArrayList <>();
328362 private JoinType joinType ;
@@ -338,6 +372,7 @@ public JoinSpecificationFinisher(SqlTable table, BasicColumn joinColumn,
338372 .build ();
339373
340374 joinCriteria .add (joinCriterion );
375+ buildDelegateMethod = this ::internalbuild ;
341376 }
342377
343378 public JoinSpecificationFinisher (SqlTable table , BasicColumn joinColumn ,
@@ -352,6 +387,7 @@ public JoinSpecificationFinisher(SqlTable table, BasicColumn joinColumn,
352387
353388 this .joinCriteria .add (joinCriterion );
354389 this .joinCriteria .addAll (Arrays .asList (joinCriteria ));
390+ buildDelegateMethod = this ::internalbuild ;
355391 }
356392
357393 protected JoinSpecification buildJoinSpecification () {
@@ -368,6 +404,10 @@ protected JoinModel buildJoinModel() {
368404
369405 @ Override
370406 public R build () {
407+ return buildDelegateMethod .get ();
408+ }
409+
410+ private R internalbuild () {
371411 joinModel = buildJoinModel ();
372412 selectDSL .addQueryExpression (buildModel ());
373413 return selectDSL .build ();
@@ -434,51 +474,67 @@ public JoinSpecificationStarter fullJoin(SqlTable joinTable, String tableAlias)
434474 }
435475
436476 public SelectDSL <R > orderBy (SortSpecification ...columns ) {
477+ buildDelegateMethod = selectDSL ::build ;
437478 joinModel = buildJoinModel ();
438479 selectDSL .addQueryExpression (buildModel ());
439480 selectDSL .setOrderByModel (OrderByModel .of (columns ));
440481 return selectDSL ;
441482 }
442483
443484 public SelectDSL <R >.LimitFinisher limit (long limit ) {
485+ buildDelegateMethod = selectDSL ::build ;
444486 joinModel = buildJoinModel ();
445487 selectDSL .addQueryExpression (buildModel ());
446488 return selectDSL .limit (limit );
447489 }
448490
449491 public SelectDSL <R >.OffsetFirstFinisher offset (long offset ) {
492+ buildDelegateMethod = selectDSL ::build ;
450493 joinModel = buildJoinModel ();
451494 selectDSL .addQueryExpression (buildModel ());
452495 return selectDSL .offset (offset );
453496 }
454497
455498 public SelectDSL <R >.FetchFirstFinisher fetchFirst (long fetchFirstRows ) {
499+ buildDelegateMethod = selectDSL ::build ;
456500 joinModel = buildJoinModel ();
457501 selectDSL .addQueryExpression (buildModel ());
458502 return selectDSL .fetchFirst (fetchFirstRows );
459503 }
460504 }
461505
462506 public class GroupByFinisher implements Buildable <R > {
507+ public GroupByFinisher () {
508+ buildDelegateMethod = this ::internalBuild ;
509+ }
510+
463511 public SelectDSL <R > orderBy (SortSpecification ...columns ) {
512+ buildDelegateMethod = selectDSL ::build ;
464513 selectDSL .setOrderByModel (OrderByModel .of (columns ));
465514 return selectDSL ;
466515 }
467516
468517 @ Override
469518 public R build () {
519+ return buildDelegateMethod .get ();
520+ }
521+
522+ private R internalBuild () {
470523 return selectDSL .build ();
471524 }
472525
473526 public SelectDSL <R >.LimitFinisher limit (long limit ) {
527+ buildDelegateMethod = selectDSL ::build ;
474528 return selectDSL .limit (limit );
475529 }
476530
477531 public SelectDSL <R >.OffsetFirstFinisher offset (long offset ) {
532+ buildDelegateMethod = selectDSL ::build ;
478533 return selectDSL .offset (offset );
479534 }
480535
481536 public SelectDSL <R >.FetchFirstFinisher fetchFirst (long fetchFirstRows ) {
537+ buildDelegateMethod = selectDSL ::build ;
482538 return selectDSL .fetchFirst (fetchFirstRows );
483539 }
484540 }
@@ -495,6 +551,7 @@ public FromGatherer<R> select(BasicColumn...selectList) {
495551 .withConnector (connector )
496552 .withSelectList (selectList )
497553 .withSelectDSL (selectDSL )
554+ .withPriorQuery (QueryExpressionDSL .this )
498555 .build ();
499556 }
500557
@@ -504,6 +561,7 @@ public FromGatherer<R> selectDistinct(BasicColumn...selectList) {
504561 .withSelectList (selectList )
505562 .withSelectDSL (selectDSL )
506563 .isDistinct ()
564+ .withPriorQuery (QueryExpressionDSL .this )
507565 .build ();
508566 }
509567 }
0 commit comments