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
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 start, Object end) {
583        if (QueryColumnBehavior.shouldIgnoreValue(start) || QueryColumnBehavior.shouldIgnoreValue(end)) {
584            return QueryCondition.createEmpty();
585        }
586        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.BETWEEN, new Object[]{start, end}));
587    }
588
589    @Override
590    public QueryCondition between(Object start, Object end, boolean isEffective) {
591        if (QueryColumnBehavior.shouldIgnoreValue(start) || QueryColumnBehavior.shouldIgnoreValue(end)) {
592            return QueryCondition.createEmpty();
593        }
594        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.BETWEEN, new Object[]{start, end}).when(isEffective));
595    }
596
597    @Override
598    public QueryCondition between(Object start, Object end, BooleanSupplier isEffective) {
599        if (QueryColumnBehavior.shouldIgnoreValue(start) || QueryColumnBehavior.shouldIgnoreValue(end)) {
600            return QueryCondition.createEmpty();
601        }
602        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.BETWEEN, new Object[]{start, end}).when(isEffective));
603    }
604
605    @Override
606    public <S, E> QueryCondition between(S start, E end, BiPredicate<S, E> isEffective) {
607        if (QueryColumnBehavior.shouldIgnoreValue(start) || QueryColumnBehavior.shouldIgnoreValue(end)) {
608            return QueryCondition.createEmpty();
609        }
610        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.BETWEEN, new Object[]{start, end}).when(isEffective.test(start, end)));
611    }
612
613    @Override
614    public QueryCondition notBetween(Object start, Object end) {
615        if (QueryColumnBehavior.shouldIgnoreValue(start) || QueryColumnBehavior.shouldIgnoreValue(end)) {
616            return QueryCondition.createEmpty();
617        }
618        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_BETWEEN, new Object[]{start, end}));
619    }
620
621    @Override
622    public QueryCondition notBetween(Object start, Object end, boolean isEffective) {
623        if (QueryColumnBehavior.shouldIgnoreValue(start) || QueryColumnBehavior.shouldIgnoreValue(end)) {
624            return QueryCondition.createEmpty();
625        }
626        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_BETWEEN, new Object[]{start, end}).when(isEffective));
627    }
628
629    @Override
630    public QueryCondition notBetween(Object start, Object end, BooleanSupplier isEffective) {
631        if (QueryColumnBehavior.shouldIgnoreValue(start) || QueryColumnBehavior.shouldIgnoreValue(end)) {
632            return QueryCondition.createEmpty();
633        }
634        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_BETWEEN, new Object[]{start, end}).when(isEffective));
635    }
636
637    @Override
638    public <S, E> QueryCondition notBetween(S start, E end, BiPredicate<S, E> isEffective) {
639        if (QueryColumnBehavior.shouldIgnoreValue(start) || QueryColumnBehavior.shouldIgnoreValue(end)) {
640            return QueryCondition.createEmpty();
641        }
642        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_BETWEEN, new Object[]{start, end}).when(isEffective.test(start, end)));
643    }
644
645    @Override
646    public QueryCondition like(Object value) {
647        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
648            return QueryCondition.createEmpty();
649        }
650        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, "%" + value + "%"));
651    }
652
653    @Override
654    public QueryCondition like(Object value, boolean isEffective) {
655        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
656            return QueryCondition.createEmpty();
657        }
658        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, "%" + value + "%").when(isEffective));
659    }
660
661    @Override
662    public QueryCondition like(Object value, BooleanSupplier isEffective) {
663        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
664            return QueryCondition.createEmpty();
665        }
666        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, "%" + value + "%").when(isEffective));
667    }
668
669    @Override
670    public <T> QueryCondition like(T value, Predicate<T> isEffective) {
671        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
672            return QueryCondition.createEmpty();
673        }
674        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, "%" + value + "%").when(isEffective.test(value)));
675    }
676
677    @Override
678    public QueryCondition likeLeft(Object value) {
679        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
680            return QueryCondition.createEmpty();
681        }
682        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, value + "%"));
683    }
684
685    @Override
686    public QueryCondition likeLeft(Object value, boolean isEffective) {
687        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
688            return QueryCondition.createEmpty();
689        }
690        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, value + "%").when(isEffective));
691    }
692
693    @Override
694    public QueryCondition likeLeft(Object value, BooleanSupplier isEffective) {
695        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
696            return QueryCondition.createEmpty();
697        }
698        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, value + "%").when(isEffective));
699    }
700
701    @Override
702    public <T> QueryCondition likeLeft(T value, Predicate<T> isEffective) {
703        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
704            return QueryCondition.createEmpty();
705        }
706        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, value + "%").when(isEffective.test(value)));
707    }
708
709    @Override
710    public QueryCondition likeRight(Object value) {
711        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
712            return QueryCondition.createEmpty();
713        }
714        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, "%" + value));
715    }
716
717    @Override
718    public QueryCondition likeRight(Object value, boolean isEffective) {
719        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
720            return QueryCondition.createEmpty();
721        }
722        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, "%" + value).when(isEffective));
723    }
724
725    @Override
726    public QueryCondition likeRight(Object value, BooleanSupplier isEffective) {
727        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
728            return QueryCondition.createEmpty();
729        }
730        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, "%" + value).when(isEffective));
731    }
732
733    @Override
734    public <T> QueryCondition likeRight(T value, Predicate<T> isEffective) {
735        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
736            return QueryCondition.createEmpty();
737        }
738        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.LIKE, "%" + value).when(isEffective.test(value)));
739    }
740
741    /**
742     * {@code LIKE value}
743     */
744    public QueryCondition likeRaw(Object value) {
745        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
746            return QueryCondition.createEmpty();
747        }
748        return likeRaw(value, true);
749    }
750
751    /**
752     * {@code LIKE value}
753     */
754    public QueryCondition likeRaw(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    /**
762     * {@code LIKE value}
763     */
764    public QueryCondition likeRaw(Object value, BooleanSupplier isEffective) {
765        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
766            return QueryCondition.createEmpty();
767        }
768        return likeRaw(value, isEffective.getAsBoolean());
769    }
770
771    /**
772     * {@code LIKE value}
773     */
774    public <T> QueryCondition likeRaw(T value, Predicate<T> isEffective) {
775        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
776            return QueryCondition.createEmpty();
777        }
778        return likeRaw(value, isEffective.test(value));
779    }
780
781    @Override
782    public QueryCondition notLike(Object value) {
783        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
784            return QueryCondition.createEmpty();
785        }
786        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, "%" + value + "%"));
787    }
788
789    @Override
790    public QueryCondition notLike(Object value, boolean isEffective) {
791        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
792            return QueryCondition.createEmpty();
793        }
794        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, "%" + value + "%").when(isEffective));
795    }
796
797    @Override
798    public QueryCondition notLike(Object value, BooleanSupplier isEffective) {
799        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
800            return QueryCondition.createEmpty();
801        }
802        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, "%" + value + "%").when(isEffective));
803    }
804
805    @Override
806    public <T> QueryCondition notLike(T value, Predicate<T> isEffective) {
807        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
808            return QueryCondition.createEmpty();
809        }
810        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, "%" + value + "%").when(isEffective.test(value)));
811    }
812
813    @Override
814    public QueryCondition notLikeLeft(Object value) {
815        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
816            return QueryCondition.createEmpty();
817        }
818        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, value + "%"));
819    }
820
821    @Override
822    public QueryCondition notLikeLeft(Object value, boolean isEffective) {
823        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
824            return QueryCondition.createEmpty();
825        }
826        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, value + "%").when(isEffective));
827    }
828
829    @Override
830    public QueryCondition notLikeLeft(Object value, BooleanSupplier isEffective) {
831        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
832            return QueryCondition.createEmpty();
833        }
834        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, value + "%").when(isEffective));
835    }
836
837    @Override
838    public <T> QueryCondition notLikeLeft(T value, Predicate<T> isEffective) {
839        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
840            return QueryCondition.createEmpty();
841        }
842        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, value + "%").when(isEffective.test(value)));
843    }
844
845    @Override
846    public QueryCondition notLikeRight(Object value) {
847        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
848            return QueryCondition.createEmpty();
849        }
850        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, "%" + value));
851    }
852
853    @Override
854    public QueryCondition notLikeRight(Object value, boolean isEffective) {
855        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
856            return QueryCondition.createEmpty();
857        }
858        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, "%" + value).when(isEffective));
859    }
860
861    @Override
862    public QueryCondition notLikeRight(Object value, BooleanSupplier isEffective) {
863        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
864            return QueryCondition.createEmpty();
865        }
866        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, "%" + value).when(isEffective));
867    }
868
869    @Override
870    public <T> QueryCondition notLikeRight(T value, Predicate<T> isEffective) {
871        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
872            return QueryCondition.createEmpty();
873        }
874        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.NOT_LIKE, "%" + value).when(isEffective.test(value)));
875    }
876
877    /**
878     * {@code NOT LIKE value}
879     */
880    public QueryCondition notLikeRaw(Object value) {
881        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
882            return QueryCondition.createEmpty();
883        }
884        return likeRaw(value, true);
885    }
886
887    /**
888     * {@code NOT LIKE value}
889     */
890    public QueryCondition notLikeRaw(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    /**
898     * {@code NOT LIKE value}
899     */
900    public QueryCondition notLikeRaw(Object value, BooleanSupplier isEffective) {
901        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
902            return QueryCondition.createEmpty();
903        }
904        return likeRaw(value, isEffective.getAsBoolean());
905    }
906
907    /**
908     * {@code NOT LIKE value}
909     */
910    public <T> QueryCondition notLikeRaw(T value, Predicate<T> isEffective) {
911        if (QueryColumnBehavior.shouldIgnoreValue(value)) {
912            return QueryCondition.createEmpty();
913        }
914        return likeRaw(value, isEffective.test(value));
915    }
916
917    @Override
918    public QueryCondition isNull(boolean isEffective) {
919        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.IS_NULL, null).when(isEffective));
920    }
921
922    @Override
923    public QueryCondition isNotNull(boolean isEffective) {
924        return QueryColumnBehavior.castCondition(QueryCondition.create(this, SqlOperator.IS_NOT_NULL, null).when(isEffective));
925    }
926
927
928    ////order by ////
929    public QueryOrderBy asc() {
930        return new QueryOrderBy(this, SqlConsts.ASC);
931    }
932
933
934    public QueryOrderBy desc() {
935        return new QueryOrderBy(this, SqlConsts.DESC);
936    }
937
938
939    // 运算 加减乘除 + - * /
940    public QueryColumn add(QueryColumn queryColumn) {
941        return new ArithmeticQueryColumn(this).add(queryColumn);
942    }
943
944    public QueryColumn add(Number number) {
945        return new ArithmeticQueryColumn(this).add(number);
946    }
947
948    public QueryColumn subtract(QueryColumn queryColumn) {
949        return new ArithmeticQueryColumn(this).subtract(queryColumn);
950    }
951
952    public QueryColumn subtract(Number number) {
953        return new ArithmeticQueryColumn(this).subtract(number);
954    }
955
956    public QueryColumn multiply(QueryColumn queryColumn) {
957        return new ArithmeticQueryColumn(this).multiply(queryColumn);
958    }
959
960    public QueryColumn multiply(Number number) {
961        return new ArithmeticQueryColumn(this).multiply(number);
962    }
963
964    public QueryColumn divide(QueryColumn queryColumn) {
965        return new ArithmeticQueryColumn(this).divide(queryColumn);
966    }
967
968    public QueryColumn divide(Number number) {
969        return new ArithmeticQueryColumn(this).divide(number);
970    }
971
972
973    String toConditionSql(List<QueryTable> queryTables, IDialect dialect) {
974        QueryTable selectTable = getSelectTable(queryTables, table);
975        if (selectTable == null) {
976            return dialect.wrap(name);
977        } else {
978            if (StringUtil.isNotBlank(selectTable.alias)) {
979                return dialect.wrap(selectTable.alias) + SqlConsts.REFERENCE + dialect.wrap(name);
980            } else if (StringUtil.isNotBlank(selectTable.getSchema()) && StringUtil.isNotBlank(selectTable.getName())) {
981                String realTable = dialect.getRealTable(selectTable.getName(), OperateType.SELECT);
982                return dialect.wrap(dialect.getRealSchema(selectTable.schema, realTable, OperateType.SELECT)) + SqlConsts.REFERENCE + dialect.wrap(realTable)
983                    + SqlConsts.REFERENCE + dialect.wrap(name);
984            } else if (StringUtil.isNotBlank(selectTable.getName())) {
985                return dialect.wrap(dialect.getRealTable(selectTable.getName(), OperateType.SELECT)) + SqlConsts.REFERENCE + dialect.wrap(name);
986            } else {
987                return dialect.wrap(name);
988            }
989        }
990    }
991
992
993    String toSelectSql(List<QueryTable> queryTables, IDialect dialect) {
994        return toConditionSql(queryTables, dialect) + WrapperUtil.buildColumnAlias(alias, dialect);
995    }
996
997
998    QueryTable getSelectTable(List<QueryTable> queryTables, QueryTable selfTable) {
999        // 未查询任何表
1000        if (queryTables == null || queryTables.isEmpty()) {
1001            return null;
1002        }
1003
1004        if (selfTable != null && StringUtil.isNotBlank(selfTable.alias)) {
1005            return selfTable;
1006        }
1007
1008        if (queryTables.size() == 1 && queryTables.get(0).isSameTable(selfTable)) {
1009            // ignore table
1010            return null;
1011        }
1012
1013        if (CollectionUtil.isEmpty(queryTables)) {
1014            return selfTable;
1015        }
1016
1017        if (selfTable == null && queryTables.size() == 1) {
1018            return queryTables.get(0);
1019        }
1020
1021        for (QueryTable table : queryTables) {
1022            if (table.isSameTable(selfTable)) {
1023                return table;
1024            }
1025        }
1026        return selfTable;
1027    }
1028
1029
1030    @Override
1031    public String toString() {
1032        return "QueryColumn{" +
1033            "table=" + table +
1034            ", name='" + name + '\'' +
1035            ", alias='" + alias + '\'' +
1036            '}';
1037    }
1038
1039
1040    @Override
1041    public QueryColumn clone() {
1042        try {
1043            QueryColumn clone = (QueryColumn) super.clone();
1044            // deep clone ...
1045            clone.table = ObjectUtil.clone(this.table);
1046            return clone;
1047        } catch (CloneNotSupportedException e) {
1048            throw FlexExceptions.wrap(e);
1049        }
1050    }
1051
1052}