001/*
002 *  Copyright (c) 2022-2025, 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
018
019import com.mybatisflex.core.constant.SqlConsts;
020import com.mybatisflex.core.constant.SqlOperator;
021import com.mybatisflex.core.dialect.IDialect;
022import com.mybatisflex.core.dialect.OperateType;
023import com.mybatisflex.core.exception.FlexExceptions;
024import com.mybatisflex.core.util.CollectionUtil;
025import com.mybatisflex.core.util.LambdaGetter;
026import com.mybatisflex.core.util.LambdaUtil;
027import com.mybatisflex.core.util.ObjectUtil;
028import com.mybatisflex.core.util.SqlUtil;
029import com.mybatisflex.core.util.StringUtil;
030
031import java.util.Collection;
032import java.util.List;
033import java.util.function.BiPredicate;
034import java.util.function.BooleanSupplier;
035import java.util.function.Predicate;
036
037/**
038 * 查询列,描述的是一张表的字段
039 */
040public class QueryColumn implements CloneSupport<QueryColumn>, Conditional<QueryCondition> {
041
042    protected QueryTable table;
043    protected String name;
044    protected String alias;
045
046    private boolean returnCopyByAsMethod = false;
047
048
049    public QueryColumn() {
050    }
051
052    public QueryColumn(String name) {
053        SqlUtil.keepColumnSafely(name);
054        this.name = StringUtil.tryTrim(name);
055    }
056
057    public QueryColumn(String tableName, String name) {
058        SqlUtil.keepColumnSafely(name);
059        this.table = new QueryTable(tableName);
060        this.name = StringUtil.tryTrim(name);
061    }
062
063    public QueryColumn(String schema, String tableName, String name) {
064        SqlUtil.keepColumnSafely(name);
065        this.table = new QueryTable(schema, tableName);
066        this.name = StringUtil.tryTrim(name);
067    }
068
069    public QueryColumn(String schema, String tableName, String name, String alias) {
070        SqlUtil.keepColumnSafely(name);
071        this.returnCopyByAsMethod = true;
072        this.table = new QueryTable(schema, tableName);
073        this.name = StringUtil.tryTrim(name);
074        this.alias = StringUtil.tryTrim(alias);
075    }
076
077    public QueryColumn(QueryTable queryTable, String name) {
078        SqlUtil.keepColumnSafely(name);
079        this.table = queryTable;
080        this.name = StringUtil.tryTrim(name);
081        this.returnCopyByAsMethod = true;
082    }
083
084    public QueryColumn(QueryTable queryTable, String name, String alias) {
085        SqlUtil.keepColumnSafely(name);
086        this.returnCopyByAsMethod = true;
087        this.table = queryTable;
088        this.name = StringUtil.tryTrim(name);
089        this.alias = StringUtil.tryTrim(alias);
090    }
091
092    public QueryTable getTable() {
093        return table;
094    }
095
096    public void setTable(QueryTable table) {
097        this.table = table;
098    }
099
100    public String getName() {
101        return name;
102    }
103
104    public void setName(String name) {
105        this.name = name;
106    }
107
108    public String getAlias() {
109        return alias;
110    }
111
112    public void setAlias(String alias) {
113        this.alias = alias;
114    }
115
116    public <T> QueryColumn as(LambdaGetter<T> fn) {
117        return as(fn, false);
118    }
119
120    public <T> QueryColumn as(LambdaGetter<T> fn, boolean withPrefix) {
121        return as(LambdaUtil.getAliasName(fn, withPrefix));
122    }
123
124    public QueryColumn as(String alias) {
125        SqlUtil.keepColumnSafely(alias);
126        if (returnCopyByAsMethod) {
127            QueryColumn newColumn = new QueryColumn();
128            newColumn.table = this.table;
129            newColumn.name = this.name;
130            newColumn.alias = alias;
131            return newColumn;
132        } else {
133            this.alias = alias;
134            return this;
135        }
136    }
137
138
139    // query methods ///////
140
141    @Override
142    public QueryCondition eq(Object value) {
143        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
144            return QueryCondition.createEmpty();
145        }
146        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.EQUALS, value));
147    }
148
149    @Override
150    public QueryCondition eq(Object value, boolean isEffective) {
151        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
152            return QueryCondition.createEmpty();
153        }
154        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.EQUALS, value).when(isEffective));
155    }
156
157    @Override
158    public QueryCondition eq(Object value, BooleanSupplier isEffective) {
159        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
160            return QueryCondition.createEmpty();
161        }
162        return QueryColumnBehavior.castCondition(QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.EQUALS, value).when(isEffective)));
163    }
164
165    @Override
166    public <T> QueryCondition eq(T value, Predicate<T> isEffective) {
167        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
168            return QueryCondition.createEmpty();
169        }
170        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.EQUALS, value).when(isEffective.test(value)));
171    }
172
173    @Override
174    public QueryCondition ne(Object value) {
175        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
176            return QueryCondition.createEmpty();
177        }
178        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_EQUALS, value));
179    }
180
181    @Override
182    public QueryCondition ne(Object value, boolean isEffective) {
183        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
184            return QueryCondition.createEmpty();
185        }
186        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_EQUALS, value).when(isEffective));
187    }
188
189    @Override
190    public QueryCondition ne(Object value, BooleanSupplier isEffective) {
191        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
192            return QueryCondition.createEmpty();
193        }
194        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_EQUALS, value).when(isEffective));
195    }
196
197    @Override
198    public <T> QueryCondition ne(T value, Predicate<T> isEffective) {
199        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
200            return QueryCondition.createEmpty();
201        }
202        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_EQUALS, value).when(isEffective.test(value)));
203    }
204
205    @Override
206    public QueryCondition gt(Object value) {
207        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
208            return QueryCondition.createEmpty();
209        }
210        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.GT, value));
211    }
212
213    @Override
214    public QueryCondition gt(Object value, boolean isEffective) {
215        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
216            return QueryCondition.createEmpty();
217        }
218        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.GT, value).when(isEffective));
219    }
220
221    @Override
222    public QueryCondition gt(Object value, BooleanSupplier isEffective) {
223        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
224            return QueryCondition.createEmpty();
225        }
226        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.GT, value).when(isEffective));
227    }
228
229    @Override
230    public <T> QueryCondition gt(T value, Predicate<T> isEffective) {
231        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
232            return QueryCondition.createEmpty();
233        }
234        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.GT, value).when(isEffective.test(value)));
235    }
236
237    @Override
238    public QueryCondition ge(Object value) {
239        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
240            return QueryCondition.createEmpty();
241        }
242        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.GE, value));
243    }
244
245    @Override
246    public QueryCondition ge(Object value, boolean isEffective) {
247        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
248            return QueryCondition.createEmpty();
249        }
250        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.GE, value).when(isEffective));
251    }
252
253    @Override
254    public QueryCondition ge(Object value, BooleanSupplier isEffective) {
255        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
256            return QueryCondition.createEmpty();
257        }
258        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.GE, value).when(isEffective));
259    }
260
261    @Override
262    public <T> QueryCondition ge(T value, Predicate<T> isEffective) {
263        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
264            return QueryCondition.createEmpty();
265        }
266        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.GE, value).when(isEffective.test(value)));
267    }
268
269    @Override
270    public QueryCondition lt(Object value) {
271        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
272            return QueryCondition.createEmpty();
273        }
274        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LT, value));
275    }
276
277    @Override
278    public QueryCondition lt(Object value, boolean isEffective) {
279        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
280            return QueryCondition.createEmpty();
281        }
282        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LT, value).when(isEffective));
283    }
284
285    @Override
286    public QueryCondition lt(Object value, BooleanSupplier isEffective) {
287        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
288            return QueryCondition.createEmpty();
289        }
290        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LT, value).when(isEffective));
291    }
292
293    @Override
294    public <T> QueryCondition lt(T value, Predicate<T> isEffective) {
295        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
296            return QueryCondition.createEmpty();
297        }
298        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LT, value).when(isEffective.test(value)));
299    }
300
301    @Override
302    public QueryCondition le(Object value) {
303        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
304            return QueryCondition.createEmpty();
305        }
306        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LE, value));
307    }
308
309    @Override
310    public QueryCondition le(Object value, boolean isEffective) {
311        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
312            return QueryCondition.createEmpty();
313        }
314        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LE, value).when(isEffective));
315    }
316
317    @Override
318    public QueryCondition le(Object value, BooleanSupplier isEffective) {
319        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
320            return QueryCondition.createEmpty();
321        }
322        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LE, value).when(isEffective));
323    }
324
325    @Override
326    public <T> QueryCondition le(T value, Predicate<T> isEffective) {
327        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
328            return QueryCondition.createEmpty();
329        }
330        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LE, value).when(isEffective.test(value)));
331    }
332
333    @Override
334    public QueryCondition in(Object... value) {
335        if (QueryColumnBehavior.shouldIgnoreValue(value) || value.length == 0) {
336            return QueryCondition.createEmpty();
337        }
338        // IN 里面只有一个值的情况
339        if (value.length == 1) {
340            if (QueryColumnBehavior.shouldIgnoreValue(value[0])) {
341                return QueryCondition.createEmpty();
342            }
343            if (QueryColumnBehavior.isSmartConvertInToEquals()) {
344                return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.EQUALS, value[0]));
345            }
346        }
347        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlConsts.IN, value));
348    }
349
350    @Override
351    public QueryCondition in(Object[] value, boolean isEffective) {
352        if (QueryColumnBehavior.shouldIgnoreValue(value) || value.length == 0) {
353            return QueryCondition.createEmpty();
354        }
355        // IN 里面只有一个值的情况
356        if (value.length == 1) {
357            if (QueryColumnBehavior.shouldIgnoreValue(value[0])) {
358                return QueryCondition.createEmpty();
359            }
360            if (QueryColumnBehavior.isSmartConvertInToEquals()) {
361                return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.EQUALS, value[0]).when(isEffective));
362            }
363        }
364        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlConsts.IN, value).when(isEffective));
365    }
366
367    @Override
368    public QueryCondition in(Object[] value, BooleanSupplier isEffective) {
369        if (QueryColumnBehavior.shouldIgnoreValue(value) || value.length == 0) {
370            return QueryCondition.createEmpty();
371        }
372        // IN 里面只有一个值的情况
373        if (value.length == 1) {
374            if (QueryColumnBehavior.shouldIgnoreValue(value[0])) {
375                return QueryCondition.createEmpty();
376            }
377            if (QueryColumnBehavior.isSmartConvertInToEquals()) {
378                return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.EQUALS, value[0]).when(isEffective));
379            }
380        }
381        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlConsts.IN, value).when(isEffective));
382    }
383
384    @Override
385    public <T> QueryCondition in(T[] value, Predicate<T[]> isEffective) {
386        if (QueryColumnBehavior.shouldIgnoreValue(value) || value.length == 0) {
387            return QueryCondition.createEmpty();
388        }
389        // IN 里面只有一个值的情况
390        if (value.length == 1) {
391            if (QueryColumnBehavior.shouldIgnoreValue(value[0])) {
392                return QueryCondition.createEmpty();
393            }
394            if (QueryColumnBehavior.isSmartConvertInToEquals()) {
395                return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.EQUALS, value[0]).when(isEffective.test(value)));
396            }
397        }
398        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlConsts.IN, value).when(isEffective.test(value)));
399    }
400
401    @Override
402    public QueryCondition in(Collection<?> value) {
403        if (value == null || value.isEmpty()) {
404            return QueryCondition.createEmpty();
405        }
406        return in(value.toArray());
407    }
408
409    @Override
410    public QueryCondition in(Collection<?> value, boolean isEffective) {
411        if (value == null || value.isEmpty()) {
412            return QueryCondition.createEmpty();
413        }
414        return in(value.toArray()).when(isEffective);
415    }
416
417    @Override
418    public QueryCondition in(Collection<?> value, BooleanSupplier isEffective) {
419        if (value == null || value.isEmpty()) {
420            return QueryCondition.createEmpty();
421        }
422        return in(value.toArray()).when(isEffective);
423    }
424
425    @Override
426    public <T extends Collection<?>> QueryCondition in(T value, Predicate<T> isEffective) {
427        if (value == null || value.isEmpty()) {
428            return QueryCondition.createEmpty();
429        }
430        return in(value.toArray()).when(isEffective.test(value));
431    }
432
433    @Override
434    public QueryCondition in(QueryWrapper queryWrapper) {
435        if (queryWrapper == null) {
436            return QueryCondition.createEmpty();
437        }
438        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.IN, queryWrapper));
439    }
440
441    @Override
442    public QueryCondition in(QueryWrapper queryWrapper, boolean isEffective) {
443        if (queryWrapper == null) {
444            return QueryCondition.createEmpty();
445        }
446        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.IN, queryWrapper).when(isEffective));
447    }
448
449    @Override
450    public QueryCondition in(QueryWrapper queryWrapper, BooleanSupplier isEffective) {
451        if (queryWrapper == null) {
452            return QueryCondition.createEmpty();
453        }
454        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.IN, queryWrapper).when(isEffective));
455    }
456
457    @Override
458    public QueryCondition notIn(Object... value) {
459        if (QueryColumnBehavior.shouldIgnoreValue(value) || value.length == 0) {
460            return QueryCondition.createEmpty();
461        }
462        // NOT IN 里面只有一个值的情况
463        if (value.length == 1) {
464            if (QueryColumnBehavior.shouldIgnoreValue(value[0])) {
465                return QueryCondition.createEmpty();
466            }
467            if (QueryColumnBehavior.isSmartConvertInToEquals()) {
468                return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_EQUALS, value[0]));
469            }
470        }
471        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlConsts.NOT_IN, value));
472    }
473
474    @Override
475    public QueryCondition notIn(Object[] value, boolean isEffective) {
476        if (QueryColumnBehavior.shouldIgnoreValue(value) || value.length == 0) {
477            return QueryCondition.createEmpty();
478        }
479        // NOT IN 里面只有一个值的情况
480        if (value.length == 1) {
481            if (QueryColumnBehavior.shouldIgnoreValue(value[0])) {
482                return QueryCondition.createEmpty();
483            }
484            if (QueryColumnBehavior.isSmartConvertInToEquals()) {
485                return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_EQUALS, value[0]).when(isEffective));
486            }
487        }
488        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlConsts.NOT_IN, value).when(isEffective));
489    }
490
491    @Override
492    public QueryCondition notIn(Object[] value, BooleanSupplier isEffective) {
493        if (QueryColumnBehavior.shouldIgnoreValue(value) || value.length == 0) {
494            return QueryCondition.createEmpty();
495        }
496        // NOT IN 里面只有一个值的情况
497        if (value.length == 1) {
498            if (QueryColumnBehavior.shouldIgnoreValue(value[0])) {
499                return QueryCondition.createEmpty();
500            }
501            if (QueryColumnBehavior.isSmartConvertInToEquals()) {
502                return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_EQUALS, value[0]).when(isEffective));
503            }
504        }
505        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlConsts.NOT_IN, value).when(isEffective));
506    }
507
508    @Override
509    public <T> QueryCondition notIn(T[] value, Predicate<T[]> isEffective) {
510        if (QueryColumnBehavior.shouldIgnoreValue(value) || value.length == 0) {
511            return QueryCondition.createEmpty();
512        }
513        // NOT IN 里面只有一个值的情况
514        if (value.length == 1) {
515            if (QueryColumnBehavior.shouldIgnoreValue(value[0])) {
516                return QueryCondition.createEmpty();
517            }
518            if (QueryColumnBehavior.isSmartConvertInToEquals()) {
519                return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_EQUALS, value[0]).when(isEffective.test(value)));
520            }
521        }
522        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlConsts.NOT_IN, value).when(isEffective.test(value)));
523    }
524
525    @Override
526    public QueryCondition notIn(Collection<?> value) {
527        if (value == null || value.isEmpty()) {
528            return QueryCondition.createEmpty();
529        }
530        return notIn(value.toArray());
531    }
532
533    @Override
534    public QueryCondition notIn(Collection<?> value, boolean isEffective) {
535        if (value == null || value.isEmpty()) {
536            return QueryCondition.createEmpty();
537        }
538        return notIn(value.toArray()).when(isEffective);
539    }
540
541    @Override
542    public QueryCondition notIn(Collection<?> value, BooleanSupplier isEffective) {
543        if (value == null || value.isEmpty()) {
544            return QueryCondition.createEmpty();
545        }
546        return notIn(value.toArray()).when(isEffective);
547    }
548
549    @Override
550    public <T extends Collection<?>> QueryCondition notIn(T value, Predicate<T> isEffective) {
551        if (value == null || value.isEmpty()) {
552            return QueryCondition.createEmpty();
553        }
554        return notIn(value.toArray()).when(isEffective.test(value));
555    }
556
557    @Override
558    public QueryCondition notIn(QueryWrapper queryWrapper) {
559        if (queryWrapper == null) {
560            return QueryCondition.createEmpty();
561        }
562        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_IN, queryWrapper));
563    }
564
565    @Override
566    public QueryCondition notIn(QueryWrapper queryWrapper, boolean isEffective) {
567        if (queryWrapper == null) {
568            return QueryCondition.createEmpty();
569        }
570        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_IN, queryWrapper).when(isEffective));
571    }
572
573    @Override
574    public QueryCondition notIn(QueryWrapper queryWrapper, BooleanSupplier isEffective) {
575        if (queryWrapper == null) {
576            return QueryCondition.createEmpty();
577        }
578        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_IN, queryWrapper).when(isEffective));
579    }
580
581    @Override
582    public QueryCondition between(Object[] values) {
583        if (QueryColumnBehavior.shouldIgnoreValue(values) || values.length < 2) {
584            return QueryCondition.createEmpty();
585        }
586
587       return between(values[0], values[values.length - 1]);
588    }
589
590    @Override
591    public QueryCondition between(Object[] values, boolean isEffective) {
592        if (QueryColumnBehavior.shouldIgnoreValue(values) || values.length < 2) {
593            return QueryCondition.createEmpty();
594        }
595
596        return between(values[0], values[values.length - 1], isEffective);
597    }
598
599    @Override
600    public QueryCondition between(Object start, Object end) {
601        if (QueryColumnBehavior.shouldIgnoreValue(start) || QueryColumnBehavior.shouldIgnoreValue(end)) {
602            return QueryCondition.createEmpty();
603        }
604        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.BETWEEN, new Object[]{start, end}));
605    }
606
607    @Override
608    public QueryCondition between(Object start, Object end, boolean isEffective) {
609        if (QueryColumnBehavior.shouldIgnoreValue(start) || QueryColumnBehavior.shouldIgnoreValue(end)) {
610            return QueryCondition.createEmpty();
611        }
612        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.BETWEEN, new Object[]{start, end}).when(isEffective));
613    }
614
615    @Override
616    public QueryCondition between(Object start, Object end, BooleanSupplier isEffective) {
617        if (QueryColumnBehavior.shouldIgnoreValue(start) || QueryColumnBehavior.shouldIgnoreValue(end)) {
618            return QueryCondition.createEmpty();
619        }
620        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.BETWEEN, new Object[]{start, end}).when(isEffective));
621    }
622
623    @Override
624    public <S, E> QueryCondition between(S start, E end, BiPredicate<S, E> isEffective) {
625        if (QueryColumnBehavior.shouldIgnoreValue(start) || QueryColumnBehavior.shouldIgnoreValue(end)) {
626            return QueryCondition.createEmpty();
627        }
628        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.BETWEEN, new Object[]{start, end}).when(isEffective.test(start, end)));
629    }
630
631    @Override
632    public QueryCondition notBetween(Object[] values) {
633        if (QueryColumnBehavior.shouldIgnoreValue(values) || values.length < 2) {
634            return QueryCondition.createEmpty();
635        }
636
637        return notBetween(values[0], values[values.length - 1]);
638    }
639
640    @Override
641    public QueryCondition notBetween(Object[] values, boolean isEffective) {
642        if (QueryColumnBehavior.shouldIgnoreValue(values) || values.length < 2) {
643            return QueryCondition.createEmpty();
644        }
645
646        return notBetween(values[0], values[values.length - 1], isEffective);
647    }
648
649    @Override
650    public QueryCondition notBetween(Object start, Object end) {
651        if (QueryColumnBehavior.shouldIgnoreValue(start) || QueryColumnBehavior.shouldIgnoreValue(end)) {
652            return QueryCondition.createEmpty();
653        }
654        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_BETWEEN, new Object[]{start, end}));
655    }
656
657    @Override
658    public QueryCondition notBetween(Object start, Object end, boolean isEffective) {
659        if (QueryColumnBehavior.shouldIgnoreValue(start) || QueryColumnBehavior.shouldIgnoreValue(end)) {
660            return QueryCondition.createEmpty();
661        }
662        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_BETWEEN, new Object[]{start, end}).when(isEffective));
663    }
664
665    @Override
666    public QueryCondition notBetween(Object start, Object end, BooleanSupplier isEffective) {
667        if (QueryColumnBehavior.shouldIgnoreValue(start) || QueryColumnBehavior.shouldIgnoreValue(end)) {
668            return QueryCondition.createEmpty();
669        }
670        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_BETWEEN, new Object[]{start, end}).when(isEffective));
671    }
672
673    @Override
674    public <S, E> QueryCondition notBetween(S start, E end, BiPredicate<S, E> isEffective) {
675        if (QueryColumnBehavior.shouldIgnoreValue(start) || QueryColumnBehavior.shouldIgnoreValue(end)) {
676            return QueryCondition.createEmpty();
677        }
678        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_BETWEEN, new Object[]{start, end}).when(isEffective.test(start, end)));
679    }
680
681    @Override
682    public QueryCondition like(Object value) {
683        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
684            return QueryCondition.createEmpty();
685        }
686        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, "%" + value + "%"));
687    }
688
689    @Override
690    public QueryCondition like(Object value, boolean isEffective) {
691        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
692            return QueryCondition.createEmpty();
693        }
694        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, "%" + value + "%").when(isEffective));
695    }
696
697    @Override
698    public QueryCondition like(Object value, BooleanSupplier isEffective) {
699        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
700            return QueryCondition.createEmpty();
701        }
702        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, "%" + value + "%").when(isEffective));
703    }
704
705    @Override
706    public <T> QueryCondition like(T value, Predicate<T> isEffective) {
707        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
708            return QueryCondition.createEmpty();
709        }
710        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, "%" + value + "%").when(isEffective.test(value)));
711    }
712
713    @Override
714    public QueryCondition likeLeft(Object value) {
715        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
716            return QueryCondition.createEmpty();
717        }
718        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, value + "%"));
719    }
720
721    @Override
722    public QueryCondition likeLeft(Object value, boolean isEffective) {
723        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
724            return QueryCondition.createEmpty();
725        }
726        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, value + "%").when(isEffective));
727    }
728
729    @Override
730    public QueryCondition likeLeft(Object value, BooleanSupplier isEffective) {
731        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
732            return QueryCondition.createEmpty();
733        }
734        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, value + "%").when(isEffective));
735    }
736
737    @Override
738    public <T> QueryCondition likeLeft(T value, Predicate<T> isEffective) {
739        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
740            return QueryCondition.createEmpty();
741        }
742        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, value + "%").when(isEffective.test(value)));
743    }
744
745    @Override
746    public QueryCondition likeRight(Object value) {
747        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
748            return QueryCondition.createEmpty();
749        }
750        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, "%" + value));
751    }
752
753    @Override
754    public QueryCondition likeRight(Object value, boolean isEffective) {
755        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
756            return QueryCondition.createEmpty();
757        }
758        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, "%" + value).when(isEffective));
759    }
760
761    @Override
762    public QueryCondition likeRight(Object value, BooleanSupplier isEffective) {
763        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
764            return QueryCondition.createEmpty();
765        }
766        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, "%" + value).when(isEffective));
767    }
768
769    @Override
770    public <T> QueryCondition likeRight(T value, Predicate<T> isEffective) {
771        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
772            return QueryCondition.createEmpty();
773        }
774        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, "%" + value).when(isEffective.test(value)));
775    }
776
777    /**
778     * {@code LIKE value}
779     */
780    public QueryCondition likeRaw(Object value) {
781        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
782            return QueryCondition.createEmpty();
783        }
784        return likeRaw(value, true);
785    }
786
787    /**
788     * {@code LIKE value}
789     */
790    public QueryCondition likeRaw(Object value, boolean isEffective) {
791        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
792            return QueryCondition.createEmpty();
793        }
794        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, value).when(isEffective));
795    }
796
797    /**
798     * {@code LIKE value}
799     */
800    public QueryCondition likeRaw(Object value, BooleanSupplier isEffective) {
801        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
802            return QueryCondition.createEmpty();
803        }
804        return likeRaw(value, isEffective.getAsBoolean());
805    }
806
807    /**
808     * {@code LIKE value}
809     */
810    public <T> QueryCondition likeRaw(T value, Predicate<T> isEffective) {
811        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
812            return QueryCondition.createEmpty();
813        }
814        return likeRaw(value, isEffective.test(value));
815    }
816
817    @Override
818    public QueryCondition notLike(Object value) {
819        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
820            return QueryCondition.createEmpty();
821        }
822        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, "%" + value + "%"));
823    }
824
825    @Override
826    public QueryCondition notLike(Object value, boolean isEffective) {
827        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
828            return QueryCondition.createEmpty();
829        }
830        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, "%" + value + "%").when(isEffective));
831    }
832
833    @Override
834    public QueryCondition notLike(Object value, BooleanSupplier isEffective) {
835        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
836            return QueryCondition.createEmpty();
837        }
838        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, "%" + value + "%").when(isEffective));
839    }
840
841    @Override
842    public <T> QueryCondition notLike(T value, Predicate<T> isEffective) {
843        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
844            return QueryCondition.createEmpty();
845        }
846        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, "%" + value + "%").when(isEffective.test(value)));
847    }
848
849    @Override
850    public QueryCondition notLikeLeft(Object value) {
851        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
852            return QueryCondition.createEmpty();
853        }
854        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, value + "%"));
855    }
856
857    @Override
858    public QueryCondition notLikeLeft(Object value, boolean isEffective) {
859        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
860            return QueryCondition.createEmpty();
861        }
862        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, value + "%").when(isEffective));
863    }
864
865    @Override
866    public QueryCondition notLikeLeft(Object value, BooleanSupplier isEffective) {
867        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
868            return QueryCondition.createEmpty();
869        }
870        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, value + "%").when(isEffective));
871    }
872
873    @Override
874    public <T> QueryCondition notLikeLeft(T value, Predicate<T> isEffective) {
875        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
876            return QueryCondition.createEmpty();
877        }
878        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, value + "%").when(isEffective.test(value)));
879    }
880
881    @Override
882    public QueryCondition notLikeRight(Object value) {
883        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
884            return QueryCondition.createEmpty();
885        }
886        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, "%" + value));
887    }
888
889    @Override
890    public QueryCondition notLikeRight(Object value, boolean isEffective) {
891        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
892            return QueryCondition.createEmpty();
893        }
894        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, "%" + value).when(isEffective));
895    }
896
897    @Override
898    public QueryCondition notLikeRight(Object value, BooleanSupplier isEffective) {
899        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
900            return QueryCondition.createEmpty();
901        }
902        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, "%" + value).when(isEffective));
903    }
904
905    @Override
906    public <T> QueryCondition notLikeRight(T value, Predicate<T> isEffective) {
907        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
908            return QueryCondition.createEmpty();
909        }
910        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, "%" + value).when(isEffective.test(value)));
911    }
912
913    /**
914     * {@code NOT LIKE value}
915     */
916    public QueryCondition notLikeRaw(Object value) {
917        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
918            return QueryCondition.createEmpty();
919        }
920        return likeRaw(value, true);
921    }
922
923    /**
924     * {@code NOT LIKE value}
925     */
926    public QueryCondition notLikeRaw(Object value, boolean isEffective) {
927        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
928            return QueryCondition.createEmpty();
929        }
930        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, value).when(isEffective));
931    }
932
933    /**
934     * {@code NOT LIKE value}
935     */
936    public QueryCondition notLikeRaw(Object value, BooleanSupplier isEffective) {
937        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
938            return QueryCondition.createEmpty();
939        }
940        return likeRaw(value, isEffective.getAsBoolean());
941    }
942
943    /**
944     * {@code NOT LIKE value}
945     */
946    public <T> QueryCondition notLikeRaw(T value, Predicate<T> isEffective) {
947        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
948            return QueryCondition.createEmpty();
949        }
950        return likeRaw(value, isEffective.test(value));
951    }
952
953    @Override
954    public QueryCondition isNull(boolean isEffective) {
955        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.IS_NULL, null).when(isEffective));
956    }
957
958    @Override
959    public QueryCondition isNotNull(boolean isEffective) {
960        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.IS_NOT_NULL, null).when(isEffective));
961    }
962
963
964    ////order by ////
965    public QueryOrderBy asc() {
966        return new QueryOrderBy(this, SqlConsts.ASC);
967    }
968
969
970    public QueryOrderBy desc() {
971        return new QueryOrderBy(this, SqlConsts.DESC);
972    }
973
974
975    // 运算 加减乘除 + - * /
976    public QueryColumn add(QueryColumn queryColumn) {
977        return new ArithmeticQueryColumn(this).add(queryColumn);
978    }
979
980    public QueryColumn add(Number number) {
981        return new ArithmeticQueryColumn(this).add(number);
982    }
983
984    public QueryColumn subtract(QueryColumn queryColumn) {
985        return new ArithmeticQueryColumn(this).subtract(queryColumn);
986    }
987
988    public QueryColumn subtract(Number number) {
989        return new ArithmeticQueryColumn(this).subtract(number);
990    }
991
992    public QueryColumn multiply(QueryColumn queryColumn) {
993        return new ArithmeticQueryColumn(this).multiply(queryColumn);
994    }
995
996    public QueryColumn multiply(Number number) {
997        return new ArithmeticQueryColumn(this).multiply(number);
998    }
999
1000    public QueryColumn divide(QueryColumn queryColumn) {
1001        return new ArithmeticQueryColumn(this).divide(queryColumn);
1002    }
1003
1004    public QueryColumn divide(Number number) {
1005        return new ArithmeticQueryColumn(this).divide(number);
1006    }
1007
1008
1009    String toConditionSql(List<QueryTable> queryTables, IDialect dialect) {
1010        QueryTable selectTable = getSelectTable(queryTables, table);
1011        if (selectTable == null) {
1012            return dialect.wrap(name);
1013        } else {
1014            if (StringUtil.isNotBlank(selectTable.alias)) {
1015                return dialect.wrap(selectTable.alias) + SqlConsts.REFERENCE + dialect.wrap(name);
1016            } else if (StringUtil.isNotBlank(selectTable.getSchema()) && StringUtil.isNotBlank(selectTable.getName())) {
1017                String realTable = dialect.getRealTable(selectTable.getName(), OperateType.SELECT);
1018                return dialect.wrap(dialect.getRealSchema(selectTable.schema, realTable, OperateType.SELECT)) + SqlConsts.REFERENCE + dialect.wrap(realTable)
1019                    + SqlConsts.REFERENCE + dialect.wrap(name);
1020            } else if (StringUtil.isNotBlank(selectTable.getName())) {
1021                return dialect.wrap(dialect.getRealTable(selectTable.getName(), OperateType.SELECT)) + SqlConsts.REFERENCE + dialect.wrap(name);
1022            } else {
1023                return dialect.wrap(name);
1024            }
1025        }
1026    }
1027
1028
1029    String toSelectSql(List<QueryTable> queryTables, IDialect dialect) {
1030        return toConditionSql(queryTables, dialect) + WrapperUtil.buildColumnAlias(alias, dialect);
1031    }
1032
1033
1034    QueryTable getSelectTable(List<QueryTable> queryTables, QueryTable selfTable) {
1035        // 未查询任何表
1036        if (queryTables == null || queryTables.isEmpty()) {
1037            return null;
1038        }
1039
1040        if (selfTable != null && StringUtil.isNotBlank(selfTable.alias)) {
1041            return selfTable;
1042        }
1043
1044        if (queryTables.size() == 1 && queryTables.get(0).isSameTable(selfTable)) {
1045            // ignore table
1046            return null;
1047        }
1048
1049        if (CollectionUtil.isEmpty(queryTables)) {
1050            return selfTable;
1051        }
1052
1053        if (selfTable == null && queryTables.size() == 1) {
1054            return queryTables.get(0);
1055        }
1056
1057        for (QueryTable table : queryTables) {
1058            if (table.isSameTable(selfTable)) {
1059                return table;
1060            }
1061        }
1062        return selfTable;
1063    }
1064
1065
1066    @Override
1067    public String toString() {
1068        return "QueryColumn{" +
1069            "table=" + table +
1070            ", name='" + name + '\'' +
1071            ", alias='" + alias + '\'' +
1072            '}';
1073    }
1074
1075
1076    @Override
1077    public QueryColumn clone() {
1078        try {
1079            QueryColumn clone = (QueryColumn) super.clone();
1080            // deep clone ...
1081            clone.table = ObjectUtil.clone(this.table);
1082            return clone;
1083        } catch (CloneNotSupportedException e) {
1084            throw FlexExceptions.wrap(e);
1085        }
1086    }
1087
1088}