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