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