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 */
016
017package com.mybatisflex.core.activerecord.query;
018
019import com.mybatisflex.core.constant.SqlConnector;
020import com.mybatisflex.core.constant.SqlConsts;
021import com.mybatisflex.core.query.*;
022import com.mybatisflex.core.table.TableDef;
023import com.mybatisflex.core.table.TableInfo;
024import com.mybatisflex.core.table.TableInfoFactory;
025import com.mybatisflex.core.util.LambdaGetter;
026import com.mybatisflex.core.util.LambdaUtil;
027
028/**
029 * <p>实体类条件查询构建模型。
030 *
031 * <p>该类内部维护了一个 {@link QueryWrapper} 属性,用来构建查询条件。
032 * 通过实体类属性构建的查询条件都是值等于,该扩展用于非等于值构建,及一些其他方法。
033 * 如果不想通过实体类直接构建查询条件,可以不继承该类。
034 *
035 * @param <T> 实体类类型
036 * @author 王帅
037 * @since 2023-07-24
038 */
039@SuppressWarnings({"unused", "unchecked"})
040public abstract class QueryModel<T extends QueryModel<T>> {
041
042    private QueryWrapper queryWrapper;
043
044    protected QueryWrapper queryWrapper() {
045        if (queryWrapper == null) {
046            TableInfo tableInfo = TableInfoFactory.ofEntityClass(getClass());
047            QueryTable queryTable = new QueryTable();
048            queryTable.setSchema(tableInfo.getSchema());
049            queryTable.setName(tableInfo.getTableName());
050            queryWrapper = QueryWrapper.create().from(queryTable);
051        }
052        return queryWrapper;
053    }
054
055    public T as(String alias) {
056        queryWrapper().as(alias);
057        return (T) this;
058    }
059
060    public T select() {
061        return (T) this;
062    }
063
064    public T select(String... columns) {
065        queryWrapper().select(columns);
066        return (T) this;
067    }
068
069    public T select(QueryColumn... queryColumns) {
070        queryWrapper().select(queryColumns);
071        return (T) this;
072    }
073
074    public <E> T select(LambdaGetter<E>... columns) {
075        queryWrapper().select(columns);
076        return (T) this;
077    }
078
079    public T select(QueryColumn[]... queryColumns) {
080        queryWrapper().select(queryColumns);
081        return (T) this;
082    }
083
084    public T where(QueryCondition queryCondition) {
085        queryWrapper().where(queryCondition);
086        return (T) this;
087    }
088
089    public T where(String sql) {
090        queryWrapper().where(sql);
091        return (T) this;
092    }
093
094    public T where(String sql, Object... params) {
095        queryWrapper().where(sql, params);
096        return (T) this;
097    }
098
099    public <E> WhereBuilder<T> where(LambdaGetter<E> column) {
100        return new WhereBuilder<>((T) this, LambdaUtil.getQueryColumn(column), SqlConnector.AND);
101    }
102
103    public T and(QueryCondition queryCondition) {
104        queryWrapper().and(queryCondition);
105        return (T) this;
106    }
107
108    public T and(String sql) {
109        queryWrapper().and(sql);
110        return (T) this;
111    }
112
113    public T and(String sql, Object... params) {
114        queryWrapper().and(sql, params);
115        return (T) this;
116    }
117
118    public <E> WhereBuilder<T> and(LambdaGetter<E> column) {
119        return new WhereBuilder<>((T) this, LambdaUtil.getQueryColumn(column), SqlConnector.AND);
120    }
121
122    public T or(QueryCondition queryCondition) {
123        queryWrapper().or(queryCondition);
124        return (T) this;
125    }
126
127    public T or(String sql) {
128        queryWrapper().or(sql);
129        return (T) this;
130    }
131
132    public T or(String sql, Object... params) {
133        queryWrapper().or(sql, params);
134        return (T) this;
135    }
136
137    public <E> WhereBuilder<T> or(LambdaGetter<E> column) {
138        return new WhereBuilder<>((T) this, LambdaUtil.getQueryColumn(column), SqlConnector.OR);
139    }
140
141    public JoinBuilder<T> leftJoin(String table) {
142        return joins(SqlConsts.LEFT_JOIN, new QueryTable(table), true);
143    }
144
145    public JoinBuilder<T> leftJoin(String table, boolean when) {
146        return joins(SqlConsts.LEFT_JOIN, new QueryTable(table), when);
147    }
148
149    public JoinBuilder<T> leftJoin(Class<?> entityClass) {
150        return joins(SqlConsts.LEFT_JOIN, entityClass, true);
151    }
152
153    public JoinBuilder<T> leftJoin(Class<?> entityClass, boolean when) {
154        return joins(SqlConsts.LEFT_JOIN, entityClass, when);
155    }
156
157    public JoinBuilder<T> leftJoin(TableDef table) {
158        return joins(SqlConsts.LEFT_JOIN, new QueryTable(table), true);
159    }
160
161    public JoinBuilder<T> leftJoin(TableDef table, boolean when) {
162        return joins(SqlConsts.LEFT_JOIN, new QueryTable(table), when);
163    }
164
165    public JoinBuilder<T> leftJoin(QueryWrapper table) {
166        return joins(SqlConsts.LEFT_JOIN, table, true);
167    }
168
169    public JoinBuilder<T> leftJoin(QueryWrapper table, boolean when) {
170        return joins(SqlConsts.LEFT_JOIN, table, when);
171    }
172
173    public JoinBuilder<T> rightJoin(String table) {
174        return joins(SqlConsts.RIGHT_JOIN, new QueryTable(table), true);
175    }
176
177    public JoinBuilder<T> rightJoin(String table, boolean when) {
178        return joins(SqlConsts.RIGHT_JOIN, new QueryTable(table), when);
179    }
180
181    public JoinBuilder<T> rightJoin(Class<?> entityClass) {
182        return joins(SqlConsts.RIGHT_JOIN, entityClass, true);
183    }
184
185    public JoinBuilder<T> rightJoin(Class<?> entityClass, boolean when) {
186        return joins(SqlConsts.RIGHT_JOIN, entityClass, when);
187    }
188
189    public JoinBuilder<T> rightJoin(TableDef table) {
190        return joins(SqlConsts.RIGHT_JOIN, new QueryTable(table), true);
191    }
192
193    public JoinBuilder<T> rightJoin(TableDef table, boolean when) {
194        return joins(SqlConsts.RIGHT_JOIN, new QueryTable(table), when);
195    }
196
197    public JoinBuilder<T> rightJoin(QueryWrapper table) {
198        return joins(SqlConsts.RIGHT_JOIN, table, true);
199    }
200
201    public JoinBuilder<T> rightJoin(QueryWrapper table, boolean when) {
202        return joins(SqlConsts.RIGHT_JOIN, table, when);
203    }
204
205    public JoinBuilder<T> innerJoin(String table) {
206        return joins(SqlConsts.INNER_JOIN, new QueryTable(table), true);
207    }
208
209    public JoinBuilder<T> innerJoin(String table, boolean when) {
210        return joins(SqlConsts.INNER_JOIN, new QueryTable(table), when);
211    }
212
213    public JoinBuilder<T> innerJoin(Class<?> entityClass) {
214        return joins(SqlConsts.INNER_JOIN, entityClass, true);
215    }
216
217    public JoinBuilder<T> innerJoin(Class<?> entityClass, boolean when) {
218        return joins(SqlConsts.INNER_JOIN, entityClass, when);
219    }
220
221    public JoinBuilder<T> innerJoin(TableDef table) {
222        return innerJoin(table, true);
223    }
224
225    public JoinBuilder<T> innerJoin(TableDef table, boolean when) {
226        return joins(SqlConsts.INNER_JOIN, new QueryTable(table), when);
227    }
228
229    public JoinBuilder<T> innerJoin(QueryWrapper table) {
230        return joins(SqlConsts.INNER_JOIN, table, true);
231    }
232
233    public JoinBuilder<T> innerJoin(QueryWrapper table, boolean when) {
234        return joins(SqlConsts.INNER_JOIN, table, when);
235    }
236
237    public JoinBuilder<T> fullJoin(String table) {
238        return joins(SqlConsts.FULL_JOIN, new QueryTable(table), true);
239    }
240
241    public JoinBuilder<T> fullJoin(String table, boolean when) {
242        return joins(SqlConsts.FULL_JOIN, new QueryTable(table), when);
243    }
244
245    public JoinBuilder<T> fullJoin(Class<?> entityClass) {
246        return joins(SqlConsts.FULL_JOIN, entityClass, true);
247    }
248
249    public JoinBuilder<T> fullJoin(Class<?> entityClass, boolean when) {
250        return joins(SqlConsts.FULL_JOIN, entityClass, when);
251    }
252
253    public JoinBuilder<T> fullJoin(TableDef table) {
254        return joins(SqlConsts.FULL_JOIN, new QueryTable(table), true);
255    }
256
257    public JoinBuilder<T> fullJoin(TableDef table, boolean when) {
258        return joins(SqlConsts.FULL_JOIN, new QueryTable(table), when);
259    }
260
261    public JoinBuilder<T> fullJoin(QueryWrapper table) {
262        return joins(SqlConsts.FULL_JOIN, table, true);
263    }
264
265    public JoinBuilder<T> fullJoin(QueryWrapper table, boolean when) {
266        return joins(SqlConsts.FULL_JOIN, table, when);
267    }
268
269    public JoinBuilder<T> crossJoin(String table) {
270        return joins(SqlConsts.CROSS_JOIN, new QueryTable(table), true);
271    }
272
273    public JoinBuilder<T> crossJoin(String table, boolean when) {
274        return joins(SqlConsts.CROSS_JOIN, new QueryTable(table), when);
275    }
276
277    public JoinBuilder<T> crossJoin(Class<?> entityClass) {
278        return joins(SqlConsts.CROSS_JOIN, entityClass, true);
279    }
280
281    public JoinBuilder<T> crossJoin(Class<?> entityClass, boolean when) {
282        return joins(SqlConsts.CROSS_JOIN, entityClass, when);
283    }
284
285    public JoinBuilder<T> crossJoin(TableDef table) {
286        return joins(SqlConsts.CROSS_JOIN, new QueryTable(table), true);
287    }
288
289    public JoinBuilder<T> crossJoin(TableDef table, boolean when) {
290        return joins(SqlConsts.CROSS_JOIN, new QueryTable(table), when);
291    }
292
293    public JoinBuilder<T> crossJoin(QueryWrapper table) {
294        return joins(SqlConsts.CROSS_JOIN, table, true);
295    }
296
297    public JoinBuilder<T> crossJoin(QueryWrapper table, boolean when) {
298        return joins(SqlConsts.CROSS_JOIN, table, when);
299    }
300
301    public JoinBuilder<T> join(String table) {
302        return joins(SqlConsts.JOIN, new QueryTable(table), true);
303    }
304
305    public JoinBuilder<T> join(String table, boolean when) {
306        return joins(SqlConsts.JOIN, new QueryTable(table), when);
307    }
308
309    public JoinBuilder<T> join(Class<?> entityClass) {
310        return joins(SqlConsts.JOIN, entityClass, true);
311    }
312
313    public JoinBuilder<T> join(Class<?> entityClass, boolean when) {
314        return joins(SqlConsts.JOIN, entityClass, when);
315    }
316
317    public JoinBuilder<T> join(TableDef table) {
318        return joins(SqlConsts.JOIN, new QueryTable(table), true);
319    }
320
321    public JoinBuilder<T> join(TableDef table, boolean when) {
322        return joins(SqlConsts.JOIN, new QueryTable(table), when);
323    }
324
325    public JoinBuilder<T> join(QueryWrapper table) {
326        return joins(SqlConsts.JOIN, table, true);
327    }
328
329    public JoinBuilder<T> join(QueryWrapper table, boolean when) {
330        return joins(SqlConsts.JOIN, table, when);
331    }
332
333    public T groupBy(String... names) {
334        queryWrapper().groupBy(names);
335        return (T) this;
336    }
337
338    public T groupBy(QueryColumn... columns) {
339        queryWrapper().groupBy(columns);
340        return (T) this;
341    }
342
343    public <E> T groupBy(LambdaGetter<E>... columns) {
344        queryWrapper().groupBy(columns);
345        return (T) this;
346    }
347
348    public T having(QueryCondition queryCondition) {
349        queryWrapper().having(queryCondition);
350        return (T) this;
351    }
352
353    public T orderBy(QueryOrderBy... orderBys) {
354        queryWrapper().orderBy(orderBys);
355        return (T) this;
356    }
357
358    public T orderBy(QueryColumn column, Boolean asc) {
359        queryWrapper().orderBy(column, asc);
360        return (T) this;
361    }
362
363    public T orderBy(String... orderBys) {
364        queryWrapper().orderBy(orderBys);
365        return (T) this;
366    }
367
368    public T orderBy(String column, Boolean asc) {
369        queryWrapper().orderBy(column, asc);
370        return (T) this;
371    }
372
373    public <E> OrderByBuilder<T> orderBy(LambdaGetter<E> column) {
374        return new OrderByBuilder<>((T) this, column);
375    }
376
377    public <E> T orderBy(LambdaGetter<E> column, Boolean asc) {
378        queryWrapper().orderBy(column, asc);
379        return (T) this;
380    }
381
382    public T limit(Number rows) {
383        queryWrapper().limit(rows);
384        return (T) this;
385    }
386
387    public T offset(Number offset) {
388        queryWrapper().offset(offset);
389        return (T) this;
390    }
391
392    public T limit(Number offset, Number rows) {
393        queryWrapper().limit(offset, rows);
394        return (T) this;
395    }
396
397    protected JoinBuilder<T> joins(String type, QueryTable table, boolean when) {
398        Join join = new Join(type, table, when);
399        CPI.addJoin(queryWrapper(), join);
400        return new JoinBuilder<>((T) this, join);
401    }
402
403    protected JoinBuilder<T> joins(String type, Class<?> entityClass, boolean when) {
404        TableInfo tableInfo = TableInfoFactory.ofEntityClass(entityClass);
405        QueryTable queryTable = new QueryTable(tableInfo.getSchema(), tableInfo.getTableName());
406        return joins(type, queryTable, when);
407    }
408
409    protected JoinBuilder<T> joins(String type, QueryWrapper queryWrapper, boolean when) {
410        Join join = new Join(type, queryWrapper, when);
411        CPI.addJoin(queryWrapper(), join);
412        return new JoinBuilder<>((T) this, join);
413    }
414
415}