001/*
002 *  Copyright (c) 2022-2024, 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.LambdaGetter;
025import com.mybatisflex.core.util.LambdaUtil;
026import com.mybatisflex.core.util.ObjectUtil;
027import com.mybatisflex.core.util.SqlUtil;
028import com.mybatisflex.core.util.StringUtil;
029
030import java.util.Collection;
031import java.util.List;
032import java.util.ListIterator;
033import java.util.Objects;
034import java.util.function.BiPredicate;
035import java.util.function.BooleanSupplier;
036import java.util.function.Predicate;
037
038/**
039 * 查询列,描述的是一张表的字段
040 */
041public class QueryColumn implements CloneSupport<QueryColumn>, Conditional<QueryCondition> {
042
043    protected QueryTable table;
044    protected String name;
045    protected String alias;
046
047    private boolean returnCopyByAsMethod = false;
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        return in(value, true);
336    }
337
338    @Override
339    public QueryCondition in(Object[] value, boolean isEffective) {
340        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
341            return QueryCondition.createEmpty();
342        }
343        // IN 里面只有一个值的情况
344        if (value.length == 1) {
345            if (QueryColumnBehavior.shouldIgnoreValue(value[0])) {
346                return QueryCondition.createEmpty();
347            }
348            if (QueryColumnBehavior.isSmartConvertInToEquals()) {
349                return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.EQUALS, value[0]).when(isEffective));
350            }
351        }
352        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlConsts.IN, value).when(isEffective));
353    }
354
355    @Override
356    public QueryCondition in(Object[] value, BooleanSupplier isEffective) {
357        return in(value, isEffective.getAsBoolean());
358    }
359
360    @Override
361    public <T> QueryCondition in(T[] value, Predicate<T[]> isEffective) {
362        return in(value, isEffective.test(value));
363    }
364
365    @Override
366    public QueryCondition in(Collection<?> value) {
367        return in(value, true);
368    }
369
370    @Override
371    public QueryCondition in(Collection<?> value, boolean isEffective) {
372        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
373            return QueryCondition.createEmpty();
374        }
375        // IN 里面只有一个值的情况
376        if (value.size() == 1) {
377            Object next = value.iterator().next();
378            if (QueryColumnBehavior.shouldIgnoreValue(next)) {
379                return QueryCondition.createEmpty();
380            }
381            if (QueryColumnBehavior.isSmartConvertInToEquals()) {
382                return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.EQUALS, next).when(isEffective));
383            }
384        }
385        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlConsts.IN, value).when(isEffective));
386    }
387
388    @Override
389    public QueryCondition in(Collection<?> value, BooleanSupplier isEffective) {
390        return in(value, isEffective.getAsBoolean());
391    }
392
393    @Override
394    public <T extends Collection<?>> QueryCondition in(T value, Predicate<T> isEffective) {
395        return in(value, isEffective.test(value));
396    }
397
398    @Override
399    public QueryCondition in(QueryWrapper queryWrapper) {
400        if (queryWrapper == null) {
401            return QueryCondition.createEmpty();
402        }
403        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlConsts.IN, queryWrapper));
404    }
405
406    @Override
407    public QueryCondition in(QueryWrapper queryWrapper, boolean isEffective) {
408        if (queryWrapper == null) {
409            return QueryCondition.createEmpty();
410        }
411        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlConsts.IN, queryWrapper).when(isEffective));
412    }
413
414    @Override
415    public QueryCondition in(QueryWrapper queryWrapper, BooleanSupplier isEffective) {
416        if (queryWrapper == null) {
417            return QueryCondition.createEmpty();
418        }
419        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlConsts.IN, queryWrapper).when(isEffective));
420    }
421
422    @Override
423    public QueryCondition notIn(Object... value) {
424        return notIn(value, true);
425    }
426
427    @Override
428    public QueryCondition notIn(Object[] value, boolean isEffective) {
429        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
430            return QueryCondition.createEmpty();
431        }
432        // NOT IN 里面只有一个值的情况
433        if (value.length == 1) {
434            if (QueryColumnBehavior.shouldIgnoreValue(value[0])) {
435                return QueryCondition.createEmpty();
436            }
437            if (QueryColumnBehavior.isSmartConvertInToEquals()) {
438                return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_EQUALS, value[0]).when(isEffective));
439            }
440        }
441        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlConsts.NOT_IN, value).when(isEffective));
442    }
443
444    @Override
445    public QueryCondition notIn(Object[] value, BooleanSupplier isEffective) {
446        return notIn(value, isEffective.getAsBoolean());
447    }
448
449    @Override
450    public <T> QueryCondition notIn(T[] value, Predicate<T[]> isEffective) {
451        return notIn(value, isEffective.test(value));
452    }
453
454    @Override
455    public QueryCondition notIn(Collection<?> value) {
456        return notIn(value, true);
457    }
458
459    @Override
460    public QueryCondition notIn(Collection<?> value, boolean isEffective) {
461        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
462            return QueryCondition.createEmpty();
463        }
464        // NOT IN 里面只有一个值的情况
465        if (value.size() == 1) {
466            Object next = value.iterator().next();
467            if (QueryColumnBehavior.shouldIgnoreValue(next)) {
468                return QueryCondition.createEmpty();
469            }
470            if (QueryColumnBehavior.isSmartConvertInToEquals()) {
471                return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_EQUALS, next).when(isEffective));
472            }
473        }
474        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlConsts.NOT_IN, value).when(isEffective));
475    }
476
477    @Override
478    public QueryCondition notIn(Collection<?> value, BooleanSupplier isEffective) {
479        return notIn(value, isEffective.getAsBoolean());
480    }
481
482    @Override
483    public <T extends Collection<?>> QueryCondition notIn(T value, Predicate<T> isEffective) {
484        return notIn(value, isEffective.test(value));
485    }
486
487    @Override
488    public QueryCondition notIn(QueryWrapper queryWrapper) {
489        if (queryWrapper == null) {
490            return QueryCondition.createEmpty();
491        }
492        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlConsts.NOT_IN, queryWrapper));
493    }
494
495    @Override
496    public QueryCondition notIn(QueryWrapper queryWrapper, boolean isEffective) {
497        if (queryWrapper == null) {
498            return QueryCondition.createEmpty();
499        }
500        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlConsts.NOT_IN, queryWrapper).when(isEffective));
501    }
502
503    @Override
504    public QueryCondition notIn(QueryWrapper queryWrapper, BooleanSupplier isEffective) {
505        if (queryWrapper == null) {
506            return QueryCondition.createEmpty();
507        }
508        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlConsts.NOT_IN, queryWrapper).when(isEffective));
509    }
510
511    @Override
512    public QueryCondition between(Object[] values) {
513        if (QueryColumnBehavior.shouldIgnoreValue(values) || values.length < 2) {
514            return QueryCondition.createEmpty();
515        }
516
517        return between(values[0], values[values.length - 1]);
518    }
519
520    @Override
521    public QueryCondition between(Object[] values, boolean isEffective) {
522        if (QueryColumnBehavior.shouldIgnoreValue(values) || values.length < 2) {
523            return QueryCondition.createEmpty();
524        }
525
526        return between(values[0], values[values.length - 1], isEffective);
527    }
528
529    @Override
530    public QueryCondition between(Object start, Object end) {
531        if (QueryColumnBehavior.shouldIgnoreValue(start) || QueryColumnBehavior.shouldIgnoreValue(end)) {
532            return QueryCondition.createEmpty();
533        }
534        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlConsts.BETWEEN, new Object[]{start, end}));
535    }
536
537    @Override
538    public QueryCondition between(Object start, Object end, boolean isEffective) {
539        if (QueryColumnBehavior.shouldIgnoreValue(start) || QueryColumnBehavior.shouldIgnoreValue(end)) {
540            return QueryCondition.createEmpty();
541        }
542        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlConsts.BETWEEN, new Object[]{start, end}).when(isEffective));
543    }
544
545    @Override
546    public QueryCondition between(Object start, Object end, BooleanSupplier isEffective) {
547        if (QueryColumnBehavior.shouldIgnoreValue(start) || QueryColumnBehavior.shouldIgnoreValue(end)) {
548            return QueryCondition.createEmpty();
549        }
550        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlConsts.BETWEEN, new Object[]{start, end}).when(isEffective));
551    }
552
553    @Override
554    public <S, E> QueryCondition between(S start, E end, BiPredicate<S, E> isEffective) {
555        if (QueryColumnBehavior.shouldIgnoreValue(start) || QueryColumnBehavior.shouldIgnoreValue(end)) {
556            return QueryCondition.createEmpty();
557        }
558        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlConsts.BETWEEN, new Object[]{start, end}).when(isEffective.test(start, end)));
559    }
560
561    @Override
562    public QueryCondition notBetween(Object[] values) {
563        if (QueryColumnBehavior.shouldIgnoreValue(values) || values.length < 2) {
564            return QueryCondition.createEmpty();
565        }
566
567        return notBetween(values[0], values[values.length - 1]);
568    }
569
570    @Override
571    public QueryCondition notBetween(Object[] values, boolean isEffective) {
572        if (QueryColumnBehavior.shouldIgnoreValue(values) || values.length < 2) {
573            return QueryCondition.createEmpty();
574        }
575
576        return notBetween(values[0], values[values.length - 1], isEffective);
577    }
578
579    @Override
580    public QueryCondition notBetween(Object start, Object end) {
581        if (QueryColumnBehavior.shouldIgnoreValue(start) || QueryColumnBehavior.shouldIgnoreValue(end)) {
582            return QueryCondition.createEmpty();
583        }
584        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlConsts.NOT_BETWEEN, new Object[]{start, end}));
585    }
586
587    @Override
588    public QueryCondition notBetween(Object start, Object end, boolean isEffective) {
589        if (QueryColumnBehavior.shouldIgnoreValue(start) || QueryColumnBehavior.shouldIgnoreValue(end)) {
590            return QueryCondition.createEmpty();
591        }
592        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlConsts.NOT_BETWEEN, new Object[]{start, end}).when(isEffective));
593    }
594
595    @Override
596    public QueryCondition notBetween(Object start, Object end, BooleanSupplier isEffective) {
597        if (QueryColumnBehavior.shouldIgnoreValue(start) || QueryColumnBehavior.shouldIgnoreValue(end)) {
598            return QueryCondition.createEmpty();
599        }
600        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlConsts.NOT_BETWEEN, new Object[]{start, end}).when(isEffective));
601    }
602
603    @Override
604    public <S, E> QueryCondition notBetween(S start, E end, BiPredicate<S, E> isEffective) {
605        if (QueryColumnBehavior.shouldIgnoreValue(start) || QueryColumnBehavior.shouldIgnoreValue(end)) {
606            return QueryCondition.createEmpty();
607        }
608        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlConsts.NOT_BETWEEN, new Object[]{start, end}).when(isEffective.test(start, end)));
609    }
610
611    @Override
612    public QueryCondition like(Object value) {
613        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
614            return QueryCondition.createEmpty();
615        }
616        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, "%" + value + "%"));
617    }
618
619    @Override
620    public QueryCondition like(Object value, boolean isEffective) {
621        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
622            return QueryCondition.createEmpty();
623        }
624        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, "%" + value + "%").when(isEffective));
625    }
626
627    @Override
628    public QueryCondition like(Object value, BooleanSupplier isEffective) {
629        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
630            return QueryCondition.createEmpty();
631        }
632        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, "%" + value + "%").when(isEffective));
633    }
634
635    @Override
636    public <T> QueryCondition like(T value, Predicate<T> isEffective) {
637        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
638            return QueryCondition.createEmpty();
639        }
640        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, "%" + value + "%").when(isEffective.test(value)));
641    }
642
643    @Override
644    public QueryCondition likeLeft(Object value) {
645        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
646            return QueryCondition.createEmpty();
647        }
648        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, value + "%"));
649    }
650
651    @Override
652    public QueryCondition likeLeft(Object value, boolean isEffective) {
653        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
654            return QueryCondition.createEmpty();
655        }
656        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, value + "%").when(isEffective));
657    }
658
659    @Override
660    public QueryCondition likeLeft(Object value, BooleanSupplier isEffective) {
661        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
662            return QueryCondition.createEmpty();
663        }
664        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, value + "%").when(isEffective));
665    }
666
667    @Override
668    public <T> QueryCondition likeLeft(T value, Predicate<T> isEffective) {
669        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
670            return QueryCondition.createEmpty();
671        }
672        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, value + "%").when(isEffective.test(value)));
673    }
674
675    @Override
676    public QueryCondition likeRight(Object value) {
677        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
678            return QueryCondition.createEmpty();
679        }
680        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, "%" + value));
681    }
682
683    @Override
684    public QueryCondition likeRight(Object value, boolean isEffective) {
685        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
686            return QueryCondition.createEmpty();
687        }
688        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, "%" + value).when(isEffective));
689    }
690
691    @Override
692    public QueryCondition likeRight(Object value, BooleanSupplier isEffective) {
693        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
694            return QueryCondition.createEmpty();
695        }
696        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, "%" + value).when(isEffective));
697    }
698
699    @Override
700    public <T> QueryCondition likeRight(T value, Predicate<T> isEffective) {
701        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
702            return QueryCondition.createEmpty();
703        }
704        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, "%" + value).when(isEffective.test(value)));
705    }
706
707    /**
708     * {@code LIKE value}
709     */
710    public QueryCondition likeRaw(Object value) {
711        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
712            return QueryCondition.createEmpty();
713        }
714        return likeRaw(value, true);
715    }
716
717    /**
718     * {@code LIKE value}
719     */
720    public QueryCondition likeRaw(Object value, boolean isEffective) {
721        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
722            return QueryCondition.createEmpty();
723        }
724        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, value).when(isEffective));
725    }
726
727    /**
728     * {@code LIKE value}
729     */
730    public QueryCondition likeRaw(Object value, BooleanSupplier isEffective) {
731        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
732            return QueryCondition.createEmpty();
733        }
734        return likeRaw(value, isEffective.getAsBoolean());
735    }
736
737    /**
738     * {@code LIKE value}
739     */
740    public <T> QueryCondition likeRaw(T value, Predicate<T> isEffective) {
741        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
742            return QueryCondition.createEmpty();
743        }
744        return likeRaw(value, isEffective.test(value));
745    }
746
747    @Override
748    public QueryCondition notLike(Object value) {
749        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
750            return QueryCondition.createEmpty();
751        }
752        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, "%" + value + "%"));
753    }
754
755    @Override
756    public QueryCondition notLike(Object value, boolean isEffective) {
757        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
758            return QueryCondition.createEmpty();
759        }
760        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, "%" + value + "%").when(isEffective));
761    }
762
763    @Override
764    public QueryCondition notLike(Object value, BooleanSupplier isEffective) {
765        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
766            return QueryCondition.createEmpty();
767        }
768        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, "%" + value + "%").when(isEffective));
769    }
770
771    @Override
772    public <T> QueryCondition notLike(T value, Predicate<T> isEffective) {
773        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
774            return QueryCondition.createEmpty();
775        }
776        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, "%" + value + "%").when(isEffective.test(value)));
777    }
778
779    @Override
780    public QueryCondition notLikeLeft(Object value) {
781        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
782            return QueryCondition.createEmpty();
783        }
784        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, value + "%"));
785    }
786
787    @Override
788    public QueryCondition notLikeLeft(Object value, boolean isEffective) {
789        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
790            return QueryCondition.createEmpty();
791        }
792        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, value + "%").when(isEffective));
793    }
794
795    @Override
796    public QueryCondition notLikeLeft(Object value, BooleanSupplier isEffective) {
797        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
798            return QueryCondition.createEmpty();
799        }
800        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, value + "%").when(isEffective));
801    }
802
803    @Override
804    public <T> QueryCondition notLikeLeft(T value, Predicate<T> isEffective) {
805        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
806            return QueryCondition.createEmpty();
807        }
808        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, value + "%").when(isEffective.test(value)));
809    }
810
811    @Override
812    public QueryCondition notLikeRight(Object value) {
813        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
814            return QueryCondition.createEmpty();
815        }
816        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, "%" + value));
817    }
818
819    @Override
820    public QueryCondition notLikeRight(Object value, boolean isEffective) {
821        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
822            return QueryCondition.createEmpty();
823        }
824        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, "%" + value).when(isEffective));
825    }
826
827    @Override
828    public QueryCondition notLikeRight(Object value, BooleanSupplier isEffective) {
829        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
830            return QueryCondition.createEmpty();
831        }
832        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, "%" + value).when(isEffective));
833    }
834
835    @Override
836    public <T> QueryCondition notLikeRight(T value, Predicate<T> isEffective) {
837        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
838            return QueryCondition.createEmpty();
839        }
840        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, "%" + value).when(isEffective.test(value)));
841    }
842
843    /**
844     * {@code NOT LIKE value}
845     */
846    public QueryCondition notLikeRaw(Object value) {
847        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
848            return QueryCondition.createEmpty();
849        }
850        return likeRaw(value, true);
851    }
852
853    /**
854     * {@code NOT LIKE value}
855     */
856    public QueryCondition notLikeRaw(Object value, boolean isEffective) {
857        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
858            return QueryCondition.createEmpty();
859        }
860        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, value).when(isEffective));
861    }
862
863    /**
864     * {@code NOT LIKE value}
865     */
866    public QueryCondition notLikeRaw(Object value, BooleanSupplier isEffective) {
867        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
868            return QueryCondition.createEmpty();
869        }
870        return likeRaw(value, isEffective.getAsBoolean());
871    }
872
873    /**
874     * {@code NOT LIKE value}
875     */
876    public <T> QueryCondition notLikeRaw(T value, Predicate<T> isEffective) {
877        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
878            return QueryCondition.createEmpty();
879        }
880        return likeRaw(value, isEffective.test(value));
881    }
882
883    @Override
884    public QueryCondition isNull(boolean isEffective) {
885        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.IS_NULL, null).when(isEffective));
886    }
887
888    @Override
889    public QueryCondition isNotNull(boolean isEffective) {
890        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.IS_NOT_NULL, null).when(isEffective));
891    }
892
893
894    ////order by ////
895    public QueryOrderBy asc() {
896        return new QueryOrderBy(this, SqlConsts.ASC);
897    }
898
899
900    public QueryOrderBy desc() {
901        return new QueryOrderBy(this, SqlConsts.DESC);
902    }
903
904
905    // 运算 加减乘除 + - * /
906    public QueryColumn add(QueryColumn queryColumn) {
907        return new ArithmeticQueryColumn(this).add(queryColumn);
908    }
909
910    public QueryColumn add(Number number) {
911        return new ArithmeticQueryColumn(this).add(number);
912    }
913
914    public QueryColumn subtract(QueryColumn queryColumn) {
915        return new ArithmeticQueryColumn(this).subtract(queryColumn);
916    }
917
918    public QueryColumn subtract(Number number) {
919        return new ArithmeticQueryColumn(this).subtract(number);
920    }
921
922    public QueryColumn multiply(QueryColumn queryColumn) {
923        return new ArithmeticQueryColumn(this).multiply(queryColumn);
924    }
925
926    public QueryColumn multiply(Number number) {
927        return new ArithmeticQueryColumn(this).multiply(number);
928    }
929
930    public QueryColumn divide(QueryColumn queryColumn) {
931        return new ArithmeticQueryColumn(this).divide(queryColumn);
932    }
933
934    public QueryColumn divide(Number number) {
935        return new ArithmeticQueryColumn(this).divide(number);
936    }
937
938    /**
939     * 生成列用于构建查询条件的 SQL 语句。
940     *
941     * @param queryTables 查询表
942     * @param dialect     方言
943     * @return SQL 语句
944     */
945    protected String toConditionSql(List<QueryTable> queryTables, IDialect dialect) {
946        QueryTable selectTable = getSelectTable(queryTables, table);
947        if (selectTable == null) {
948            return dialect.wrap(name);
949        } else {
950            if (StringUtil.isNotBlank(selectTable.alias)) {
951                return dialect.wrap(selectTable.alias) + SqlConsts.REFERENCE + dialect.wrap(name);
952            } else if (StringUtil.isNotBlank(selectTable.getSchema()) && StringUtil.isNotBlank(selectTable.getName())) {
953                String realTable = dialect.getRealTable(selectTable.getName(), OperateType.SELECT);
954                return dialect.wrap(dialect.getRealSchema(selectTable.schema, realTable, OperateType.SELECT)) + SqlConsts.REFERENCE + dialect.wrap(realTable)
955                    + SqlConsts.REFERENCE + dialect.wrap(name);
956            } else if (StringUtil.isNotBlank(selectTable.getName())) {
957                return dialect.wrap(dialect.getRealTable(selectTable.getName(), OperateType.SELECT)) + SqlConsts.REFERENCE + dialect.wrap(name);
958            } else {
959                return dialect.wrap(name);
960            }
961        }
962    }
963
964    /**
965     * 生成列用于构建查询列的 SQL 语句。
966     *
967     * @param queryTables 查询表
968     * @param dialect     方言
969     * @return SQL 语句
970     */
971    protected String toSelectSql(List<QueryTable> queryTables, IDialect dialect) {
972        return toConditionSql(queryTables, dialect) + WrapperUtil.buildColumnAlias(alias, dialect);
973    }
974
975    QueryTable getSelectTable(List<QueryTable> queryTables, QueryTable selfTable) {
976        // 未查询任何表,或查询表仅有一个
977        // 可以省略表的引用,直接使用列名
978        // SELECT 1
979        // SELECT id FROM tb_user
980        if (queryTables == null || queryTables.isEmpty() || queryTables.size() == 1) {
981            return null;
982        }
983
984        // 列未指定表名,仅以字符串的形式输入列名
985        // 以查询表中的第一个表为主
986        // SELECT tb_user.id FROM tb_user
987        if (selfTable == null) {
988            return queryTables.get(0);
989        }
990
991        // 当前表有别名,以别名为主
992        // SELECT u.id FROM tb_user u
993        if (StringUtil.isNotBlank(selfTable.alias)) {
994            return selfTable;
995        }
996
997        QueryTable consideredTable = selfTable;
998
999        // 当前表存在且没有别名
1000        ListIterator<QueryTable> it = queryTables.listIterator(queryTables.size());
1001
1002        while (it.hasPrevious()) {
1003            QueryTable queryTable = it.previous();
1004            if (Objects.equals(queryTable.name, selfTable.name)) {
1005                if (StringUtil.isBlank(queryTable.alias)) {
1006                    // 因为当前表没有别名,所以表名相同有没有别名,一定是这个表
1007                    return queryTable;
1008                } else {
1009                    // 只是表名相同,但是查询表有别名,当前表没有别名
1010                    // 考虑这个表,但是继续寻找,是否有未设置别名的表
1011                    consideredTable = queryTable;
1012                }
1013            }
1014        }
1015
1016        return consideredTable;
1017    }
1018
1019
1020    @Override
1021    public String toString() {
1022        return "QueryColumn{" +
1023            "table=" + table +
1024            ", name='" + name + '\'' +
1025            ", alias='" + alias + '\'' +
1026            '}';
1027    }
1028
1029
1030    @Override
1031    public QueryColumn clone() {
1032        try {
1033            QueryColumn clone = (QueryColumn) super.clone();
1034            // deep clone ...
1035            clone.table = ObjectUtil.clone(this.table);
1036            return clone;
1037        } catch (CloneNotSupportedException e) {
1038            throw FlexExceptions.wrap(e);
1039        }
1040    }
1041
1042}