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 T select(Iterable<QueryColumn> queryColumns) {
075        queryWrapper().select(queryColumns);
076        return (T) this;
077    }
078    @SafeVarargs
079    public final <E> T select(LambdaGetter<E>... columns) {
080        queryWrapper().select(columns);
081        return (T) this;
082    }
083
084    public T select(QueryColumn[]... queryColumns) {
085        queryWrapper().select(queryColumns);
086        return (T) this;
087    }
088
089    public T where(QueryCondition queryCondition) {
090        queryWrapper().where(queryCondition);
091        return (T) this;
092    }
093
094    public T where(String sql) {
095        queryWrapper().where(sql);
096        return (T) this;
097    }
098
099    public T where(String sql, Object... params) {
100        queryWrapper().where(sql, params);
101        return (T) this;
102    }
103
104    public <E> WhereBuilder<T> where(LambdaGetter<E> column) {
105        return new WhereBuilder<>((T) this, LambdaUtil.getQueryColumn(column), SqlConnector.AND);
106    }
107
108    public T and(QueryCondition queryCondition) {
109        queryWrapper().and(queryCondition);
110        return (T) this;
111    }
112
113    public T and(String sql) {
114        queryWrapper().and(sql);
115        return (T) this;
116    }
117
118    public T and(String sql, Object... params) {
119        queryWrapper().and(sql, params);
120        return (T) this;
121    }
122
123    public <E> WhereBuilder<T> and(LambdaGetter<E> column) {
124        return new WhereBuilder<>((T) this, LambdaUtil.getQueryColumn(column), SqlConnector.AND);
125    }
126
127    public T or(QueryCondition queryCondition) {
128        queryWrapper().or(queryCondition);
129        return (T) this;
130    }
131
132    public T or(String sql) {
133        queryWrapper().or(sql);
134        return (T) this;
135    }
136
137    public T or(String sql, Object... params) {
138        queryWrapper().or(sql, params);
139        return (T) this;
140    }
141
142    public <E> WhereBuilder<T> or(LambdaGetter<E> column) {
143        return new WhereBuilder<>((T) this, LambdaUtil.getQueryColumn(column), SqlConnector.OR);
144    }
145
146    public JoinBuilder<T> leftJoin(String table) {
147        return joins(SqlConsts.LEFT_JOIN, new QueryTable(table), true);
148    }
149
150    public JoinBuilder<T> leftJoin(String table, boolean when) {
151        return joins(SqlConsts.LEFT_JOIN, new QueryTable(table), when);
152    }
153
154    public JoinBuilder<T> leftJoin(Class<?> entityClass) {
155        return joins(SqlConsts.LEFT_JOIN, entityClass, true);
156    }
157
158    public JoinBuilder<T> leftJoin(Class<?> entityClass, boolean when) {
159        return joins(SqlConsts.LEFT_JOIN, entityClass, when);
160    }
161
162    public JoinBuilder<T> leftJoin(TableDef table) {
163        return joins(SqlConsts.LEFT_JOIN, new QueryTable(table), true);
164    }
165
166    public JoinBuilder<T> leftJoin(TableDef table, boolean when) {
167        return joins(SqlConsts.LEFT_JOIN, new QueryTable(table), when);
168    }
169
170    public JoinBuilder<T> leftJoin(QueryWrapper table) {
171        return joins(SqlConsts.LEFT_JOIN, table, true);
172    }
173
174    public JoinBuilder<T> leftJoin(QueryWrapper table, boolean when) {
175        return joins(SqlConsts.LEFT_JOIN, table, when);
176    }
177
178    public JoinBuilder<T> rightJoin(String table) {
179        return joins(SqlConsts.RIGHT_JOIN, new QueryTable(table), true);
180    }
181
182    public JoinBuilder<T> rightJoin(String table, boolean when) {
183        return joins(SqlConsts.RIGHT_JOIN, new QueryTable(table), when);
184    }
185
186    public JoinBuilder<T> rightJoin(Class<?> entityClass) {
187        return joins(SqlConsts.RIGHT_JOIN, entityClass, true);
188    }
189
190    public JoinBuilder<T> rightJoin(Class<?> entityClass, boolean when) {
191        return joins(SqlConsts.RIGHT_JOIN, entityClass, when);
192    }
193
194    public JoinBuilder<T> rightJoin(TableDef table) {
195        return joins(SqlConsts.RIGHT_JOIN, new QueryTable(table), true);
196    }
197
198    public JoinBuilder<T> rightJoin(TableDef table, boolean when) {
199        return joins(SqlConsts.RIGHT_JOIN, new QueryTable(table), when);
200    }
201
202    public JoinBuilder<T> rightJoin(QueryWrapper table) {
203        return joins(SqlConsts.RIGHT_JOIN, table, true);
204    }
205
206    public JoinBuilder<T> rightJoin(QueryWrapper table, boolean when) {
207        return joins(SqlConsts.RIGHT_JOIN, table, when);
208    }
209
210    public JoinBuilder<T> innerJoin(String table) {
211        return joins(SqlConsts.INNER_JOIN, new QueryTable(table), true);
212    }
213
214    public JoinBuilder<T> innerJoin(String table, boolean when) {
215        return joins(SqlConsts.INNER_JOIN, new QueryTable(table), when);
216    }
217
218    public JoinBuilder<T> innerJoin(Class<?> entityClass) {
219        return joins(SqlConsts.INNER_JOIN, entityClass, true);
220    }
221
222    public JoinBuilder<T> innerJoin(Class<?> entityClass, boolean when) {
223        return joins(SqlConsts.INNER_JOIN, entityClass, when);
224    }
225
226    public JoinBuilder<T> innerJoin(TableDef table) {
227        return innerJoin(table, true);
228    }
229
230    public JoinBuilder<T> innerJoin(TableDef table, boolean when) {
231        return joins(SqlConsts.INNER_JOIN, new QueryTable(table), when);
232    }
233
234    public JoinBuilder<T> innerJoin(QueryWrapper table) {
235        return joins(SqlConsts.INNER_JOIN, table, true);
236    }
237
238    public JoinBuilder<T> innerJoin(QueryWrapper table, boolean when) {
239        return joins(SqlConsts.INNER_JOIN, table, when);
240    }
241
242    public JoinBuilder<T> fullJoin(String table) {
243        return joins(SqlConsts.FULL_JOIN, new QueryTable(table), true);
244    }
245
246    public JoinBuilder<T> fullJoin(String table, boolean when) {
247        return joins(SqlConsts.FULL_JOIN, new QueryTable(table), when);
248    }
249
250    public JoinBuilder<T> fullJoin(Class<?> entityClass) {
251        return joins(SqlConsts.FULL_JOIN, entityClass, true);
252    }
253
254    public JoinBuilder<T> fullJoin(Class<?> entityClass, boolean when) {
255        return joins(SqlConsts.FULL_JOIN, entityClass, when);
256    }
257
258    public JoinBuilder<T> fullJoin(TableDef table) {
259        return joins(SqlConsts.FULL_JOIN, new QueryTable(table), true);
260    }
261
262    public JoinBuilder<T> fullJoin(TableDef table, boolean when) {
263        return joins(SqlConsts.FULL_JOIN, new QueryTable(table), when);
264    }
265
266    public JoinBuilder<T> fullJoin(QueryWrapper table) {
267        return joins(SqlConsts.FULL_JOIN, table, true);
268    }
269
270    public JoinBuilder<T> fullJoin(QueryWrapper table, boolean when) {
271        return joins(SqlConsts.FULL_JOIN, table, when);
272    }
273
274    public JoinBuilder<T> crossJoin(String table) {
275        return joins(SqlConsts.CROSS_JOIN, new QueryTable(table), true);
276    }
277
278    public JoinBuilder<T> crossJoin(String table, boolean when) {
279        return joins(SqlConsts.CROSS_JOIN, new QueryTable(table), when);
280    }
281
282    public JoinBuilder<T> crossJoin(Class<?> entityClass) {
283        return joins(SqlConsts.CROSS_JOIN, entityClass, true);
284    }
285
286    public JoinBuilder<T> crossJoin(Class<?> entityClass, boolean when) {
287        return joins(SqlConsts.CROSS_JOIN, entityClass, when);
288    }
289
290    public JoinBuilder<T> crossJoin(TableDef table) {
291        return joins(SqlConsts.CROSS_JOIN, new QueryTable(table), true);
292    }
293
294    public JoinBuilder<T> crossJoin(TableDef table, boolean when) {
295        return joins(SqlConsts.CROSS_JOIN, new QueryTable(table), when);
296    }
297
298    public JoinBuilder<T> crossJoin(QueryWrapper table) {
299        return joins(SqlConsts.CROSS_JOIN, table, true);
300    }
301
302    public JoinBuilder<T> crossJoin(QueryWrapper table, boolean when) {
303        return joins(SqlConsts.CROSS_JOIN, table, when);
304    }
305
306    public JoinBuilder<T> join(String table) {
307        return joins(SqlConsts.JOIN, new QueryTable(table), true);
308    }
309
310    public JoinBuilder<T> join(String table, boolean when) {
311        return joins(SqlConsts.JOIN, new QueryTable(table), when);
312    }
313
314    public JoinBuilder<T> join(Class<?> entityClass) {
315        return joins(SqlConsts.JOIN, entityClass, true);
316    }
317
318    public JoinBuilder<T> join(Class<?> entityClass, boolean when) {
319        return joins(SqlConsts.JOIN, entityClass, when);
320    }
321
322    public JoinBuilder<T> join(TableDef table) {
323        return joins(SqlConsts.JOIN, new QueryTable(table), true);
324    }
325
326    public JoinBuilder<T> join(TableDef table, boolean when) {
327        return joins(SqlConsts.JOIN, new QueryTable(table), when);
328    }
329
330    public JoinBuilder<T> join(QueryWrapper table) {
331        return joins(SqlConsts.JOIN, table, true);
332    }
333
334    public JoinBuilder<T> join(QueryWrapper table, boolean when) {
335        return joins(SqlConsts.JOIN, table, when);
336    }
337
338    public T groupBy(String... names) {
339        queryWrapper().groupBy(names);
340        return (T) this;
341    }
342
343    public T groupBy(QueryColumn... columns) {
344        queryWrapper().groupBy(columns);
345        return (T) this;
346    }
347    @SafeVarargs
348    public final  <E> T groupBy(LambdaGetter<E>... columns) {
349        queryWrapper().groupBy(columns);
350        return (T) this;
351    }
352
353    public T having(QueryCondition queryCondition) {
354        queryWrapper().having(queryCondition);
355        return (T) this;
356    }
357
358    public T orderBy(QueryOrderBy... orderBys) {
359        queryWrapper().orderBy(orderBys);
360        return (T) this;
361    }
362
363    public T orderBy(QueryColumn column, Boolean asc) {
364        queryWrapper().orderBy(column, asc);
365        return (T) this;
366    }
367
368    public T orderBy(String... orderBys) {
369        queryWrapper().orderBy(orderBys);
370        return (T) this;
371    }
372
373    public T orderBy(String column, Boolean asc) {
374        queryWrapper().orderBy(column, asc);
375        return (T) this;
376    }
377
378    public <E> OrderByBuilder<T> orderBy(LambdaGetter<E> column) {
379        return new OrderByBuilder<>((T) this, column);
380    }
381
382    public <E> T orderBy(LambdaGetter<E> column, Boolean asc) {
383        queryWrapper().orderBy(column, asc);
384        return (T) this;
385    }
386
387    public T limit(Number rows) {
388        queryWrapper().limit(rows);
389        return (T) this;
390    }
391
392    public T offset(Number offset) {
393        queryWrapper().offset(offset);
394        return (T) this;
395    }
396
397    public T limit(Number offset, Number rows) {
398        queryWrapper().limit(offset, rows);
399        return (T) this;
400    }
401
402    protected JoinBuilder<T> joins(String type, QueryTable table, boolean when) {
403        Join join = new Join(type, table, when);
404        CPI.addJoin(queryWrapper(), join);
405        return new JoinBuilder<>((T) this, join);
406    }
407
408    protected JoinBuilder<T> joins(String type, Class<?> entityClass, boolean when) {
409        TableInfo tableInfo = TableInfoFactory.ofEntityClass(entityClass);
410        QueryTable queryTable = new QueryTable(tableInfo.getSchema(), tableInfo.getTableName());
411        return joins(type, queryTable, when);
412    }
413
414    protected JoinBuilder<T> joins(String type, QueryWrapper queryWrapper, boolean when) {
415        Join join = new Join(type, queryWrapper, when);
416        CPI.addJoin(queryWrapper(), join);
417        return new JoinBuilder<>((T) this, join);
418    }
419
420}