001/*
002 *  Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
003 *  <p>
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *  <p>
008 *  http://www.apache.org/licenses/LICENSE-2.0
009 *  <p>
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package com.mybatisflex.core.query;
017
018import com.mybatisflex.core.FlexConsts;
019import com.mybatisflex.core.constant.SqlConnector;
020import com.mybatisflex.core.constant.SqlConsts;
021import com.mybatisflex.core.constant.SqlOperator;
022import com.mybatisflex.core.dialect.DialectFactory;
023import com.mybatisflex.core.table.TableDef;
024import com.mybatisflex.core.table.TableInfo;
025import com.mybatisflex.core.table.TableInfoFactory;
026import com.mybatisflex.core.util.*;
027
028import java.util.*;
029import java.util.function.Consumer;
030
031public class QueryWrapper extends BaseQueryWrapper<QueryWrapper> {
032
033    public static QueryWrapper create() {
034        return new QueryWrapper();
035    }
036
037    /**
038     * 根据实体类对象,构建查询条件
039     *
040     * @param entity 实体类对象
041     * @return 查询对象 QueryWrapper
042     */
043    public static QueryWrapper create(Object entity) {
044        TableInfo tableInfo = TableInfoFactory.ofEntityClass(ClassUtil.getUsefulClass(entity.getClass()));
045        return tableInfo.buildQueryWrapper(entity, null);
046    }
047
048    /**
049     * 根据实体类构建查询条件
050     *
051     * @param entity    实体类对象
052     * @param operators 每个属性对应的操作符
053     * @return 查询对象 QueryWrapper
054     */
055    public static QueryWrapper create(Object entity, SqlOperators operators) {
056        TableInfo tableInfo = TableInfoFactory.ofEntityClass(ClassUtil.getUsefulClass(entity.getClass()));
057        return tableInfo.buildQueryWrapper(entity, operators);
058    }
059
060
061    @SuppressWarnings("unchecked")
062    public <Q extends QueryWrapper> WithBuilder<Q> with(String name) {
063        if (with == null) {
064            with = new With();
065        }
066        return new WithBuilder<>((Q) this, with, name);
067    }
068
069    @SuppressWarnings("unchecked")
070    public <Q extends QueryWrapper> WithBuilder<Q> with(String name, String... params) {
071        if (with == null) {
072            with = new With();
073        }
074        return new WithBuilder<>((Q) this, with, name, Arrays.asList(params));
075    }
076
077    @SuppressWarnings("unchecked")
078    public <Q extends QueryWrapper> WithBuilder<Q> withRecursive(String name) {
079        if (with == null) {
080            with = new With(true);
081        }
082        return new WithBuilder<>((Q) this, with, name);
083    }
084
085    @SuppressWarnings("unchecked")
086    public <Q extends QueryWrapper> WithBuilder<Q> withRecursive(String name, String... params) {
087        if (with == null) {
088            with = new With(true);
089        }
090        return new WithBuilder<>((Q) this, with, name, Arrays.asList(params));
091    }
092
093    public QueryWrapper select() {
094        return this;
095    }
096
097    public QueryWrapper select(String... columns) {
098        for (String column : columns) {
099            addSelectColumn(new RawQueryColumn(column));
100        }
101        return this;
102    }
103
104    public <T> QueryWrapper select(LambdaGetter<T>... lambdaGetters) {
105        for (LambdaGetter<T> lambdaGetter : lambdaGetters) {
106            QueryColumn queryColumn = LambdaUtil.getQueryColumn(lambdaGetter);
107            addSelectColumn(queryColumn);
108        }
109        return this;
110    }
111
112    public QueryWrapper select(QueryColumn... queryColumns) {
113        for (QueryColumn column : queryColumns) {
114            if (column != null) {
115                addSelectColumn(column);
116            }
117        }
118        return this;
119    }
120
121    public QueryWrapper select(QueryColumn[]... queryColumns) {
122        for (QueryColumn[] columnArray : queryColumns) {
123            if (columnArray != null) {
124                for (QueryColumn column : columnArray) {
125                    if (column != null) {
126                        addSelectColumn(column);
127                    }
128                }
129            }
130        }
131        return this;
132    }
133
134    public QueryWrapper select(QueryColumn[] queryColumns, QueryColumn... queryColumns2) {
135        for (QueryColumn column : queryColumns) {
136            if (column != null) {
137                addSelectColumn(column);
138            }
139        }
140        for (QueryColumn column : queryColumns2) {
141            if (column != null) {
142                addSelectColumn(column);
143            }
144        }
145        return this;
146    }
147
148    public QueryWrapper from(TableDef... tableDefs) {
149        for (TableDef tableDef : tableDefs) {
150            from(new QueryTable(tableDef));
151        }
152        return this;
153    }
154
155    public QueryWrapper from(Class<?>... entityClasses) {
156        for (Class<?> entityClass : entityClasses) {
157            TableInfo tableInfo = TableInfoFactory.ofEntityClass(entityClass);
158            from(new QueryTable(tableInfo.getSchema(), tableInfo.getTableName()));
159        }
160        return this;
161    }
162
163    public QueryWrapper from(String... tables) {
164        for (String table : tables) {
165            if (StringUtil.isBlank(table)) {
166                throw new IllegalArgumentException("table must not be null or blank.");
167            }
168            from(new QueryTable(table));
169        }
170        return this;
171    }
172
173    public QueryWrapper from(QueryTable... tables) {
174        if (CollectionUtil.isEmpty(queryTables)) {
175            queryTables = new ArrayList<>();
176            queryTables.addAll(Arrays.asList(tables));
177        } else {
178            for (QueryTable table : tables) {
179                boolean contains = false;
180                for (QueryTable queryTable : queryTables) {
181                    if (queryTable.isSameTable(table)) {
182                        contains = true;
183                    }
184                }
185                if (!contains) {
186                    queryTables.add(table);
187                }
188            }
189        }
190        return this;
191    }
192
193    public QueryWrapper from(QueryWrapper queryWrapper) {
194        return from(new SelectQueryTable(queryWrapper));
195    }
196
197    public QueryWrapper as(String alias) {
198        if (CollectionUtil.isEmpty(queryTables)) {
199            throw new IllegalArgumentException("query table must not be empty.");
200        }
201        queryTables.get(queryTables.size() - 1).alias = alias;
202        return this;
203    }
204
205    public QueryWrapper where(QueryCondition queryCondition) {
206        this.setWhereQueryCondition(queryCondition);
207        return this;
208    }
209
210    public QueryWrapper where(String sql) {
211        this.setWhereQueryCondition(new RawFragment(sql));
212        return this;
213    }
214
215    public QueryWrapper where(String sql, Object... params) {
216        this.setWhereQueryCondition(new RawFragment(sql, params));
217        return this;
218    }
219
220    public QueryWrapper where(Map<String, Object> whereConditions) {
221        return and(whereConditions);
222    }
223
224    public QueryWrapper where(Map<String, Object> whereConditions, SqlOperators operators) {
225        return and(whereConditions, operators);
226    }
227
228    public <T> QueryConditionBuilder<? extends QueryWrapper> where(LambdaGetter<T> fn) {
229        return new QueryConditionBuilder<>(this, LambdaUtil.getQueryColumn(fn), SqlConnector.AND);
230    }
231
232    public QueryWrapper where(Consumer<QueryWrapper> consumer) {
233        return and(consumer);
234    }
235
236    public QueryWrapper and(QueryCondition queryCondition) {
237        return addWhereQueryCondition(queryCondition, SqlConnector.AND);
238    }
239
240    public QueryWrapper and(String sql) {
241        this.addWhereQueryCondition(new RawFragment(sql), SqlConnector.AND);
242        return this;
243    }
244
245    public QueryWrapper and(String sql, Object... params) {
246        this.addWhereQueryCondition(new RawFragment(sql, params), SqlConnector.AND);
247        return this;
248    }
249
250    public <T> QueryConditionBuilder<? extends QueryWrapper> and(LambdaGetter<T> fn) {
251        return new QueryConditionBuilder<>(this, LambdaUtil.getQueryColumn(fn), SqlConnector.AND);
252    }
253
254    public QueryWrapper and(Consumer<QueryWrapper> consumer) {
255        return and(consumer, true);
256    }
257
258    public QueryWrapper and(Consumer<QueryWrapper> consumer, boolean condition) {
259        if (!condition) {
260            return this;
261        }
262        QueryWrapper newWrapper = new QueryWrapper();
263        consumer.accept(newWrapper);
264        QueryCondition whereQueryCondition = newWrapper.whereQueryCondition;
265        if (whereQueryCondition != null) {
266            and(new Brackets(whereQueryCondition));
267        }
268        return this;
269    }
270
271
272    public QueryWrapper and(Map<String, Object> whereConditions) {
273        return and(whereConditions, SqlOperators.empty());
274    }
275
276    public QueryWrapper and(Map<String, Object> whereConditions, SqlOperators operators) {
277        return connectMap(whereConditions, operators, SqlConnector.AND, SqlConnector.AND);
278    }
279
280    public QueryWrapper and(Map<String, Object> whereConditions, SqlOperators operators, SqlConnector innerConnector) {
281        return connectMap(whereConditions, operators, SqlConnector.AND, innerConnector);
282    }
283
284
285    public QueryWrapper or(QueryCondition queryCondition) {
286        return addWhereQueryCondition(queryCondition, SqlConnector.OR);
287    }
288
289    public QueryWrapper or(String sql) {
290        this.addWhereQueryCondition(new RawFragment(sql), SqlConnector.OR);
291        return this;
292    }
293
294    public QueryWrapper or(String sql, Object... params) {
295        this.addWhereQueryCondition(new RawFragment(sql, params), SqlConnector.OR);
296        return this;
297    }
298
299    public <T> QueryConditionBuilder<? extends QueryWrapper> or(LambdaGetter<T> fn) {
300        return new QueryConditionBuilder<>(this, LambdaUtil.getQueryColumn(fn), SqlConnector.OR);
301    }
302
303    public QueryWrapper or(Consumer<QueryWrapper> consumer) {
304        return or(consumer, true);
305    }
306
307    public QueryWrapper or(Consumer<QueryWrapper> consumer, boolean condition) {
308        if (!condition) {
309            return this;
310        }
311        QueryWrapper newWrapper = new QueryWrapper();
312        consumer.accept(newWrapper);
313        QueryCondition whereQueryCondition = newWrapper.whereQueryCondition;
314        if (whereQueryCondition != null) {
315            or(new Brackets(whereQueryCondition));
316        }
317        return this;
318    }
319
320
321    public QueryWrapper or(Map<String, Object> whereConditions) {
322        return or(whereConditions, SqlOperators.empty());
323    }
324
325    public QueryWrapper or(Map<String, Object> whereConditions, SqlOperators operators) {
326        return connectMap(whereConditions, operators, SqlConnector.OR, SqlConnector.AND);
327    }
328
329    public QueryWrapper or(Map<String, Object> whereConditions, SqlOperators operators, SqlConnector innerConnector) {
330        return connectMap(whereConditions, operators, SqlConnector.OR, SqlConnector.AND);
331    }
332
333    protected QueryWrapper connectMap(Map<String, Object> mapConditions, SqlOperators operators, SqlConnector outerConnector, SqlConnector innerConnector) {
334        if (operators == null) {
335            operators = SqlOperators.empty();
336        }
337        if (mapConditions != null) {
338            QueryCondition condition = null;
339            for (Map.Entry<String, Object> entry : mapConditions.entrySet()) {
340                SqlOperator operator = operators.get(entry.getKey());
341                if (operator == null) {
342                    operator = SqlOperator.EQUALS;
343                }
344                QueryCondition cond = QueryCondition.create(new QueryColumn(entry.getKey()), operator.getValue(), entry.getValue());
345                if (condition == null) {
346                    condition = cond;
347                } else {
348                    if (innerConnector == SqlConnector.AND) {
349                        condition.and(cond);
350                    } else {
351                        condition.or(cond);
352                    }
353                }
354            }
355            addWhereQueryCondition(condition, outerConnector);
356        }
357        return this;
358    }
359
360
361    public <Q extends QueryWrapper> Joiner<Q> leftJoin(String table) {
362        return joining(SqlConsts.LEFT_JOIN, new QueryTable(table), true);
363    }
364
365    public <Q extends QueryWrapper> Joiner<Q> leftJoin(String table, boolean when) {
366        return joining(SqlConsts.LEFT_JOIN, new QueryTable(table), when);
367    }
368
369    public <Q extends QueryWrapper> Joiner<Q> leftJoin(Class<?> entityClass) {
370        return joining(SqlConsts.LEFT_JOIN, entityClass, true);
371    }
372
373    public <Q extends QueryWrapper> Joiner<Q> leftJoin(Class<?> entityClass, boolean when) {
374        return joining(SqlConsts.LEFT_JOIN, entityClass, when);
375    }
376
377    public <Q extends QueryWrapper> Joiner<Q> leftJoin(TableDef table) {
378        return joining(SqlConsts.LEFT_JOIN, new QueryTable(table), true);
379    }
380
381    public <Q extends QueryWrapper> Joiner<Q> leftJoin(TableDef table, boolean when) {
382        return joining(SqlConsts.LEFT_JOIN, new QueryTable(table), when);
383    }
384
385    public <Q extends QueryWrapper> Joiner<Q> leftJoin(QueryWrapper table) {
386        return joining(SqlConsts.LEFT_JOIN, table, true);
387    }
388
389    public <Q extends QueryWrapper> Joiner<Q> leftJoin(QueryWrapper table, boolean when) {
390        return joining(SqlConsts.LEFT_JOIN, table, when);
391    }
392
393    public <Q extends QueryWrapper> Joiner<Q> rightJoin(String table) {
394        return joining(SqlConsts.RIGHT_JOIN, new QueryTable(table), true);
395    }
396
397    public <Q extends QueryWrapper> Joiner<Q> rightJoin(String table, boolean when) {
398        return joining(SqlConsts.RIGHT_JOIN, new QueryTable(table), when);
399    }
400
401    public <Q extends QueryWrapper> Joiner<Q> rightJoin(Class<?> entityClass) {
402        return joining(SqlConsts.RIGHT_JOIN, entityClass, true);
403    }
404
405    public <Q extends QueryWrapper> Joiner<Q> rightJoin(Class<?> entityClass, boolean when) {
406        return joining(SqlConsts.RIGHT_JOIN, entityClass, when);
407    }
408
409    public <Q extends QueryWrapper> Joiner<Q> rightJoin(TableDef table) {
410        return joining(SqlConsts.RIGHT_JOIN, new QueryTable(table), true);
411    }
412
413    public <Q extends QueryWrapper> Joiner<Q> rightJoin(TableDef table, boolean when) {
414        return joining(SqlConsts.RIGHT_JOIN, new QueryTable(table), when);
415    }
416
417    public <Q extends QueryWrapper> Joiner<Q> rightJoin(QueryWrapper table) {
418        return joining(SqlConsts.RIGHT_JOIN, table, true);
419    }
420
421    public <Q extends QueryWrapper> Joiner<Q> rightJoin(QueryWrapper table, boolean when) {
422        return joining(SqlConsts.RIGHT_JOIN, table, when);
423    }
424
425    public <Q extends QueryWrapper> Joiner<Q> innerJoin(String table) {
426        return joining(SqlConsts.INNER_JOIN, new QueryTable(table), true);
427    }
428
429    public <Q extends QueryWrapper> Joiner<Q> innerJoin(String table, boolean when) {
430        return joining(SqlConsts.INNER_JOIN, new QueryTable(table), when);
431    }
432
433    public <Q extends QueryWrapper> Joiner<Q> innerJoin(Class<?> entityClass) {
434        return joining(SqlConsts.INNER_JOIN, entityClass, true);
435    }
436
437    public <Q extends QueryWrapper> Joiner<Q> innerJoin(Class<?> entityClass, boolean when) {
438        return joining(SqlConsts.INNER_JOIN, entityClass, when);
439    }
440
441    public <Q extends QueryWrapper> Joiner<Q> innerJoin(TableDef table) {
442        return innerJoin(table, true);
443    }
444
445    public <Q extends QueryWrapper> Joiner<Q> innerJoin(TableDef table, boolean when) {
446        return joining(SqlConsts.INNER_JOIN, new QueryTable(table), when);
447    }
448
449    public <Q extends QueryWrapper> Joiner<Q> innerJoin(QueryWrapper table) {
450        return joining(SqlConsts.INNER_JOIN, table, true);
451    }
452
453    public <Q extends QueryWrapper> Joiner<Q> innerJoin(QueryWrapper table, boolean when) {
454        return joining(SqlConsts.INNER_JOIN, table, when);
455    }
456
457    public <Q extends QueryWrapper> Joiner<Q> fullJoin(String table) {
458        return joining(SqlConsts.FULL_JOIN, new QueryTable(table), true);
459    }
460
461    public <Q extends QueryWrapper> Joiner<Q> fullJoin(String table, boolean when) {
462        return joining(SqlConsts.FULL_JOIN, new QueryTable(table), when);
463    }
464
465    public <Q extends QueryWrapper> Joiner<Q> fullJoin(Class<?> entityClass) {
466        return joining(SqlConsts.FULL_JOIN, entityClass, true);
467    }
468
469    public <Q extends QueryWrapper> Joiner<Q> fullJoin(Class<?> entityClass, boolean when) {
470        return joining(SqlConsts.FULL_JOIN, entityClass, when);
471    }
472
473    public <Q extends QueryWrapper> Joiner<Q> fullJoin(TableDef table) {
474        return joining(SqlConsts.FULL_JOIN, new QueryTable(table), true);
475    }
476
477    public <Q extends QueryWrapper> Joiner<Q> fullJoin(TableDef table, boolean when) {
478        return joining(SqlConsts.FULL_JOIN, new QueryTable(table), when);
479    }
480
481    public <Q extends QueryWrapper> Joiner<Q> fullJoin(QueryWrapper table) {
482        return joining(SqlConsts.FULL_JOIN, table, true);
483    }
484
485    public <Q extends QueryWrapper> Joiner<Q> fullJoin(QueryWrapper table, boolean when) {
486        return joining(SqlConsts.FULL_JOIN, table, when);
487    }
488
489    public <Q extends QueryWrapper> Joiner<Q> crossJoin(String table) {
490        return joining(SqlConsts.CROSS_JOIN, new QueryTable(table), true);
491    }
492
493    public <Q extends QueryWrapper> Joiner<Q> crossJoin(String table, boolean when) {
494        return joining(SqlConsts.CROSS_JOIN, new QueryTable(table), when);
495    }
496
497    public <Q extends QueryWrapper> Joiner<Q> crossJoin(Class<?> entityClass) {
498        return joining(SqlConsts.CROSS_JOIN, entityClass, true);
499    }
500
501    public <Q extends QueryWrapper> Joiner<Q> crossJoin(Class<?> entityClass, boolean when) {
502        return joining(SqlConsts.CROSS_JOIN, entityClass, when);
503    }
504
505    public <Q extends QueryWrapper> Joiner<Q> crossJoin(TableDef table) {
506        return joining(SqlConsts.CROSS_JOIN, new QueryTable(table), true);
507    }
508
509    public <Q extends QueryWrapper> Joiner<Q> crossJoin(TableDef table, boolean when) {
510        return joining(SqlConsts.CROSS_JOIN, new QueryTable(table), when);
511    }
512
513    public <Q extends QueryWrapper> Joiner<Q> crossJoin(QueryWrapper table) {
514        return joining(SqlConsts.CROSS_JOIN, table, true);
515    }
516
517    public <Q extends QueryWrapper> Joiner<Q> crossJoin(QueryWrapper table, boolean when) {
518        return joining(SqlConsts.CROSS_JOIN, table, when);
519    }
520
521    public <Q extends QueryWrapper> Joiner<Q> join(String table) {
522        return joining(SqlConsts.JOIN, new QueryTable(table), true);
523    }
524
525    public <Q extends QueryWrapper> Joiner<Q> join(String table, boolean when) {
526        return joining(SqlConsts.JOIN, new QueryTable(table), when);
527    }
528
529    public <Q extends QueryWrapper> Joiner<Q> join(Class<?> entityClass) {
530        return joining(SqlConsts.JOIN, entityClass, true);
531    }
532
533    public <Q extends QueryWrapper> Joiner<Q> join(Class<?> entityClass, boolean when) {
534        return joining(SqlConsts.JOIN, entityClass, when);
535    }
536
537    public <Q extends QueryWrapper> Joiner<Q> join(TableDef table) {
538        return joining(SqlConsts.JOIN, new QueryTable(table), true);
539    }
540
541    public <Q extends QueryWrapper> Joiner<Q> join(TableDef table, boolean when) {
542        return joining(SqlConsts.JOIN, new QueryTable(table), when);
543    }
544
545    public <Q extends QueryWrapper> Joiner<Q> join(QueryWrapper table) {
546        return joining(SqlConsts.JOIN, table, true);
547    }
548
549    public <Q extends QueryWrapper> Joiner<Q> join(QueryWrapper table, boolean when) {
550        return joining(SqlConsts.JOIN, table, when);
551    }
552
553    public QueryWrapper union(QueryWrapper unionQuery) {
554        if (unions == null) {
555            unions = new ArrayList<>();
556        }
557        unions.add(UnionWrapper.union(unionQuery));
558        return this;
559    }
560
561    public QueryWrapper unionAll(QueryWrapper unionQuery) {
562        if (unions == null) {
563            unions = new ArrayList<>();
564        }
565        unions.add(UnionWrapper.unionAll(unionQuery));
566        return this;
567    }
568
569    public QueryWrapper forUpdate() {
570        addEndFragment("FOR UPDATE");
571        return this;
572    }
573
574    public QueryWrapper forUpdateNoWait() {
575        addEndFragment("FOR UPDATE NOWAIT");
576        return this;
577    }
578
579    //    public QueryWrapper end(String sqlPart){
580    //        addEndFragment(sqlPart);
581    //        return this;
582    //    }
583
584    @SuppressWarnings("unchecked")
585    protected <T extends QueryWrapper> Joiner<T> joining(String type, QueryTable table, boolean when) {
586        Join join = new Join(type, table, when);
587        addJoinTable(join.getQueryTable());
588        return new Joiner<>((T) addJoin(join), join);
589    }
590
591    protected <T extends QueryWrapper> Joiner<T> joining(String type, Class<?> entityClass, boolean when) {
592        TableInfo tableInfo = TableInfoFactory.ofEntityClass(entityClass);
593        QueryTable queryTable = new QueryTable(tableInfo.getSchema(), tableInfo.getTableName());
594        return joining(type, queryTable, when);
595    }
596
597    @SuppressWarnings("unchecked")
598    protected <T extends QueryWrapper> Joiner<T> joining(String type, QueryWrapper queryWrapper, boolean when) {
599        Join join = new Join(type, queryWrapper, when);
600        addJoinTable(join.getQueryTable());
601        return new Joiner<>((T) addJoin(join), join);
602    }
603
604    public QueryWrapper groupBy(String name) {
605        addGroupByColumns(new QueryColumn(name));
606        return this;
607    }
608
609    public QueryWrapper groupBy(String... names) {
610        for (String name : names) {
611            groupBy(name);
612        }
613        return this;
614    }
615
616    public QueryWrapper groupBy(QueryColumn column) {
617        addGroupByColumns(column);
618        return this;
619    }
620
621    public QueryWrapper groupBy(QueryColumn... columns) {
622        for (QueryColumn column : columns) {
623            groupBy(column);
624        }
625        return this;
626    }
627
628    public <T> QueryWrapper groupBy(LambdaGetter<T> column) {
629        addGroupByColumns(LambdaUtil.getQueryColumn(column));
630        return this;
631    }
632
633    public <T> QueryWrapper groupBy(LambdaGetter<T>... columns) {
634        for (LambdaGetter<T> column : columns) {
635            groupBy(LambdaUtil.getQueryColumn(column));
636        }
637        return this;
638    }
639
640    public QueryWrapper having(QueryCondition queryCondition) {
641        addHavingQueryCondition(queryCondition, SqlConnector.AND);
642        return this;
643    }
644
645    /**
646     * <p>动态排序。
647     *
648     * <p>排序规则:
649     * <ul>
650     *     <li>{@code null} 不排序
651     *     <li>{@code true} 升序
652     *     <li>{@code false} 降序
653     * </ul>
654     *
655     * @param column 列
656     * @param asc    是否升序
657     * @return {@link QueryWrapper}
658     */
659    public QueryWrapper orderBy(QueryColumn column, Boolean asc) {
660        if (asc != null) {
661            if (asc) {
662                addOrderBy(column.asc());
663            } else {
664                addOrderBy(column.desc());
665            }
666        }
667        return this;
668    }
669
670    public QueryWrapper orderBy(QueryOrderBy... orderBys) {
671        for (QueryOrderBy queryOrderBy : orderBys) {
672            addOrderBy(queryOrderBy);
673        }
674        return this;
675    }
676
677    /**
678     * <p>动态排序。
679     *
680     * <p>排序规则:
681     * <ul>
682     *     <li>{@code null} 不排序
683     *     <li>{@code true} 升序
684     *     <li>{@code false} 降序
685     * </ul>
686     *
687     * @param column 列
688     * @param asc    是否升序
689     * @return {@link QueryWrapper}
690     */
691    public <T> QueryWrapper orderBy(LambdaGetter<T> column, Boolean asc) {
692        if (asc != null) {
693            if (asc) {
694                addOrderBy(LambdaUtil.getQueryColumn(column).asc());
695            } else {
696                addOrderBy(LambdaUtil.getQueryColumn(column).desc());
697            }
698        }
699        return this;
700    }
701
702
703    public <T> QueryOrderByBuilder<? extends QueryWrapper> orderBy(LambdaGetter<T> getter) {
704        return new QueryOrderByBuilder<>(this, getter);
705    }
706
707    /**
708     * <p>动态排序。
709     *
710     * <p>排序规则:
711     * <ul>
712     *     <li>{@code null} 不排序
713     *     <li>{@code true} 升序
714     *     <li>{@code false} 降序
715     * </ul>
716     *
717     * @param column 列
718     * @param asc    是否升序
719     * @return {@link QueryWrapper}
720     */
721    public QueryWrapper orderBy(String column, Boolean asc) {
722        if (asc != null) {
723            if (asc) {
724                addOrderBy(new RawQueryColumn(column).asc());
725            } else {
726                addOrderBy(new RawQueryColumn(column).desc());
727            }
728        }
729        return this;
730    }
731
732    public QueryWrapper orderBy(String... orderBys) {
733        if (orderBys == null || orderBys.length == 0) {
734            //ignore
735            return this;
736        }
737        for (String queryOrderBy : orderBys) {
738            if (StringUtil.isNotBlank(queryOrderBy)) {
739                addOrderBy(new StringQueryOrderBy(queryOrderBy));
740            }
741        }
742        return this;
743    }
744
745    public QueryWrapper limit(Number rows) {
746        if (rows != null) {
747            setLimitRows(rows.longValue());
748        } else {
749            setLimitRows(null);
750        }
751        return this;
752    }
753
754    public QueryWrapper offset(Number offset) {
755        if (offset != null) {
756            setLimitOffset(offset.longValue());
757        } else {
758            setLimitOffset(null);
759        }
760        return this;
761    }
762
763    public QueryWrapper limit(Number offset, Number rows) {
764        offset(offset);
765        limit(rows);
766        return this;
767    }
768
769    public QueryWrapper datasource(String datasource) {
770        setDataSource(datasource);
771        return this;
772    }
773
774    public QueryWrapper hint(String hint) {
775        setHint(hint);
776        return this;
777    }
778
779    /**
780     * 获取 queryWrapper 的参数
781     * 在构建 sql 的时候,需要保证 where 在 having 的前面
782     */
783    Object[] getAllValueArray() {
784
785        List<Object> withValues = null;
786        if (with != null) {
787            Object[] paramValues = with.getParamValues();
788            if (ArrayUtil.isNotEmpty(paramValues)) {
789                withValues = new ArrayList<>(Arrays.asList(paramValues));
790
791            }
792        }
793
794        List<Object> columnValues = null;
795        List<QueryColumn> selectColumns = getSelectColumns();
796        if (CollectionUtil.isNotEmpty(selectColumns)) {
797            for (QueryColumn selectColumn : selectColumns) {
798                if (selectColumn instanceof HasParamsColumn) {
799                    Object[] paramValues = ((HasParamsColumn) selectColumn).getParamValues();
800                    if (ArrayUtil.isNotEmpty(paramValues)) {
801                        if (columnValues == null) {
802                            columnValues = new ArrayList<>(paramValues.length);
803                        }
804                        columnValues.addAll(Arrays.asList(paramValues));
805                    }
806                }
807            }
808        }
809
810        //select 子查询的参数:select * from (select ....)
811        List<Object> tableValues = null;
812        List<QueryTable> queryTables = getQueryTables();
813        if (CollectionUtil.isNotEmpty(queryTables)) {
814            for (QueryTable queryTable : queryTables) {
815                Object[] tableValueArray = queryTable.getValueArray();
816                if (tableValueArray.length > 0) {
817                    if (tableValues == null) {
818                        tableValues = new ArrayList<>(tableValueArray.length);
819                    }
820                    tableValues.addAll(Arrays.asList(tableValueArray));
821                }
822            }
823        }
824
825        //join 子查询的参数:left join (select ...)
826        List<Object> joinValues = null;
827        List<Join> joins = getJoins();
828        if (CollectionUtil.isNotEmpty(joins)) {
829            for (Join join : joins) {
830                QueryTable joinTable = join.getQueryTable();
831                Object[] valueArray = joinTable.getValueArray();
832                if (valueArray.length > 0) {
833                    if (joinValues == null) {
834                        joinValues = new ArrayList<>(valueArray.length);
835                    }
836                    joinValues.addAll(Arrays.asList(valueArray));
837                }
838                QueryCondition onCondition = join.getOnCondition();
839                Object[] values = WrapperUtil.getValues(onCondition);
840                if (values.length > 0) {
841                    if (joinValues == null) {
842                        joinValues = new ArrayList<>(values.length);
843                    }
844                    joinValues.addAll(Arrays.asList(values));
845                }
846            }
847        }
848
849        //where 参数
850        Object[] whereValues = WrapperUtil.getValues(whereQueryCondition);
851
852        //having 参数
853        Object[] havingValues = WrapperUtil.getValues(havingQueryCondition);
854
855        Object[] paramValues = ArrayUtil.concat(whereValues, havingValues);
856
857        //unions 参数
858        if (CollectionUtil.isNotEmpty(unions)) {
859            for (UnionWrapper union : unions) {
860                QueryWrapper queryWrapper = union.getQueryWrapper();
861                paramValues = ArrayUtil.concat(paramValues, queryWrapper.getAllValueArray());
862            }
863        }
864
865        Object[] returnValues = withValues == null ? FlexConsts.EMPTY_ARRAY : withValues.toArray();
866        returnValues = columnValues != null ? ArrayUtil.concat(returnValues, columnValues.toArray()) : returnValues;
867        returnValues = tableValues != null ? ArrayUtil.concat(returnValues, tableValues.toArray()) : returnValues;
868        returnValues = joinValues != null ? ArrayUtil.concat(returnValues, joinValues.toArray()) : returnValues;
869        returnValues = ArrayUtil.concat(returnValues, paramValues);
870
871        return returnValues;
872    }
873
874
875    /**
876     * 获取 queryWrapper 的参数
877     * 在构建 sql 的时候,需要保证 where 在 having 的前面
878     */
879    Object[] getJoinValueArray() {
880        //join 子查询的参数:left join (select ...)
881        List<Object> joinValues = null;
882        List<Join> joins = getJoins();
883        if (CollectionUtil.isNotEmpty(joins)) {
884            for (Join join : joins) {
885                QueryTable joinTable = join.getQueryTable();
886                Object[] valueArray = joinTable.getValueArray();
887                if (valueArray.length > 0) {
888                    if (joinValues == null) {
889                        joinValues = new ArrayList<>(valueArray.length);
890                    }
891                    joinValues.addAll(Arrays.asList(valueArray));
892                }
893                QueryCondition onCondition = join.getOnCondition();
894                Object[] values = WrapperUtil.getValues(onCondition);
895                if (values.length > 0) {
896                    if (joinValues == null) {
897                        joinValues = new ArrayList<>(values.length);
898                    }
899                    joinValues.addAll(Arrays.asList(values));
900                }
901            }
902        }
903
904        return joinValues == null ? FlexConsts.EMPTY_ARRAY : joinValues.toArray();
905    }
906
907
908    /**
909     * 获取 queryWrapper 的参数
910     * 在构建 sql 的时候,需要保证 where 在 having 的前面
911     */
912    Object[] getConditionValueArray() {
913        //where 参数
914        Object[] whereValues = WrapperUtil.getValues(whereQueryCondition);
915
916        //having 参数
917        Object[] havingValues = WrapperUtil.getValues(havingQueryCondition);
918
919        Object[] paramValues = ArrayUtil.concat(whereValues, havingValues);
920
921        //unions 参数
922        if (CollectionUtil.isNotEmpty(unions)) {
923            for (UnionWrapper union : unions) {
924                QueryWrapper queryWrapper = union.getQueryWrapper();
925                paramValues = ArrayUtil.concat(paramValues, queryWrapper.getAllValueArray());
926            }
927        }
928
929        return paramValues;
930    }
931
932
933    List<QueryWrapper> getChildSelect() {
934
935        List<QueryWrapper> tableChildQuery = null;
936        List<QueryTable> queryTables = getQueryTables();
937        if (CollectionUtil.isNotEmpty(queryTables)) {
938            for (QueryTable queryTable : queryTables) {
939                if (queryTable instanceof SelectQueryTable) {
940                    if (tableChildQuery == null) {
941                        tableChildQuery = new ArrayList<>();
942                    }
943                    tableChildQuery.add(((SelectQueryTable) queryTable).getQueryWrapper());
944                }
945            }
946        }
947
948        List<QueryWrapper> whereChildQuery = WrapperUtil.getChildQueryWrapper(whereQueryCondition);
949        List<QueryWrapper> havingChildQuery = WrapperUtil.getChildQueryWrapper(havingQueryCondition);
950
951        if (tableChildQuery == null && whereChildQuery.isEmpty() && havingChildQuery.isEmpty()) {
952            return Collections.emptyList();
953        }
954
955        List<QueryWrapper> childQueryWrappers = tableChildQuery == null ? new ArrayList<>()
956            : new ArrayList<>(tableChildQuery);
957        childQueryWrappers.addAll(whereChildQuery);
958        childQueryWrappers.addAll(havingChildQuery);
959
960        return childQueryWrappers;
961    }
962
963    public String toSQL() {
964        String sql = DialectFactory.getDialect().forSelectByQuery(this);
965        return SqlUtil.replaceSqlParams(sql, getAllValueArray());
966    }
967
968    @Override
969    public QueryWrapper clone() {
970        return super.clone();
971    }
972
973}