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.dialect.IDialect; 020import com.mybatisflex.core.table.TableDef; 021import com.mybatisflex.core.util.*; 022 023import java.io.Serializable; 024import java.util.Collection; 025import java.util.List; 026import java.util.function.Predicate; 027 028/** 029 * 查询列,描述的是一张表的字段 030 */ 031public class QueryColumn implements Serializable { 032 033 protected QueryTable table; 034 protected String name; 035 protected String alias; 036 037 038 public QueryColumn() { 039 } 040 041 public QueryColumn(String name) { 042 SqlUtil.keepColumnSafely(name); 043 this.name = name; 044 } 045 046 public QueryColumn(String schema, String tableName, String name) { 047 SqlUtil.keepColumnSafely(name); 048 this.table = new QueryTable(schema, tableName); 049 this.name = name; 050 } 051 052 public QueryColumn(TableDef tableDef, String name) { 053 SqlUtil.keepColumnSafely(name); 054 this.table = new QueryTable(tableDef); 055 this.name = name; 056 } 057 058 public QueryColumn(QueryTable queryTable, String name) { 059 SqlUtil.keepColumnSafely(name); 060 this.table = queryTable; 061 this.name = name; 062 } 063 064 065 public QueryTable getTable() { 066 return table; 067 } 068 069 public void setTable(QueryTable table) { 070 this.table = table; 071 } 072 073 public String getName() { 074 return name; 075 } 076 077 public void setName(String name) { 078 this.name = name; 079 } 080 081 public String getAlias() { 082 return alias; 083 } 084 085 public void setAlias(String alias) { 086 this.alias = alias; 087 } 088 089 public <T> QueryColumn as(LambdaGetter<T> fn) { 090 return as(LambdaUtil.getFieldName(fn)); 091 } 092 093 public QueryColumn as(String alias) { 094 SqlUtil.keepColumnSafely(alias); 095 QueryColumn newColumn = new QueryColumn(); 096 newColumn.table = this.table; 097 newColumn.name = this.name; 098 newColumn.alias = alias; 099 return newColumn; 100 } 101 102 103 // query methods /////// 104 105 /** 106 * equals 107 * 108 * @param value 109 */ 110 public QueryCondition eq(Object value) { 111 if (value == null) { 112 return QueryCondition.createEmpty(); 113 } 114 return QueryCondition.create(this, QueryCondition.LOGIC_EQUALS, value); 115 } 116 117 118 public <T> QueryCondition eq(Object value, Predicate<T> fn) { 119 if (value == null) { 120 return QueryCondition.createEmpty(); 121 } 122 return QueryCondition.create(this, QueryCondition.LOGIC_EQUALS, value).when(fn); 123 } 124 125 126 /** 127 * not equals != 128 * 129 * @param value 130 */ 131 public QueryCondition ne(Object value) { 132 if (value == null) { 133 return QueryCondition.createEmpty(); 134 } 135 return QueryCondition.create(this, QueryCondition.LOGIC_NOT_EQUALS, value); 136 } 137 138 public <T> QueryCondition ne(Object value, Predicate<T> fn) { 139 if (value == null) { 140 return QueryCondition.createEmpty(); 141 } 142 return QueryCondition.create(this, QueryCondition.LOGIC_NOT_EQUALS, value).when(fn); 143 } 144 145 146 /** 147 * like %% 148 * 149 * @param value 150 */ 151 public QueryCondition like(Object value) { 152 if (value == null) { 153 return QueryCondition.createEmpty(); 154 } 155 return QueryCondition.create(this, QueryCondition.LOGIC_LIKE, "%" + value + "%"); 156 } 157 158 public <T> QueryCondition like(Object value, Predicate<T> fn) { 159 if (value == null) { 160 return QueryCondition.createEmpty(); 161 } 162 return QueryCondition.create(this, QueryCondition.LOGIC_LIKE, "%" + value + "%").when(fn); 163 } 164 165 166 public QueryCondition likeLeft(Object value) { 167 if (value == null) { 168 return QueryCondition.createEmpty(); 169 } 170 return QueryCondition.create(this, QueryCondition.LOGIC_LIKE, "%" + value); 171 } 172 173 public <T> QueryCondition likeLeft(Object value, Predicate<T> fn) { 174 if (value == null) { 175 return QueryCondition.createEmpty(); 176 } 177 return QueryCondition.create(this, QueryCondition.LOGIC_LIKE, "%" + value).when(fn); 178 } 179 180 181 public QueryCondition likeRight(Object value) { 182 if (value == null) { 183 return QueryCondition.createEmpty(); 184 } 185 return QueryCondition.create(this, QueryCondition.LOGIC_LIKE, value + "%"); 186 } 187 188 public <T> QueryCondition likeRight(Object value, Predicate<T> fn) { 189 if (value == null) { 190 return QueryCondition.createEmpty(); 191 } 192 return QueryCondition.create(this, QueryCondition.LOGIC_LIKE, value + "%").when(fn); 193 } 194 195 /** 196 * 大于 greater than 197 * 198 * @param value 199 */ 200 public QueryCondition gt(Object value) { 201 if (value == null) { 202 return QueryCondition.createEmpty(); 203 } 204 return QueryCondition.create(this, QueryCondition.LOGIC_GT, value); 205 } 206 207 public <T> QueryCondition gt(Object value, Predicate<T> fn) { 208 if (value == null) { 209 return QueryCondition.createEmpty(); 210 } 211 return QueryCondition.create(this, QueryCondition.LOGIC_GT, value).when(fn); 212 } 213 214 /** 215 * 大于等于 greater or equal 216 * 217 * @param value 218 */ 219 public QueryCondition ge(Object value) { 220 if (value == null) { 221 return QueryCondition.createEmpty(); 222 } 223 return QueryCondition.create(this, QueryCondition.LOGIC_GE, value); 224 } 225 226 public <T> QueryCondition ge(Object value, Predicate<T> fn) { 227 if (value == null) { 228 return QueryCondition.createEmpty(); 229 } 230 return QueryCondition.create(this, QueryCondition.LOGIC_GE, value).when(fn); 231 } 232 233 /** 234 * 小于 less than 235 * 236 * @param value 237 */ 238 public QueryCondition lt(Object value) { 239 if (value == null) { 240 return QueryCondition.createEmpty(); 241 } 242 return QueryCondition.create(this, QueryCondition.LOGIC_LT, value); 243 } 244 245 public <T> QueryCondition lt(Object value, Predicate<T> fn) { 246 if (value == null) { 247 return QueryCondition.createEmpty(); 248 } 249 return QueryCondition.create(this, QueryCondition.LOGIC_LT, value).when(fn); 250 } 251 252 /** 253 * 小于等于 less or equal 254 * 255 * @param value 256 */ 257 public QueryCondition le(Object value) { 258 if (value == null) { 259 return QueryCondition.createEmpty(); 260 } 261 return QueryCondition.create(this, QueryCondition.LOGIC_LE, value); 262 } 263 264 public <T> QueryCondition le(Object value, Predicate<T> fn) { 265 if (value == null) { 266 return QueryCondition.createEmpty(); 267 } 268 return QueryCondition.create(this, QueryCondition.LOGIC_LE, value).when(fn); 269 } 270 271 272 /** 273 * IS NULL 274 * 275 * @return 276 */ 277 public QueryCondition isNull() { 278 return QueryCondition.create(this, QueryCondition.LOGIC_IS_NULL, null); 279 } 280 281 public <T> QueryCondition isNull(Predicate<T> fn) { 282 return QueryCondition.create(this, QueryCondition.LOGIC_IS_NULL, null).when(fn); 283 } 284 285 286 /** 287 * IS NOT NULL 288 * 289 * @return 290 */ 291 public QueryCondition isNotNull() { 292 return QueryCondition.create(this, QueryCondition.LOGIC_IS_NOT_NULL, null); 293 } 294 295 public <T> QueryCondition isNotNull(Predicate<T> fn) { 296 return QueryCondition.create(this, QueryCondition.LOGIC_IS_NOT_NULL, null).when(fn); 297 } 298 299 300 /** 301 * in arrays 302 * 303 * @param arrays 304 * @return 305 */ 306 public QueryCondition in(Object... arrays) { 307 //忽略 QueryWrapper.in("name", null) 的情况 308 if (arrays == null || arrays.length == 0 || (arrays.length == 1 && arrays[0] == null)) { 309 return QueryCondition.createEmpty(); 310 } 311 return QueryCondition.create(this, QueryCondition.LOGIC_IN, arrays); 312 } 313 314 public <T> QueryCondition in(Object[] arrays, Predicate<T> fn) { 315 //忽略 QueryWrapper.in("name", null) 的情况 316 if (arrays == null || arrays.length == 0 || (arrays.length == 1 && arrays[0] == null)) { 317 return QueryCondition.createEmpty(); 318 } 319 return QueryCondition.create(this, QueryCondition.LOGIC_IN, arrays).when(fn); 320 } 321 322 /** 323 * in child select 324 * 325 * @param queryWrapper 326 * @return 327 */ 328 public QueryCondition in(QueryWrapper queryWrapper) { 329 return QueryCondition.create(this, QueryCondition.LOGIC_IN, queryWrapper); 330 } 331 332 public <T> QueryCondition in(QueryWrapper queryWrapper, Predicate<T> fn) { 333 return QueryCondition.create(this, QueryCondition.LOGIC_IN, queryWrapper).when(fn); 334 } 335 336 337 /** 338 * in Collection 339 * 340 * @param collection 341 * @return 342 */ 343 public QueryCondition in(Collection<?> collection) { 344 if (collection != null && !collection.isEmpty()) { 345 return in(collection.toArray()); 346 } 347 return QueryCondition.createEmpty(); 348 } 349 350 public <T> QueryCondition in(Collection<?> collection, Predicate<T> fn) { 351 if (collection != null && !collection.isEmpty()) { 352 return in(collection.toArray(), fn); 353 } 354 return QueryCondition.createEmpty(); 355 } 356 357 /** 358 * not int arrays 359 * 360 * @param arrays 361 * @return 362 */ 363 public QueryCondition notIn(Object... arrays) { 364 //忽略 QueryWrapper.notIn("name", null) 的情况 365 if (arrays == null || arrays.length == 0 || (arrays.length == 1 && arrays[0] == null)) { 366 return QueryCondition.createEmpty(); 367 } 368 return QueryCondition.create(this, QueryCondition.LOGIC_NOT_IN, arrays); 369 } 370 371 public <T> QueryCondition notIn(Object[] arrays, Predicate<T> fn) { 372 //忽略 QueryWrapper.notIn("name", null) 的情况 373 if (arrays == null || arrays.length == 0 || (arrays.length == 1 && arrays[0] == null)) { 374 return QueryCondition.createEmpty(); 375 } 376 return QueryCondition.create(this, QueryCondition.LOGIC_NOT_IN, arrays).when(fn); 377 } 378 379 380 /** 381 * not in Collection 382 * 383 * @param collection 384 * @return 385 */ 386 public QueryCondition notIn(Collection<?> collection) { 387 if (collection != null && !collection.isEmpty()) { 388 return notIn(collection.toArray()); 389 } 390 return QueryCondition.createEmpty(); 391 } 392 393 public <T> QueryCondition notIn(Collection<?> collection, Predicate<T> fn) { 394 if (collection != null && !collection.isEmpty()) { 395 return notIn(collection.toArray(), fn); 396 } 397 return QueryCondition.createEmpty(); 398 } 399 400 /** 401 * not in child select 402 * 403 * @param queryWrapper 404 */ 405 public QueryCondition notIn(QueryWrapper queryWrapper) { 406 return QueryCondition.create(this, QueryCondition.LOGIC_NOT_IN, queryWrapper); 407 } 408 409 public <T> QueryCondition notIn(QueryWrapper queryWrapper, Predicate<T> fn) { 410 return QueryCondition.create(this, QueryCondition.LOGIC_NOT_IN, queryWrapper).when(fn); 411 } 412 413 414 /** 415 * between 416 * 417 * @param start 418 * @param end 419 */ 420 public QueryCondition between(Object start, Object end) { 421 return QueryCondition.create(this, QueryCondition.LOGIC_BETWEEN, new Object[]{start, end}); 422 } 423 424 public <T> QueryCondition between(Object start, Object end, Predicate<T> fn) { 425 return QueryCondition.create(this, QueryCondition.LOGIC_BETWEEN, new Object[]{start, end}).when(fn); 426 } 427 428 429 /** 430 * not between 431 * 432 * @param start 433 * @param end 434 */ 435 public QueryCondition notBetween(Object start, Object end) { 436 return QueryCondition.create(this, QueryCondition.LOGIC_NOT_BETWEEN, new Object[]{start, end}); 437 } 438 439 public <T> QueryCondition notBetween(Object start, Object end, Predicate<T> fn) { 440 return QueryCondition.create(this, QueryCondition.LOGIC_NOT_BETWEEN, new Object[]{start, end}).when(fn); 441 } 442 443 444 ////order by //// 445 public QueryOrderBy asc() { 446 return new QueryOrderBy(this); 447 } 448 449 450 public QueryOrderBy desc() { 451 return new QueryOrderBy(this, "DESC"); 452 } 453 454 455 // 运算 加减乘除 + - * / 456 public QueryColumn add(QueryColumn queryColumn) { 457 return new ArithmeticQueryColumn(this).add(queryColumn); 458 } 459 460 public QueryColumn add(Number number) { 461 return new ArithmeticQueryColumn(this).add(number); 462 } 463 464 public QueryColumn subtract(QueryColumn queryColumn) { 465 return new ArithmeticQueryColumn(this).subtract(queryColumn); 466 } 467 468 public QueryColumn subtract(Number number) { 469 return new ArithmeticQueryColumn(this).subtract(number); 470 } 471 472 public QueryColumn multiply(QueryColumn queryColumn) { 473 return new ArithmeticQueryColumn(this).multiply(queryColumn); 474 } 475 476 public QueryColumn multiply(Number number) { 477 return new ArithmeticQueryColumn(this).multiply(number); 478 } 479 480 public QueryColumn divide(QueryColumn queryColumn) { 481 return new ArithmeticQueryColumn(this).divide(queryColumn); 482 } 483 484 public QueryColumn divide(Number number) { 485 return new ArithmeticQueryColumn(this).divide(number); 486 } 487 488 489 String toConditionSql(List<QueryTable> queryTables, IDialect dialect) { 490 QueryTable selectTable = getSelectTable(queryTables, table); 491 if (selectTable == null) { 492 return dialect.wrap(name); 493 } else { 494 if (StringUtil.isNotBlank(selectTable.alias)) { 495 return dialect.wrap(selectTable.alias) + "." + dialect.wrap(name); 496 } else if (StringUtil.isNotBlank(selectTable.getSchema()) && StringUtil.isNotBlank(selectTable.getName())) { 497 return dialect.wrap(dialect.getRealSchema(selectTable.schema)) + "." + dialect.wrap(dialect.getRealTable(selectTable.getName())) + "." + dialect.wrap(name); 498 } else if (StringUtil.isNotBlank(selectTable.getName())) { 499 return dialect.wrap(dialect.getRealTable(selectTable.getName())) + "." + dialect.wrap(name); 500 } else { 501 return dialect.wrap(name); 502 } 503 } 504 } 505 506 507 String toSelectSql(List<QueryTable> queryTables, IDialect dialect) { 508 return toConditionSql(queryTables, dialect) + WrapperUtil.buildAsAlias(alias, dialect); 509 } 510 511 512 QueryTable getSelectTable(List<QueryTable> queryTables, QueryTable columnTable) { 513 if (queryTables == null || queryTables.isEmpty()) { 514 return null; 515 } 516 517 if (queryTables.size() == 1 && queryTables.get(0).isSameTable(columnTable)) { 518 //ignore table 519 return null; 520 } 521 522 if (CollectionUtil.isEmpty(queryTables)) { 523 return columnTable; 524 } 525 526 if (columnTable == null && queryTables.size() == 1) { 527 return queryTables.get(0); 528 } 529 530 for (QueryTable table : queryTables) { 531 if (table.isSameTable(columnTable)) { 532 return table; 533 } 534 } 535 return columnTable; 536 } 537 538 539 @Override 540 public String toString() { 541 return "QueryColumn{" + 542 "table=" + table + 543 ", name='" + name + '\'' + 544 ", alias='" + alias + '\'' + 545 '}'; 546 } 547 548 549}