001/** 002 * Copyright (c) 2015-2022, Michael Yang 杨福海 (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 io.jboot.service; 017 018import com.jfinal.kit.StrKit; 019import com.jfinal.plugin.activerecord.Page; 020import com.jfinal.plugin.activerecord.Record; 021import io.jboot.db.JbootDb; 022import io.jboot.db.model.Columns; 023import io.jboot.db.model.JbootModel; 024import io.jboot.utils.ArrayUtil; 025import io.jboot.utils.ObjectFunc; 026import io.jboot.utils.StrUtil; 027 028import java.util.ArrayList; 029import java.util.List; 030 031 032public abstract class JbootServiceJoinerImpl implements JbootServiceJoiner { 033 034 035 @Override 036 public <M extends JbootModel> Page<M> join(Page<M> page, String columnName) { 037 join(page.getList(), columnName); 038 return page; 039 } 040 041 @Override 042 public <M extends JbootModel> Page<M> join(Page<M> page, String columnName, String[] attrs) { 043 join(page.getList(), columnName, attrs); 044 return page; 045 } 046 047 048 @Override 049 public <M extends JbootModel> Page<M> join(Page<M> page, String columnName, String joinName) { 050 join(page.getList(), columnName, joinName); 051 return page; 052 } 053 054 055 @Override 056 public <M extends JbootModel> Page<M> join(Page<M> page, String columnName, String joinName, String[] attrs) { 057 join(page.getList(), columnName, joinName, attrs); 058 return page; 059 } 060 061 062 @Override 063 public <M extends JbootModel> List<M> join(List<M> models, String columnName) { 064 if (ArrayUtil.isNotEmpty(models)) { 065 for (JbootModel m : models) { 066 join(m, columnName); 067 } 068 } 069 return models; 070 } 071 072 073 @Override 074 public <M extends JbootModel> List<M> join(List<M> models, String columnName, String[] attrs) { 075 if (ArrayUtil.isNotEmpty(models)) { 076 for (JbootModel m : models) { 077 join(m, columnName, attrs); 078 } 079 } 080 return models; 081 } 082 083 084 @Override 085 public <M extends JbootModel> List<M> join(List<M> models, String columnName, String joinName) { 086 if (ArrayUtil.isNotEmpty(models)) { 087 for (JbootModel m : models) { 088 join(m, columnName, joinName); 089 } 090 } 091 return models; 092 } 093 094 095 @Override 096 public <M extends JbootModel> List<M> join(List<M> models, String columnName, String joinName, String[] attrs) { 097 if (ArrayUtil.isNotEmpty(models)) { 098 for (JbootModel m : models) { 099 join(m, columnName, joinName, attrs); 100 } 101 } 102 return models; 103 } 104 105 106 /** 107 * 添加关联数据到某个model中去,避免关联查询,提高性能。 108 * 109 * @param model 要添加到的model 110 * @param columnName model对于的关联字段 111 */ 112 @Override 113 public <M extends JbootModel> M join(M model, String columnName) { 114 return join(model, columnName, null, null); 115 } 116 117 /** 118 * 添加关联数据到某个model中去,避免关联查询,提高性能。 119 * 120 * @param model 121 * @param columnName 122 * @param attrs 123 */ 124 @Override 125 public <M extends JbootModel> M join(M model, String columnName, String[] attrs) { 126 return join(model, columnName, null, attrs); 127 } 128 129 130 /** 131 * 添加关联数据到某个model中去,避免关联查询,提高性能。 132 * 133 * @param model 134 * @param columnName 135 * @param joinName 136 */ 137 @Override 138 public <M extends JbootModel> M join(M model, String columnName, String joinName) { 139 return join(model, columnName, joinName, null); 140 } 141 142 143 /** 144 * 添加关联数据到某个model中去,避免关联查询,提高性能。 145 * 146 * @param model 147 * @param columnName 148 * @param joinName 149 * @param attrs 150 */ 151 @Override 152 public <M extends JbootModel> M join(M model, String columnName, String joinName, String[] attrs) { 153 if (model == null) { 154 return null; 155 } 156 Object value = model.get(columnName); 157 if (value == null) { 158 return model; 159 } 160 JbootModel m = joinByValue(value, model); 161 if (m != null) { 162 joinName = StrUtil.isNotBlank(joinName) ? joinName : StrKit.firstCharToLowerCase(m.getClass().getSimpleName()); 163 model.put(joinName, ArrayUtil.isNotEmpty(attrs) ? m.copy().keep(attrs) : m); 164 } 165 return model; 166 } 167 168 169 /** 170 * 可以让子类去复写 joinByColumnValue ,比如默认只 join 部分字段等,或者不是根据主键进行查询等 171 * 一般情况下,传入的 columnValue 是主键的值,但是也有可能不是,要看场景,如果不是的情况下可以通过 sourceModel 来进行判断 172 * 173 * @param columnValue 174 * @return 175 */ 176 protected abstract JbootModel joinByValue(Object columnValue, JbootModel sourceModel); 177 178 179/////////////////joinMany start///////////////////////////// 180 181 182 @Override 183 public <M extends JbootModel> Page<M> joinMany(Page<M> page, String targetColumnName) { 184 joinMany(page.getList(), targetColumnName); 185 return page; 186 } 187 188 @Override 189 public <M extends JbootModel> Page<M> joinMany(Page<M> page, String targetColumnName, String[] attrs) { 190 joinMany(page.getList(), targetColumnName, attrs); 191 return page; 192 } 193 194 195 @Override 196 public <M extends JbootModel> Page<M> joinMany(Page<M> page, String targetColumnName, String joinName) { 197 joinMany(page.getList(), targetColumnName, joinName); 198 return page; 199 } 200 201 202 @Override 203 public <M extends JbootModel> Page<M> joinMany(Page<M> page, String targetColumnName, String joinName, String[] attrs) { 204 joinMany(page.getList(), targetColumnName, joinName, attrs); 205 return page; 206 } 207 208 209 @Override 210 public <M extends JbootModel> List<M> joinMany(List<M> models, String targetColumnName) { 211 if (ArrayUtil.isNotEmpty(models)) { 212 for (M m : models) { 213 joinMany(m, targetColumnName); 214 } 215 } 216 return models; 217 } 218 219 220 @Override 221 public <M extends JbootModel> List<M> joinMany(List<M> models, String targetColumnName, String[] attrs) { 222 if (ArrayUtil.isNotEmpty(models)) { 223 for (M m : models) { 224 joinMany(m, targetColumnName, attrs); 225 } 226 } 227 return models; 228 } 229 230 231 @Override 232 public <M extends JbootModel> List<M> joinMany(List<M> models, String targetColumnName, String joinName) { 233 if (ArrayUtil.isNotEmpty(models)) { 234 for (M m : models) { 235 joinMany(m, targetColumnName, joinName); 236 } 237 } 238 return models; 239 } 240 241 242 @Override 243 public <M extends JbootModel> List<M> joinMany(List<M> models, String targetColumnName, String joinName, String[] attrs) { 244 if (ArrayUtil.isNotEmpty(models)) { 245 for (M m : models) { 246 joinMany(m, targetColumnName, joinName, attrs); 247 } 248 } 249 return models; 250 } 251 252 253 @Override 254 public <M extends JbootModel> M joinMany(M model, String targetColumnName) { 255 return joinMany(model, null, targetColumnName, null, null); 256 } 257 258 @Override 259 public <M extends JbootModel> M joinMany(M model, String targetColumnName, String[] attrs) { 260 return joinMany(model, null, targetColumnName, null, attrs); 261 } 262 263 @Override 264 public <M extends JbootModel> M joinMany(M model, String targetColumnName, String joinName) { 265 return joinMany(model, null, targetColumnName, joinName, null); 266 } 267 268 269 @Override 270 public <M extends JbootModel> M joinMany(M model, String targetColumnName, String joinName, String[] attrs) { 271 return joinMany(model, null, targetColumnName, joinName, attrs); 272 } 273 274 275 @Override 276 public <M extends JbootModel> Page<M> joinMany(Page<M> page, ObjectFunc<M> modelValueGetter, String targetColumnName) { 277 joinMany(page.getList(), modelValueGetter, targetColumnName); 278 return page; 279 } 280 281 @Override 282 public <M extends JbootModel> Page<M> joinMany(Page<M> page, ObjectFunc<M> modelValueGetter, String targetColumnName, String[] attrs) { 283 joinMany(page.getList(), modelValueGetter, targetColumnName, attrs); 284 return page; 285 } 286 287 288 @Override 289 public <M extends JbootModel> Page<M> joinMany(Page<M> page, ObjectFunc<M> modelValueGetter, String targetColumnName, String joinName) { 290 joinMany(page.getList(), modelValueGetter, targetColumnName, joinName); 291 return page; 292 } 293 294 295 @Override 296 public <M extends JbootModel> Page<M> joinMany(Page<M> page, ObjectFunc<M> modelValueGetter, String targetColumnName, String joinName, String[] attrs) { 297 joinMany(page.getList(), modelValueGetter, targetColumnName, joinName, attrs); 298 return page; 299 } 300 301 302 @Override 303 public <M extends JbootModel> List<M> joinMany(List<M> models, ObjectFunc<M> modelValueGetter, String targetColumnName) { 304 if (ArrayUtil.isNotEmpty(models)) { 305 for (M m : models) { 306 joinMany(m, modelValueGetter, targetColumnName); 307 } 308 } 309 return models; 310 } 311 312 313 @Override 314 public <M extends JbootModel> List<M> joinMany(List<M> models, ObjectFunc<M> modelValueGetter, String targetColumnName, String[] attrs) { 315 if (ArrayUtil.isNotEmpty(models)) { 316 for (M m : models) { 317 joinMany(m, modelValueGetter, targetColumnName, attrs); 318 } 319 } 320 return models; 321 } 322 323 324 @Override 325 public <M extends JbootModel> List<M> joinMany(List<M> models, ObjectFunc<M> modelValueGetter, String targetColumnName, String joinName) { 326 if (ArrayUtil.isNotEmpty(models)) { 327 for (M m : models) { 328 joinMany(m, modelValueGetter, targetColumnName, joinName); 329 } 330 } 331 return models; 332 } 333 334 335 @Override 336 public <M extends JbootModel> List<M> joinMany(List<M> models, ObjectFunc<M> modelValueGetter, String targetColumnName, String joinName, String[] attrs) { 337 if (ArrayUtil.isNotEmpty(models)) { 338 for (M m : models) { 339 joinMany(m, modelValueGetter, targetColumnName, joinName, attrs); 340 } 341 } 342 return models; 343 } 344 345 346 @Override 347 public <M extends JbootModel> M joinMany(M model, ObjectFunc<M> modelValueGetter, String targetColumnName) { 348 return joinMany(model, modelValueGetter, targetColumnName, null, null); 349 } 350 351 @Override 352 public <M extends JbootModel> M joinMany(M model, ObjectFunc<M> modelValueGetter, String targetColumnName, String[] attrs) { 353 return joinMany(model, modelValueGetter, targetColumnName, null, attrs); 354 } 355 356 357 @Override 358 public <M extends JbootModel> M joinMany(M model, ObjectFunc<M> modelValueGetter, String targetColumnName, String joinName) { 359 return joinMany(model, modelValueGetter, targetColumnName, joinName, null); 360 } 361 362 363 @Override 364 public <M extends JbootModel> M joinMany(M model, ObjectFunc<M> modelValueGetter, String targetColumnName, String joinName, String[] attrs) { 365 if (model == null) { 366 return null; 367 } 368 Object value = modelValueGetter != null ? modelValueGetter.get(model) : model._getIdValue(); 369 if (value == null) { 370 return model; 371 } 372 373 List<M> list = joinManyByValue(targetColumnName, value, model); 374 if (list != null && !list.isEmpty()) { 375 joinName = StrUtil.isNotBlank(joinName) ? joinName : StrKit.firstCharToLowerCase(list.get(0).getClass().getSimpleName()) + "List"; 376 model.put(joinName, ArrayUtil.isNotEmpty(attrs) ? keepModelListAttrs(list, attrs) : list); 377 } 378 379 return model; 380 } 381 382 383 protected <M extends JbootModel> List<M> keepModelListAttrs(List<M> list, String[] attrs) { 384 if (list == null || list.isEmpty()) { 385 return null; 386 } 387 List<M> retList = new ArrayList<>(list.size()); 388 for (M model : list) { 389 retList.add((M) model.copy().keep(attrs)); 390 } 391 return retList; 392 } 393 394 395 protected abstract <M extends JbootModel> List<M> joinManyByValue(String columnName, Object value, M sourceModel); 396 397 398/////////////////joinMany end///////////////////////////// 399 400 401/////////////////joinManyByTable start///////////////////////////// 402 403 @Override 404 public <M extends JbootModel> Page<M> joinManyByTable(Page<M> page, String tableName, String columnName, String targetColumnName) { 405 joinManyByTable(page.getList(), tableName, columnName, targetColumnName); 406 return page; 407 } 408 409 @Override 410 public <M extends JbootModel> Page<M> joinManyByTable(Page<M> page, String tableName, String columnName, String targetColumnName, String[] attrs) { 411 joinManyByTable(page.getList(), tableName, columnName, targetColumnName, attrs); 412 return page; 413 } 414 415 @Override 416 public <M extends JbootModel> Page<M> joinManyByTable(Page<M> page, String tableName, String columnName, String targetColumnName, String joinName) { 417 joinManyByTable(page.getList(), tableName, columnName, targetColumnName, joinName); 418 return page; 419 } 420 421 422 @Override 423 public <M extends JbootModel> Page<M> joinManyByTable(Page<M> page, String tableName, String columnName, String targetColumnName, String joinName, String[] attrs) { 424 joinManyByTable(page.getList(), tableName, columnName, targetColumnName, joinName, attrs); 425 return page; 426 } 427 428 429 @Override 430 public <M extends JbootModel> List<M> joinManyByTable(List<M> models, String tableName, String columnName, String targetColumnName) { 431 if (ArrayUtil.isNotEmpty(models)) { 432 for (M m : models) { 433 joinManyByTable(m, tableName, columnName, targetColumnName); 434 } 435 } 436 return models; 437 } 438 439 @Override 440 public <M extends JbootModel> List<M> joinManyByTable(List<M> models, String tableName, String columnName, String targetColumnName, String[] attrs) { 441 if (ArrayUtil.isNotEmpty(models)) { 442 for (M m : models) { 443 joinManyByTable(m, tableName, columnName, targetColumnName, attrs); 444 } 445 } 446 return models; 447 } 448 449 @Override 450 public <M extends JbootModel> List<M> joinManyByTable(List<M> models, String tableName, String columnName, String targetColumnName, String joinName) { 451 if (ArrayUtil.isNotEmpty(models)) { 452 for (M m : models) { 453 joinManyByTable(m, tableName, columnName, targetColumnName, joinName); 454 } 455 } 456 return models; 457 } 458 459 460 @Override 461 public <M extends JbootModel> List<M> joinManyByTable(List<M> models, String tableName, String columnName, String targetColumnName, String joinName, String[] attrs) { 462 if (ArrayUtil.isNotEmpty(models)) { 463 for (M m : models) { 464 joinManyByTable(m, tableName, columnName, targetColumnName, joinName, attrs); 465 } 466 } 467 return models; 468 } 469 470 471 @Override 472 public <M extends JbootModel> M joinManyByTable(M model, String tableName, String columnName, String targetColumnName) { 473 return joinManyByTable(model, tableName, columnName, targetColumnName, null, null); 474 } 475 476 @Override 477 public <M extends JbootModel> M joinManyByTable(M model, String tableName, String columnName, String targetColumnName, String[] attrs) { 478 return joinManyByTable(model, tableName, columnName, targetColumnName, null, attrs); 479 } 480 481 @Override 482 public <M extends JbootModel> M joinManyByTable(M model, String tableName, String columnName, String targetColumnName, String joinName) { 483 return joinManyByTable(model, tableName, columnName, targetColumnName, joinName, null); 484 } 485 486 @Override 487 public <M extends JbootModel> M joinManyByTable(M model, String tableName, String columnName, String targetColumnName, String joinName, String[] attrs) { 488 return joinManyByTable(model, null, tableName, columnName, targetColumnName, joinName, attrs); 489 } 490 491 492 @Override 493 public <M extends JbootModel> Page<M> joinManyByTable(Page<M> page, ObjectFunc<M> modelValueGetter, String tableName, String columnName, String targetColumnName) { 494 joinManyByTable(page.getList(), modelValueGetter, tableName, columnName, targetColumnName); 495 return page; 496 } 497 498 @Override 499 public <M extends JbootModel> Page<M> joinManyByTable(Page<M> page, ObjectFunc<M> modelValueGetter, String tableName, String columnName, String targetColumnName, String[] attrs) { 500 joinManyByTable(page.getList(), modelValueGetter, tableName, columnName, targetColumnName, attrs); 501 return page; 502 } 503 504 @Override 505 public <M extends JbootModel> Page<M> joinManyByTable(Page<M> page, ObjectFunc<M> modelValueGetter, String tableName, String columnName, String targetColumnName, String joinName) { 506 joinManyByTable(page.getList(), modelValueGetter, tableName, columnName, targetColumnName, joinName); 507 return page; 508 } 509 510 511 @Override 512 public <M extends JbootModel> Page<M> joinManyByTable(Page<M> page, ObjectFunc<M> modelValueGetter, String tableName, String columnName, String targetColumnName, String joinName, String[] attrs) { 513 joinManyByTable(page.getList(), modelValueGetter, tableName, columnName, targetColumnName, joinName, attrs); 514 return page; 515 } 516 517 518 @Override 519 public <M extends JbootModel> List<M> joinManyByTable(List<M> models, ObjectFunc<M> modelValueGetter, String tableName, String columnName, String targetColumnName) { 520 if (ArrayUtil.isNotEmpty(models)) { 521 for (M m : models) { 522 joinManyByTable(m, modelValueGetter, tableName, columnName, targetColumnName); 523 } 524 } 525 return models; 526 } 527 528 @Override 529 public <M extends JbootModel> List<M> joinManyByTable(List<M> models, ObjectFunc<M> modelValueGetter, String tableName, String columnName, String targetColumnName, String[] attrs) { 530 if (ArrayUtil.isNotEmpty(models)) { 531 for (M m : models) { 532 joinManyByTable(m, modelValueGetter, tableName, columnName, targetColumnName, attrs); 533 } 534 } 535 return models; 536 } 537 538 @Override 539 public <M extends JbootModel> List<M> joinManyByTable(List<M> models, ObjectFunc<M> modelValueGetter, String tableName, String columnName, String targetColumnName, String joinName) { 540 if (ArrayUtil.isNotEmpty(models)) { 541 for (M m : models) { 542 joinManyByTable(m, modelValueGetter, tableName, columnName, targetColumnName, joinName); 543 } 544 } 545 return models; 546 } 547 548 549 @Override 550 public <M extends JbootModel> List<M> joinManyByTable(List<M> models, ObjectFunc<M> modelValueGetter, String tableName, String columnName, String targetColumnName, String joinName, String[] attrs) { 551 if (ArrayUtil.isNotEmpty(models)) { 552 for (M m : models) { 553 joinManyByTable(m, modelValueGetter, tableName, columnName, targetColumnName, joinName, attrs); 554 } 555 } 556 return models; 557 } 558 559 560 @Override 561 public <M extends JbootModel> M joinManyByTable(M model, ObjectFunc<M> modelValueGetter, String tableName, String columnName, String targetColumnName) { 562 return joinManyByTable(model, modelValueGetter, tableName, columnName, targetColumnName, null, null); 563 } 564 565 @Override 566 public <M extends JbootModel> M joinManyByTable(M model, ObjectFunc<M> modelValueGetter, String tableName, String columnName, String targetColumnName, String[] attrs) { 567 return joinManyByTable(model, modelValueGetter, tableName, columnName, targetColumnName, null, attrs); 568 } 569 570 @Override 571 public <M extends JbootModel> M joinManyByTable(M model, ObjectFunc<M> modelValueGetter, String tableName, String columnName, String targetColumnName, String joinName) { 572 return joinManyByTable(model, modelValueGetter, tableName, columnName, targetColumnName, joinName, null); 573 } 574 575 @Override 576 public <M extends JbootModel> M joinManyByTable(M model, ObjectFunc<M> modelValueGetter, String tableName, String columnName, String targetColumnName, String joinName, String[] attrs) { 577 if (model == null) { 578 return null; 579 } 580 581 Object columnValue = modelValueGetter != null ? modelValueGetter.get(model) : model._getIdValue(); 582 if (columnValue == null) { 583 return model; 584 } 585 586 List<Record> middleTableRecords = findMiddleTableRecords(tableName, columnName, columnValue); 587 if (middleTableRecords == null || middleTableRecords.isEmpty()) { 588 return model; 589 } 590 591 List<M> list = new ArrayList(); 592 for (Record record : middleTableRecords) { 593 Object targetTableValue = record.get(targetColumnName); 594 if (targetTableValue != null) { 595 M data = (M) joinByValue(targetTableValue, model); 596 if (data != null) { 597 list.add(data); 598 } 599 } 600 } 601 602 if (!list.isEmpty()) { 603 joinName = StrUtil.isNotBlank(joinName) ? joinName : StrKit.firstCharToLowerCase(list.get(0).getClass().getSimpleName()) + "List"; 604 model.put(joinName, ArrayUtil.isNotEmpty(attrs) ? keepModelListAttrs(list, attrs) : list); 605 } 606 607 return model; 608 } 609 610 611 /** 612 * 查询中间表数据,方便子类复写,比如:通过缓存获取等 613 * @param tableName 614 * @param columnName 615 * @param columnValue 616 * @return 617 */ 618 protected List<Record> findMiddleTableRecords(String tableName, String columnName, Object columnValue) { 619 return JbootDb.find(tableName, Columns.create(columnName, columnValue)); 620 } 621 622 623/////////////////joinManyByTable end///////////////////////////// 624 625}