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