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}