mybatis-plus - TableInfo

在前面 的 inject() 方法中, 调用了一个 TableInfoHelper.initTableInfo(builderAssistant, modelClass) 方法, 来获取 表信息: TableInfo

  /**
     * 

* 实体类反射获取表信息【初始化】 *

* * @param clazz 反射实体类 * @return 数据库表反射信息 */ public synchronized static TableInfo initTableInfo(MapperBuilderAssistant builderAssistant, Class clazz) { TableInfo tableInfo = TABLE_INFO_CACHE.get(clazz); if (tableInfo != null) { if (tableInfo.getConfigMark() == null && builderAssistant != null) { tableInfo.setConfigMark(builderAssistant.getConfiguration()); } return tableInfo; } /* 没有获取到缓存信息,则初始化 */ tableInfo = new TableInfo(); GlobalConfig globalConfig; if (null != builderAssistant) { tableInfo.setCurrentNamespace(builderAssistant.getCurrentNamespace()); tableInfo.setConfigMark(builderAssistant.getConfiguration()); tableInfo.setUnderCamel(builderAssistant.getConfiguration().isMapUnderscoreToCamelCase()); globalConfig = GlobalConfigUtils.getGlobalConfig(builderAssistant.getConfiguration()); } else { // 兼容测试场景 globalConfig = GlobalConfigUtils.defaults(); } /* 初始化表名相关 */ initTableName(clazz, globalConfig, tableInfo); /* 初始化字段相关 */ initTableFields(clazz, globalConfig, tableInfo); /* 放入缓存 */ TABLE_INFO_CACHE.put(clazz, tableInfo); /* 缓存 Lambda 映射关系 */ LambdaUtils.createCache(clazz, tableInfo); return tableInfo; }

是不是还是自己人写的代码看起来爽? 这中文注释, 都不用看方法具体是干啥的. 

这里的  TABLE_INFO_CACHE  是用来缓存表信息的:

/**
 * 储存反射类表信息
 */
private static final Map, TableInfo> TABLE_INFO_CACHE = new ConcurrentHashMap<>();

第一次进这个方法的时候, 肯定是空的, 要去解析获取.

 

1. initTableName()

 /**
     * 

* 初始化 表数据库类型,表名,resultMap *

* *
@param clazz 实体类 * @param globalConfig 全局配置 * @param tableInfo 数据库表反射信息 */ public static void initTableName(Class clazz, GlobalConfig globalConfig, TableInfo tableInfo) { /* 数据库全局配置 */ GlobalConfig.DbConfig dbConfig = globalConfig.getDbConfig(); /* 设置数据库类型 */ tableInfo.setDbType(dbConfig.getDbType()); /* 设置表名 */ TableName table = clazz.getAnnotation(TableName.class); String tableName = clazz.getSimpleName(); if (table != null && StringUtils.isNotEmpty(table.value())) { tableName = table.value(); } else { // 开启表名下划线申明 if (dbConfig.isTableUnderline()) { tableName = StringUtils.camelToUnderline(tableName); } // 大写命名判断 if (dbConfig.isCapitalMode()) { tableName = tableName.toUpperCase(); } else { // 首字母小写 tableName = StringUtils.firstToLowerCase(tableName); } // 存在表名前缀 if (null != dbConfig.getTablePrefix()) { tableName = dbConfig.getTablePrefix() + tableName; } } tableInfo.setTableName(tableName); /* 表结果集映射 */ if (table != null && StringUtils.isNotEmpty(table.resultMap())) { tableInfo.setResultMap(table.resultMap()); } /* 开启了自定义 KEY 生成器 */ if (null != dbConfig.getKeyGenerator()) { tableInfo.setKeySequence(clazz.getAnnotation(KeySequence.class)); } }

判断逻辑:

1. 判断实体类上面有没有 TableName 注解

  |-> 如果有, 则拿注解里面配置的 value 作为表名

  |-> 如果没有, 则根据类名进行解析

 

2. initTableFields()

  /**
     * 

* 初始化 表主键,表字段 *

* *
@param clazz 实体类 * @param globalConfig 全局配置 * @param tableInfo 数据库表反射信息 */ public static void initTableFields(Class clazz, GlobalConfig globalConfig, TableInfo tableInfo) { /* 数据库全局配置 */ GlobalConfig.DbConfig dbConfig = globalConfig.getDbConfig(); List list = getAllFields(clazz); // 标记是否读取到主键 boolean isReadPK = false; // 是否存在 @TableId 注解 boolean existTableId = isExistTableId(list); List fieldList = new ArrayList<>(); for (Field field : list) { /* * 主键ID 初始化 */ if (!isReadPK) { if (existTableId) { isReadPK = initTableIdWithAnnotation(dbConfig, tableInfo, field, clazz); } else { isReadPK = initTableIdWithoutAnnotation(dbConfig, tableInfo, field, clazz); } if (isReadPK) { continue; } } /* 有 @TableField 注解的字段初始化 */ if (initTableFieldWithAnnotation(dbConfig, tableInfo, fieldList, field, clazz)) { continue; } /* 无 @TableField 注解的字段初始化 */ fieldList.add(new TableFieldInfo(dbConfig, tableInfo, field)); } /* 检查逻辑删除字段只能有最多一个 */ Assert.isTrue(fieldList.parallelStream().filter(TableFieldInfo::isLogicDelete).count() < 2L, String.format("annotation of @TableLogic can't more than one in class : %s.", clazz.getName())); /* 字段列表 */ tableInfo.setFieldList(fieldList); /* 未发现主键注解,提示警告信息 */ if (StringUtils.isEmpty(tableInfo.getKeyColumn())) { logger.warn(String.format("Warn: Could not find @TableId in Class: %s.", clazz.getName())); } }

 

2.1 getAllFields()

    /**
     * 获取该类的所有属性列表
     *
     * @param clazz 反射类
     * @return 属性集合
     */
    public static List getAllFields(Class clazz) {
        List fieldList = ReflectionKit.getFieldList(ClassUtils.getUserClass(clazz));
        if (CollectionUtils.isNotEmpty(fieldList)) {
            return fieldList.stream()
                .filter(i -> {
                    /* 过滤注解非表字段属性 */
                    TableField tableField = i.getAnnotation(TableField.class);
                    return (tableField == null || tableField.exist());
                }).collect(toList());
        }
        return fieldList;
    }

如果字段上面加了 TableField 注解, 如果有则进行特殊处理. 如果配置了 exist=false, 则这个字段, 过滤掉, 不参与sql生成.

 

2.2 initTableIdWithAnnotation()

如果实体类中有 TableId 注解, 则进入此方法, 一般情况下, 最好是配一下 TableId

    /**
     * 

* 主键属性初始化 *

* *
@param dbConfig 全局配置信息 * @param tableInfo 表信息 * @param field 字段 * @param clazz 实体类 * @return true 继续下一个属性判断,返回 continue; */ private static boolean initTableIdWithAnnotation(GlobalConfig.DbConfig dbConfig, TableInfo tableInfo, Field field, Class clazz) { TableId tableId = field.getAnnotation(TableId.class); boolean underCamel = tableInfo.isUnderCamel(); if (tableId != null) { if (StringUtils.isEmpty(tableInfo.getKeyColumn())) { /* 主键策略( 注解 > 全局 ) */ // 设置 Sequence 其他策略无效 if (IdType.NONE == tableId.type()) { tableInfo.setIdType(dbConfig.getIdType()); } else { tableInfo.setIdType(tableId.type()); } /* 字段 */ String column = field.getName(); if (StringUtils.isNotEmpty(tableId.value())) { column = tableId.value(); } else { // 开启字段下划线申明 if (underCamel) { column = StringUtils.camelToUnderline(column); } // 全局大写命名 if (dbConfig.isCapitalMode()) { column = column.toUpperCase(); } } tableInfo.setKeyRelated(checkRelated(underCamel, field.getName(), column)) .setClazz(field.getDeclaringClass()) .setKeyColumn(column) .setKeyProperty(field.getName()); return true; } else { throwExceptionId(clazz); } } return false; }

 

2.3 initTableFieldWithAnnotation()

这里对 TableField 进行解析赋值. 如  value 解析成 字段名称

    /**
     * 

* 字段属性初始化 *

* *
@param dbConfig 数据库全局配置 * @param tableInfo 表信息 * @param fieldList 字段列表 * @param clazz 当前表对象类 * @return true 继续下一个属性判断,返回 continue; */ private static boolean initTableFieldWithAnnotation(GlobalConfig.DbConfig dbConfig, TableInfo tableInfo, List fieldList, Field field, Class clazz) { /* 获取注解属性,自定义字段 */ TableField tableField = field.getAnnotation(TableField.class); if (null == tableField) { return false; } String columnName = field.getName(); if (StringUtils.isNotEmpty(tableField.value())) { columnName = tableField.value(); } /* * el 语法支持,可以传入多个参数以逗号分开 */ String el = field.getName(); if (StringUtils.isNotEmpty(tableField.el())) { el = tableField.el(); } String[] columns = columnName.split(StringPool.SEMICOLON); String[] els = el.split(StringPool.SEMICOLON); if (columns.length == els.length) { for (int i = 0; i < columns.length; i++) { fieldList.add(new TableFieldInfo(dbConfig, tableInfo, field, columns[i], els[i], tableField)); } return true; } throw ExceptionUtils.mpe(String.format("Class: %s, Field: %s, 'value' 'el' Length must be consistent.", clazz.getName(), field.getName())); }

 

你可能感兴趣的:(mybatis-plus - TableInfo)