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.table; 017 018import com.mybatisflex.annotation.InsertListener; 019import com.mybatisflex.annotation.KeyType; 020import com.mybatisflex.annotation.SetListener; 021import com.mybatisflex.annotation.UpdateListener; 022import com.mybatisflex.core.FlexConsts; 023import com.mybatisflex.core.FlexGlobalConfig; 024import com.mybatisflex.core.exception.FlexExceptions; 025import com.mybatisflex.core.javassist.ModifyAttrsRecord; 026import com.mybatisflex.core.mybatis.TypeHandlerObject; 027import com.mybatisflex.core.query.*; 028import com.mybatisflex.core.row.Row; 029import com.mybatisflex.core.tenant.TenantManager; 030import com.mybatisflex.core.util.*; 031import org.apache.ibatis.mapping.ResultFlag; 032import org.apache.ibatis.mapping.ResultMap; 033import org.apache.ibatis.mapping.ResultMapping; 034import org.apache.ibatis.reflection.MetaObject; 035import org.apache.ibatis.reflection.Reflector; 036import org.apache.ibatis.reflection.ReflectorFactory; 037import org.apache.ibatis.session.Configuration; 038import org.apache.ibatis.type.TypeHandler; 039import org.apache.ibatis.util.MapUtil; 040 041import java.util.*; 042import java.util.concurrent.ConcurrentHashMap; 043import java.util.stream.Collectors; 044 045public class TableInfo { 046 047 private String schema; //schema 048 private String tableName; //表名 049 private Class<?> entityClass; //实体类 050 private boolean camelToUnderline = true; 051 private String dataSource; 052 053 //逻辑删除数据库列名 054 private String logicDeleteColumn; 055 056 //乐观锁字段 057 private String versionColumn; 058 059 //租户ID 字段 060 private String tenantIdColumn; 061 062 //数据插入时,默认插入数据字段 063 private Map<String, String> onInsertColumns; 064 065 //数据更新时,默认更新内容的字段 066 private Map<String, String> onUpdateColumns; 067 068 //大字段列 069 private String[] largeColumns = new String[0]; 070 071 // 所有的字段,但除了主键的列 072 private String[] columns = new String[0]; 073 074 //主键字段 075 private String[] primaryKeys = new String[0]; 076 077 // 默认查询列 078 private String[] defaultColumns = new String[0]; 079 080 //在插入数据的时候,支持主动插入的主键字段 081 //通过自定义生成器生成 或者 Sequence 在 before 生成的时候,是需要主动插入数据的 082 private String[] insertPrimaryKeys; 083 084 private List<ColumnInfo> columnInfoList; 085 private List<IdInfo> primaryKeyList; 086 087 //column 和 java 属性的称的关系映射 088 private Map<String, ColumnInfo> columnInfoMapping = new HashMap<>(); 089 private Map<String, String> propertyColumnMapping = new HashMap<>(); 090 091 private List<InsertListener> onInsertListeners; 092 private List<UpdateListener> onUpdateListeners; 093 private List<SetListener> onSetListeners; 094 095 096 private final ReflectorFactory reflectorFactory = new BaseReflectorFactory() { 097 @Override 098 public Reflector findForClass(Class<?> type) { 099 return getReflector(); 100 } 101 }; 102 private Reflector reflector; //反射工具 103 104 public String getSchema() { 105 return schema; 106 } 107 108 public void setSchema(String schema) { 109 this.schema = schema; 110 } 111 112 public String getTableName() { 113 return tableName; 114 } 115 116 public void setTableName(String tableName) { 117 this.tableName = tableName; 118 } 119 120 public Class<?> getEntityClass() { 121 return entityClass; 122 } 123 124 public void setEntityClass(Class<?> entityClass) { 125 this.entityClass = entityClass; 126 } 127 128 public boolean isCamelToUnderline() { 129 return camelToUnderline; 130 } 131 132 public void setCamelToUnderline(boolean camelToUnderline) { 133 this.camelToUnderline = camelToUnderline; 134 } 135 136 public String getDataSource() { 137 return dataSource; 138 } 139 140 public void setDataSource(String dataSource) { 141 this.dataSource = dataSource; 142 } 143 144 public String getLogicDeleteColumn() { 145 return logicDeleteColumn; 146 } 147 148 public void setLogicDeleteColumn(String logicDeleteColumn) { 149 this.logicDeleteColumn = logicDeleteColumn; 150 } 151 152 public String getVersionColumn() { 153 return versionColumn; 154 } 155 156 public void setVersionColumn(String versionColumn) { 157 this.versionColumn = versionColumn; 158 } 159 160 public String getTenantIdColumn() { 161 return tenantIdColumn; 162 } 163 164 public void setTenantIdColumn(String tenantIdColumn) { 165 this.tenantIdColumn = tenantIdColumn; 166 } 167 168 public Map<String, String> getOnInsertColumns() { 169 return onInsertColumns; 170 } 171 172 public void setOnInsertColumns(Map<String, String> onInsertColumns) { 173 this.onInsertColumns = onInsertColumns; 174 } 175 176 public Map<String, String> getOnUpdateColumns() { 177 return onUpdateColumns; 178 } 179 180 public void setOnUpdateColumns(Map<String, String> onUpdateColumns) { 181 this.onUpdateColumns = onUpdateColumns; 182 } 183 184 public String[] getLargeColumns() { 185 return largeColumns; 186 } 187 188 public void setLargeColumns(String[] largeColumns) { 189 this.largeColumns = largeColumns; 190 } 191 192 public String[] getDefaultColumns() { 193 return defaultColumns; 194 } 195 196 public void setDefaultColumns(String[] defaultColumns) { 197 this.defaultColumns = defaultColumns; 198 } 199 200 public String[] getInsertPrimaryKeys() { 201 return insertPrimaryKeys; 202 } 203 204 public void setInsertPrimaryKeys(String[] insertPrimaryKeys) { 205 this.insertPrimaryKeys = insertPrimaryKeys; 206 } 207 208 public Reflector getReflector() { 209 return reflector; 210 } 211 212 public ReflectorFactory getReflectorFactory() { 213 return reflectorFactory; 214 } 215 216 public void setReflector(Reflector reflector) { 217 this.reflector = reflector; 218 } 219 220 public String[] getColumns() { 221 return columns; 222 } 223 224 225 public void setColumns(String[] columns) { 226 this.columns = columns; 227 } 228 229 public String[] getPrimaryKeys() { 230 return primaryKeys; 231 } 232 233 public void setPrimaryKeys(String[] primaryKeys) { 234 this.primaryKeys = primaryKeys; 235 } 236 237 238 public List<InsertListener> getOnInsertListeners() { 239 return onInsertListeners; 240 } 241 242 public void setOnInsertListeners(List<InsertListener> onInsertListeners) { 243 this.onInsertListeners = onInsertListeners; 244 } 245 246 public List<UpdateListener> getOnUpdateListeners() { 247 return onUpdateListeners; 248 } 249 250 public void setOnUpdateListeners(List<UpdateListener> onUpdateListeners) { 251 this.onUpdateListeners = onUpdateListeners; 252 } 253 254 public List<SetListener> getOnSetListeners() { 255 return onSetListeners; 256 } 257 258 public void setOnSetListeners(List<SetListener> onSetListeners) { 259 this.onSetListeners = onSetListeners; 260 } 261 262 public List<ColumnInfo> getColumnInfoList() { 263 return columnInfoList; 264 } 265 266 267 void setColumnInfoList(List<ColumnInfo> columnInfoList) { 268 this.columnInfoList = columnInfoList; 269 this.columns = new String[columnInfoList.size()]; 270 for (int i = 0; i < columnInfoList.size(); i++) { 271 ColumnInfo columnInfo = columnInfoList.get(i); 272 columns[i] = columnInfo.getColumn(); 273 columnInfoMapping.put(columnInfo.column, columnInfo); 274 propertyColumnMapping.put(columnInfo.property, columnInfo.column); 275 } 276 } 277 278 279 public List<IdInfo> getPrimaryKeyList() { 280 return primaryKeyList; 281 } 282 283 void setPrimaryKeyList(List<IdInfo> primaryKeyList) { 284 this.primaryKeyList = primaryKeyList; 285 this.primaryKeys = new String[primaryKeyList.size()]; 286 287 List<String> insertIdFields = new ArrayList<>(); 288 for (int i = 0; i < primaryKeyList.size(); i++) { 289 IdInfo idInfo = primaryKeyList.get(i); 290 primaryKeys[i] = idInfo.getColumn(); 291 292 if (idInfo.getKeyType() != KeyType.Auto && (idInfo.getBefore() != null && idInfo.getBefore())) { 293 insertIdFields.add(idInfo.getColumn()); 294 } 295 296 columnInfoMapping.put(idInfo.column, idInfo); 297 propertyColumnMapping.put(idInfo.property, idInfo.column); 298 } 299 this.insertPrimaryKeys = insertIdFields.toArray(new String[0]); 300 } 301 302 303 /** 304 * 插入(新增)数据时,获取所有要插入的字段 305 * 306 * @param entity 307 * @param ignoreNulls 308 * @return 字段列表 309 */ 310 public String[] obtainInsertColumns(Object entity, boolean ignoreNulls) { 311 if (!ignoreNulls) { 312 return ArrayUtil.concat(insertPrimaryKeys, columns); 313 } else { 314 MetaObject metaObject = EntityMetaObject.forObject(entity, reflectorFactory); 315 List<String> retColumns = new ArrayList<>(); 316 for (String insertColumn : columns) { 317 if (onInsertColumns != null && onInsertColumns.containsKey(insertColumn)) { 318 retColumns.add(insertColumn); 319 } else { 320 Object value = buildColumnSqlArg(metaObject, insertColumn); 321 if (value == null) { 322 continue; 323 } 324 retColumns.add(insertColumn); 325 } 326 } 327 return ArrayUtil.concat(insertPrimaryKeys, retColumns.toArray(new String[0])); 328 } 329 } 330 331 332 /** 333 * 构建 insert 的 Sql 参数 334 * 335 * @param entity 从 entity 中获取 336 * @param ignoreNulls 是否忽略 null 值 337 * @return 数组 338 */ 339 public Object[] buildInsertSqlArgs(Object entity, boolean ignoreNulls) { 340 MetaObject metaObject = EntityMetaObject.forObject(entity, reflectorFactory); 341 String[] insertColumns = obtainInsertColumns(entity, ignoreNulls); 342 343 List<Object> values = new ArrayList<>(insertColumns.length); 344 for (String insertColumn : insertColumns) { 345 if (onInsertColumns == null || !onInsertColumns.containsKey(insertColumn)) { 346 Object value = buildColumnSqlArg(metaObject, insertColumn); 347 if (ignoreNulls && value == null) { 348 continue; 349 } 350 values.add(value); 351 } 352 } 353 return values.toArray(); 354 } 355 356 357 /** 358 * 获取要修改的值 359 * 360 * @param entity 361 * @param ignoreNulls 362 */ 363 public Set<String> obtainUpdateColumns(Object entity, boolean ignoreNulls, boolean includePrimary) { 364 MetaObject metaObject = EntityMetaObject.forObject(entity, reflectorFactory); 365 Set<String> columns = new LinkedHashSet<>(); //需使用 LinkedHashSet 保证 columns 的顺序 366 if (entity instanceof ModifyAttrsRecord) { 367 Set<String> properties = ((ModifyAttrsRecord) entity).obtainModifyAttrs(); 368 if (properties.isEmpty()) { 369 return Collections.emptySet(); 370 } 371 for (String property : properties) { 372 String column = propertyColumnMapping.get(property); 373 if (onUpdateColumns != null && onUpdateColumns.containsKey(column)) { 374 continue; 375 } 376 377 //过滤乐观锁字段 和 租户字段 378 if (ObjectUtil.equalsAny(column, versionColumn, tenantIdColumn)) { 379 continue; 380 } 381 382 if (!includePrimary && ArrayUtil.contains(primaryKeys, column)) { 383 continue; 384 } 385 386 // ModifyAttrsRecord 忽略 ignoreNulls 的设置 387 // Object value = getPropertyValue(metaObject, property); 388 // if (ignoreNulls && value == null) { 389 // continue; 390 // } 391 columns.add(column); 392 } 393 } 394 //not ModifyAttrsRecord 395 else { 396 for (String column : this.columns) { 397 if (onUpdateColumns != null && onUpdateColumns.containsKey(column)) { 398 continue; 399 } 400 401 //过滤乐观锁字段 和 租户字段 402 if (ObjectUtil.equalsAny(column, versionColumn, tenantIdColumn)) { 403 continue; 404 } 405 406 Object value = buildColumnSqlArg(metaObject, column); 407 if (ignoreNulls && value == null) { 408 continue; 409 } 410 411 columns.add(column); 412 } 413 414 // 普通 entity(非 ModifyAttrsRecord) 忽略 includePrimary 的设置 415// if (includePrimary) { 416// for (String column : this.primaryKeys) { 417// Object value = getColumnValue(metaObject, column); 418// if (ignoreNulls && value == null) { 419// continue; 420// } 421// columns.add(column); 422// } 423// } 424 } 425 return columns; 426 } 427 428 /** 429 * 获取所有要修改的值,默认为全部除了主键以外的字段 430 * 431 * @param entity 实体对象 432 * @return 数组 433 */ 434 public Object[] buildUpdateSqlArgs(Object entity, boolean ignoreNulls, boolean includePrimary) { 435 MetaObject metaObject = EntityMetaObject.forObject(entity, reflectorFactory); 436 List<Object> values = new ArrayList<>(); 437 if (entity instanceof ModifyAttrsRecord) { 438 Set<String> properties = ((ModifyAttrsRecord) entity).obtainModifyAttrs(); 439 if (properties.isEmpty()) { 440 return values.toArray(); 441 } 442 for (String property : properties) { 443 String column = propertyColumnMapping.get(property); 444 if (onUpdateColumns != null && onUpdateColumns.containsKey(column)) { 445 continue; 446 } 447 //过滤乐观锁字段 和 租户字段 448 if (ObjectUtil.equalsAny(column, versionColumn, tenantIdColumn)) { 449 continue; 450 } 451 452 if (!includePrimary && ArrayUtil.contains(primaryKeys, column)) { 453 continue; 454 } 455 456 Object value = getPropertyValue(metaObject, property); 457 458 // ModifyAttrsRecord 忽略 ignoreNulls 的设置, 459 // 当使用 ModifyAttrsRecord 时,可以理解为要对字段进行 null 值进行更新,否则没必要使用 ModifyAttrsRecord 460 // if (ignoreNulls && value == null) { 461 // continue; 462 // } 463 values.add(value); 464 } 465 } 466 // normal entity. not ModifyAttrsRecord 467 else { 468 for (String column : this.columns) { 469 if (onUpdateColumns != null && onUpdateColumns.containsKey(column)) { 470 continue; 471 } 472 473 //过滤乐观锁字段 和 租户字段 474 if (ObjectUtil.equalsAny(column, versionColumn, tenantIdColumn)) { 475 continue; 476 } 477 478 // 普通 entity 忽略 includePrimary 的设置, 479 // 因为 for 循环中的 this.columns 本身就不包含有主键 480 // if (includePrimary) { 481 // } 482 483 Object value = buildColumnSqlArg(metaObject, column); 484 if (ignoreNulls && value == null) { 485 continue; 486 } 487 488 values.add(value); 489 } 490 } 491 492 return values.toArray(); 493 } 494 495 496 /** 497 * 构建主键的 sql 参数数据 498 * 499 * @param entity 500 */ 501 public Object[] buildPkSqlArgs(Object entity) { 502 MetaObject metaObject = EntityMetaObject.forObject(entity, reflectorFactory); 503 Object[] values = new Object[primaryKeys.length]; 504 for (int i = 0; i < primaryKeys.length; i++) { 505 values[i] = buildColumnSqlArg(metaObject, primaryKeys[i]); 506 } 507 return values; 508 } 509 510 511 public Object[] buildTenantIdArgs() { 512 if (StringUtil.isBlank(tenantIdColumn)) { 513 return null; 514 } 515 516 return TenantManager.getTenantIds(); 517 } 518 519 private static final String APPEND_CONDITIONS_FLAG = "appendConditions"; 520 521 public void appendConditions(Object entity, QueryWrapper queryWrapper) { 522 523 Object appendConditions = CPI.getContext(queryWrapper, APPEND_CONDITIONS_FLAG); 524 if (Boolean.TRUE.equals(appendConditions)) { 525 return; 526 } else { 527 CPI.putContext(queryWrapper, APPEND_CONDITIONS_FLAG, Boolean.TRUE); 528 } 529 530 //select * from (select ... from ) 中的子查询处理 531 List<QueryTable> queryTables = CPI.getQueryTables(queryWrapper); 532 if (queryTables != null && !queryTables.isEmpty()) { 533 for (QueryTable queryTable : queryTables) { 534 if (queryTable instanceof SelectQueryTable) { 535 QueryWrapper selectQueryWrapper = ((SelectQueryTable) queryTable).getQueryWrapper(); 536 List<QueryTable> selectQueryTables = CPI.getQueryTables(selectQueryWrapper); 537 if (selectQueryTables != null && !selectQueryTables.isEmpty()) { 538 for (QueryTable selectQueryTable : selectQueryTables) { 539 TableInfo tableInfo = TableInfoFactory.ofTableName(selectQueryTable.getName()); 540 if (tableInfo != null) { 541 tableInfo.appendConditions(entity, selectQueryWrapper); 542 } 543 } 544 } 545 } 546 } 547 } 548 549 //添加乐观锁条件,只有在 update 的时候进行处理 550 if (StringUtil.isNotBlank(versionColumn) && entity != null) { 551 Object versionValue = buildColumnSqlArg(entity, versionColumn); 552 if (versionValue == null) { 553 throw FlexExceptions.wrap("The version value of entity[%s] must not be null.", entity); 554 } 555 queryWrapper.and(QueryCondition.create(tableName, versionColumn, QueryCondition.LOGIC_EQUALS, versionValue)); 556 } 557 558 //逻辑删除 559 if (StringUtil.isNotBlank(logicDeleteColumn)) { 560 queryWrapper.and(QueryCondition.create(tableName, logicDeleteColumn, QueryCondition.LOGIC_EQUALS 561 , FlexGlobalConfig.getDefaultConfig().getNormalValueOfLogicDelete())); 562 } 563 564 //多租户 565 Object[] tenantIdArgs = buildTenantIdArgs(); 566 if (ArrayUtil.isNotEmpty(tenantIdArgs)) { 567 if (tenantIdArgs.length == 1) { 568 queryWrapper.and(QueryCondition.create(tableName, tenantIdColumn, QueryCondition.LOGIC_EQUALS, tenantIdArgs[0])); 569 } else { 570 queryWrapper.and(QueryCondition.create(tableName, tenantIdColumn, QueryCondition.LOGIC_IN, tenantIdArgs)); 571 } 572 } 573 574 //子查询 575 List<QueryWrapper> childSelects = CPI.getChildSelect(queryWrapper); 576 if (CollectionUtil.isNotEmpty(childSelects)) { 577 for (QueryWrapper childQueryWrapper : childSelects) { 578 List<QueryTable> childQueryTables = CPI.getQueryTables(childQueryWrapper); 579 for (QueryTable queryTable : childQueryTables) { 580 TableInfo tableInfo = TableInfoFactory.ofTableName(queryTable.getName()); 581 if (tableInfo != null) { 582 tableInfo.appendConditions(entity, childQueryWrapper); 583 } 584 } 585 } 586 } 587 588 //union 589 List<UnionWrapper> unions = CPI.getUnions(queryWrapper); 590 if (CollectionUtil.isNotEmpty(unions)) { 591 for (UnionWrapper union : unions) { 592 QueryWrapper unionQueryWrapper = union.getQueryWrapper(); 593 List<QueryTable> unionQueryTables = CPI.getQueryTables(unionQueryWrapper); 594 for (QueryTable queryTable : unionQueryTables) { 595 TableInfo tableInfo = TableInfoFactory.ofTableName(queryTable.getName()); 596 if (tableInfo != null) { 597 tableInfo.appendConditions(entity, unionQueryWrapper); 598 } 599 } 600 } 601 } 602 603 } 604 605 606 public String getKeyProperties() { 607 StringJoiner joiner = new StringJoiner(","); 608 for (IdInfo value : primaryKeyList) { 609 joiner.add(FlexConsts.ENTITY + "." + value.getProperty()); 610 } 611 return joiner.toString(); 612 } 613 614 615 public String getKeyColumns() { 616 StringJoiner joiner = new StringJoiner(","); 617 for (IdInfo value : primaryKeyList) { 618 joiner.add(value.getColumn()); 619 } 620 return joiner.toString(); 621 } 622 623 public List<QueryColumn> getDefaultQueryColumn() { 624 return Arrays.stream(defaultColumns) 625 .map(name -> new QueryColumn(getTableName(), name)) 626 .collect(Collectors.toList()); 627 } 628 629 public ResultMap buildResultMap(Configuration configuration) { 630 String resultMapId = entityClass.getName(); 631 List<ResultMapping> resultMappings = new ArrayList<>(); 632 633 for (ColumnInfo columnInfo : columnInfoList) { 634 ResultMapping mapping = new ResultMapping.Builder(configuration, columnInfo.getProperty(), 635 columnInfo.getColumn(), columnInfo.getPropertyType()) 636 .jdbcType(columnInfo.getJdbcType()) 637 .typeHandler(columnInfo.buildTypeHandler()) 638 .build(); 639 resultMappings.add(mapping); 640 } 641 642 for (IdInfo idInfo : primaryKeyList) { 643 ResultMapping mapping = new ResultMapping.Builder(configuration, idInfo.getProperty(), 644 idInfo.getColumn(), idInfo.getPropertyType()) 645 .flags(CollectionUtil.newArrayList(ResultFlag.ID)) 646 .jdbcType(idInfo.getJdbcType()) 647 .typeHandler(idInfo.buildTypeHandler()) 648 .build(); 649 resultMappings.add(mapping); 650 } 651 652 return new ResultMap.Builder(configuration, resultMapId, entityClass, resultMappings).build(); 653 } 654 655 656 private Object buildColumnSqlArg(MetaObject metaObject, String column) { 657 ColumnInfo columnInfo = columnInfoMapping.get(column); 658 Object value = getPropertyValue(metaObject, columnInfo.property); 659 660 TypeHandler typeHandler = columnInfo.buildTypeHandler(); 661 if (value != null && typeHandler != null) { 662 return new TypeHandlerObject(typeHandler, value, columnInfo.getJdbcType()); 663 } 664 665 return value; 666 } 667 668 669 public Object buildColumnSqlArg(Object entityObject, String column) { 670 MetaObject metaObject = EntityMetaObject.forObject(entityObject, reflectorFactory); 671 return buildColumnSqlArg(metaObject, column); 672 } 673 674 675 private Object getPropertyValue(MetaObject metaObject, String property) { 676 if (property != null && metaObject.hasGetter(property)) { 677 return metaObject.getValue(property); 678 } 679 return null; 680 } 681 682 683 /** 684 * 通过 row 实例类转换为一个 entity 685 * 686 * @return entity 687 */ 688 public <T> T newInstanceByRow(Row row, int index) { 689 Object instance = ClassUtil.newInstance(entityClass); 690 MetaObject metaObject = EntityMetaObject.forObject(instance, reflectorFactory); 691 Set<String> rowKeys = row.keySet(); 692 columnInfoMapping.forEach((column, columnInfo) -> { 693 if (index <= 0) { 694 for (String rowKey : rowKeys) { 695 if (column.equalsIgnoreCase(rowKey)) { 696 Object rowValue = row.get(rowKey); 697 Object value = ConvertUtil.convert(rowValue, metaObject.getSetterType(columnInfo.property)); 698 value = invokeOnSetListener(instance, columnInfo.getProperty(), value); 699 metaObject.setValue(columnInfo.property, value); 700 } 701 } 702 } else { 703 for (int i = index; i >= 0; i--) { 704 String newColumn = i <= 0 ? column : column + "$" + i; 705 boolean fillValue = false; 706 for (String rowKey : rowKeys) { 707 if (newColumn.equalsIgnoreCase(rowKey)) { 708 Object rowValue = row.get(rowKey); 709 Object value = ConvertUtil.convert(rowValue, metaObject.getSetterType(columnInfo.property)); 710 value = invokeOnSetListener(instance, columnInfo.getProperty(), value); 711 metaObject.setValue(columnInfo.property, value); 712 fillValue = true; 713 break; 714 } 715 } 716 if (fillValue) { 717 break; 718 } 719 } 720 } 721 }); 722 return (T) instance; 723 } 724 725 726 /** 727 * 初始化乐观锁版本号 728 * 729 * @param entityObject 730 */ 731 public void initVersionValueIfNecessary(Object entityObject) { 732 if (StringUtil.isBlank(versionColumn)) { 733 return; 734 } 735 736 MetaObject metaObject = EntityMetaObject.forObject(entityObject, reflectorFactory); 737 Object columnValue = getPropertyValue(metaObject, columnInfoMapping.get(versionColumn).property); 738 if (columnValue == null) { 739 String name = columnInfoMapping.get(versionColumn).property; 740 Class<?> clazz = metaObject.getSetterType(name); 741 metaObject.setValue(name, ConvertUtil.convert(0L, clazz)); 742 } 743 } 744 745 /** 746 * 设置租户id 747 * 748 * @param entityObject 749 */ 750 public void initTenantIdIfNecessary(Object entityObject) { 751 if (StringUtil.isBlank(tenantIdColumn)) { 752 return; 753 } 754 755 MetaObject metaObject = EntityMetaObject.forObject(entityObject, reflectorFactory); 756 Object[] tenantIds = TenantManager.getTenantIds(); 757 if (tenantIds == null || tenantIds.length == 0) { 758 return; 759 } 760 761 //默认使用第一个作为插入的租户ID 762 Object tenantId = tenantIds[0]; 763 if (tenantId != null) { 764 metaObject.setValue(columnInfoMapping.get(tenantIdColumn).property, tenantId); 765 } 766 } 767 768 /** 769 * 初始化逻辑删除的默认值 770 * 771 * @param entityObject 772 */ 773 public void initLogicDeleteValueIfNecessary(Object entityObject) { 774 if (StringUtil.isBlank(logicDeleteColumn)) { 775 return; 776 } 777 778 MetaObject metaObject = EntityMetaObject.forObject(entityObject, reflectorFactory); 779 Object columnValue = getPropertyValue(metaObject, columnInfoMapping.get(logicDeleteColumn).property); 780 if (columnValue == null) { 781 String property = columnInfoMapping.get(logicDeleteColumn).property; 782 Class<?> setterType = metaObject.getSetterType(property); 783 784 Object normalValueOfLogicDelete = FlexGlobalConfig.getDefaultConfig().getNormalValueOfLogicDelete(); 785 metaObject.setValue(property, ConvertUtil.convert(normalValueOfLogicDelete, setterType)); 786 } 787 } 788 789 790 private static Map<Class<?>, List<InsertListener>> insertListenerCache = new ConcurrentHashMap<>(); 791 792 public void invokeOnInsertListener(Object entity) { 793 List<InsertListener> listeners = MapUtil.computeIfAbsent(insertListenerCache, entityClass, aClass -> { 794 List<InsertListener> globalListeners = FlexGlobalConfig.getDefaultConfig() 795 .getSupportedInsertListener(entityClass, CollectionUtil.isNotEmpty(onInsertListeners)); 796 List<InsertListener> allListeners = CollectionUtil.merge(onInsertListeners, globalListeners); 797 Collections.sort(allListeners); 798 return allListeners; 799 }); 800 listeners.forEach(insertListener -> insertListener.onInsert(entity)); 801 } 802 803 804 private static Map<Class<?>, List<UpdateListener>> updateListenerCache = new ConcurrentHashMap<>(); 805 806 public void invokeOnUpdateListener(Object entity) { 807 List<UpdateListener> listeners = MapUtil.computeIfAbsent(updateListenerCache, entityClass, aClass -> { 808 List<UpdateListener> globalListeners = FlexGlobalConfig.getDefaultConfig() 809 .getSupportedUpdateListener(entityClass, CollectionUtil.isNotEmpty(onUpdateListeners)); 810 List<UpdateListener> allListeners = CollectionUtil.merge(onUpdateListeners, globalListeners); 811 Collections.sort(allListeners); 812 return allListeners; 813 }); 814 listeners.forEach(insertListener -> insertListener.onUpdate(entity)); 815 } 816 817 818 private static Map<Class<?>, List<SetListener>> setListenerCache = new ConcurrentHashMap<>(); 819 820 public Object invokeOnSetListener(Object entity, String property, Object value) { 821 List<SetListener> listeners = MapUtil.computeIfAbsent(setListenerCache, entityClass, aClass -> { 822 List<SetListener> globalListeners = FlexGlobalConfig.getDefaultConfig() 823 .getSupportedSetListener(entityClass, CollectionUtil.isNotEmpty(onSetListeners)); 824 List<SetListener> allListeners = CollectionUtil.merge(onSetListeners, globalListeners); 825 Collections.sort(allListeners); 826 return allListeners; 827 }); 828 for (SetListener setListener : listeners) { 829 value = setListener.onSet(entity, property, value); 830 } 831 return value; 832 } 833}