com.baomidou.mybatisplus.core.metadata.TableInfoHelper Maven / Gradle / Ivy
/*
* Copyright (c) 2011-2024, baomidou ([email protected]).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.baomidou.mybatisplus.core.metadata;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.baomidou.mybatisplus.core.handlers.AnnotationHandler;
import com.baomidou.mybatisplus.core.handlers.PostInitTableInfoHandler;
import com.baomidou.mybatisplus.core.incrementer.IKeyGenerator;
import com.baomidou.mybatisplus.core.toolkit.*;
import jakarta.persistence.Column;
import org.apache.ibatis.builder.MapperBuilderAssistant;
import org.apache.ibatis.builder.StaticSqlSource;
import org.apache.ibatis.executor.keygen.KeyGenerator;
import org.apache.ibatis.executor.keygen.SelectKeyGenerator;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ResultMap;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.reflection.Reflector;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.type.SimpleTypeRegistry;
import java.lang.reflect.Field;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import static java.util.stream.Collectors.toList;
/**
*
* 实体类反射表辅助类
*
*
* @author hubin sjy
* @since 2016-09-09
*/
public class TableInfoHelper {
private static final Log logger = LogFactory.getLog(TableInfoHelper.class);
/**
* 储存反射类表信息
*/
private static final Map, TableInfo> TABLE_INFO_CACHE = new ConcurrentHashMap<>();
/**
* 储存表名对应的反射类表信息
*/
private static final Map TABLE_NAME_INFO_CACHE = new ConcurrentHashMap<>();
/**
* 默认表主键名称
*/
private static final String DEFAULT_ID_NAME = "id";
/**
*
* 获取实体映射表信息
*
*
* @param clazz 反射实体类
* @return 数据库表反射信息
*/
public static TableInfo getTableInfo(Class> clazz) {
if (clazz == null || clazz.isPrimitive() || SimpleTypeRegistry.isSimpleType(clazz) || clazz.isInterface()) {
return null;
}
// https://github.com/baomidou/mybatis-plus/issues/299
Class> targetClass = ClassUtils.getUserClass(clazz);
TableInfo tableInfo = TABLE_INFO_CACHE.get(targetClass);
if (null != tableInfo) {
return tableInfo;
}
//尝试获取父类缓存
Class> currentClass = clazz;
while (null == tableInfo && Object.class != currentClass) {
currentClass = currentClass.getSuperclass();
tableInfo = TABLE_INFO_CACHE.get(ClassUtils.getUserClass(currentClass));
}
//把父类的移到子类中来
if (tableInfo != null) {
TABLE_INFO_CACHE.put(targetClass, tableInfo);
}
return tableInfo;
}
/**
*
* 根据表名获取实体映射表信息
*
*
* @param tableName 表名
* @return 数据库表反射信息
*/
public static TableInfo getTableInfo(String tableName) {
if (StringUtils.isBlank(tableName)) {
return null;
}
return TABLE_NAME_INFO_CACHE.get(tableName);
}
/**
*
* 获取所有实体映射表信息
*
*
* @return 数据库表反射信息集合
*/
public static List getTableInfos() {
return Collections.unmodifiableList(new ArrayList<>(TABLE_INFO_CACHE.values()));
}
/**
* 清空实体表映射缓存信息
*
* @param entityClass 实体 Class
*/
public static void remove(Class> entityClass) {
TABLE_INFO_CACHE.remove(entityClass);
}
/**
*
* 实体类反射获取表信息【初始化】
*
*
* @param clazz 反射实体类
* @return 数据库表反射信息
*/
public static synchronized TableInfo initTableInfo(MapperBuilderAssistant builderAssistant, Class> clazz) {
TableInfo targetTableInfo = TABLE_INFO_CACHE.get(clazz);
final Configuration configuration = builderAssistant.getConfiguration();
if (targetTableInfo != null) {
Configuration oldConfiguration = targetTableInfo.getConfiguration();
if (!oldConfiguration.equals(configuration)) {
// 不是同一个 Configuration,进行重新初始化
targetTableInfo = initTableInfo(configuration, builderAssistant.getCurrentNamespace(), clazz);
}
return targetTableInfo;
}
return initTableInfo(configuration, builderAssistant.getCurrentNamespace(), clazz);
}
/**
*
* 实体类反射获取表信息【初始化】
*
*
* @param clazz 反射实体类
* @return 数据库表反射信息
*/
private static synchronized TableInfo initTableInfo(Configuration configuration, String currentNamespace, Class> clazz) {
GlobalConfig globalConfig = GlobalConfigUtils.getGlobalConfig(configuration);
PostInitTableInfoHandler postInitTableInfoHandler = globalConfig.getPostInitTableInfoHandler();
/* 没有获取到缓存信息,则初始化 */
TableInfo tableInfo = postInitTableInfoHandler.creteTableInfo(configuration, clazz);
tableInfo.setCurrentNamespace(currentNamespace);
/* 初始化表名相关 */
final String[] excludeProperty = initTableName(clazz, globalConfig, tableInfo);
List excludePropertyList = excludeProperty != null && excludeProperty.length > 0 ? Arrays.asList(excludeProperty) : Collections.emptyList();
/* 初始化字段相关 */
initTableFields(configuration, clazz, globalConfig, tableInfo, excludePropertyList);
/* 自动构建 resultMap */
tableInfo.initResultMapIfNeed();
postInitTableInfoHandler.postTableInfo(tableInfo, configuration);
TABLE_INFO_CACHE.put(clazz, tableInfo);
TABLE_NAME_INFO_CACHE.put(tableInfo.getTableName(), tableInfo);
/* 缓存 lambda */
LambdaUtils.installCache(tableInfo);
return tableInfo;
}
/**
*
* 初始化 表数据库类型,表名,resultMap
*
*
* @param clazz 实体类
* @param globalConfig 全局配置
* @param tableInfo 数据库表反射信息
* @return 需要排除的字段名
*/
private static String[] initTableName(Class> clazz, GlobalConfig globalConfig, TableInfo tableInfo) {
/* 数据库全局配置 */
GlobalConfig.DbConfig dbConfig = globalConfig.getDbConfig();
AnnotationHandler annotationHandler = globalConfig.getAnnotationHandler();
String tableName = clazz.getSimpleName();
String tablePrefix = dbConfig.getTablePrefix();
String schema = dbConfig.getSchema();
boolean tablePrefixEffect = true;
String[] excludeProperty = null;
if(annotationHandler.isAnnotationPresent(clazz,jakarta.persistence.Table.class)){
jakarta.persistence.Table table = annotationHandler.getAnnotation(clazz, jakarta.persistence.Table.class);
if(StringUtils.isNotBlank(table.name())){
tableName = table.name();
}
// 表追加前缀
String targetTableName = tableName;
if (StringUtils.isNotBlank(table.schema())) {
schema = table.schema();
}
// 表追加 schema 信息
if (StringUtils.isNotBlank(schema)) {
targetTableName = schema + StringPool.DOT + targetTableName;
}
tableInfo.setTableName(targetTableName);
return excludeProperty;
}
TableName table = annotationHandler.getAnnotation(clazz, TableName.class);
if (table != null) {
if (StringUtils.isNotBlank(table.value())) {
tableName = table.value();
if (StringUtils.isNotBlank(tablePrefix) && !table.keepGlobalPrefix()) {
tablePrefixEffect = false;
}
} else {
tableName = initTableNameWithDbConfig(tableName, dbConfig);
}
if (StringUtils.isNotBlank(table.schema())) {
schema = table.schema();
}
/* 表结果集映射 */
if (StringUtils.isNotBlank(table.resultMap())) {
tableInfo.setResultMap(table.resultMap());
}
tableInfo.setAutoInitResultMap(table.autoResultMap());
excludeProperty = table.excludeProperty();
} else {
tableName = initTableNameWithDbConfig(tableName, dbConfig);
}
// 表追加前缀
String targetTableName = tableName;
if (StringUtils.isNotBlank(tablePrefix) && tablePrefixEffect) {
targetTableName = tablePrefix + targetTableName;
}
// 表格式化
String tableFormat = dbConfig.getTableFormat();
if (StringUtils.isNotBlank(tableFormat)) {
targetTableName = String.format(tableFormat, targetTableName);
}
// 表追加 schema 信息
if (StringUtils.isNotBlank(schema)) {
targetTableName = schema + StringPool.DOT + targetTableName;
}
tableInfo.setTableName(targetTableName);
/* 开启了自定义 KEY 生成器 */
if (CollectionUtils.isNotEmpty(dbConfig.getKeyGenerators())) {
tableInfo.setKeySequence(annotationHandler.getAnnotation(clazz, KeySequence.class));
}
return excludeProperty;
}
/**
* 根据 DbConfig 初始化 表名
*
* @param className 类名
* @param dbConfig DbConfig
* @return 表名
*/
private static String initTableNameWithDbConfig(String className, GlobalConfig.DbConfig dbConfig) {
String tableName = className;
// 开启表名下划线申明
if (dbConfig.isTableUnderline()) {
tableName = StringUtils.camelToUnderline(tableName);
}
// 大写命名判断
if (dbConfig.isCapitalMode()) {
tableName = tableName.toUpperCase();
} else {
// 首字母小写
tableName = StringUtils.firstToLowerCase(tableName);
}
return tableName;
}
/**
*
* 初始化 表主键,表字段
*
*
* @param clazz 实体类
* @param globalConfig 全局配置
* @param tableInfo 数据库表反射信息
*/
private static void initTableFields(Configuration configuration, Class> clazz, GlobalConfig globalConfig, TableInfo tableInfo, List excludeProperty) {
AnnotationHandler annotationHandler = globalConfig.getAnnotationHandler();
PostInitTableInfoHandler postInitTableInfoHandler = globalConfig.getPostInitTableInfoHandler();
Reflector reflector = tableInfo.getReflector();
List list = getAllFields(clazz, annotationHandler);
// 标记是否读取到主键
boolean isReadPK = false;
// 是否存在 @TableId 注解
boolean existTableId = isExistTableId(list, annotationHandler);
// 是否存在 @TableLogic 注解
boolean existTableLogic = isExistTableLogic(list, annotationHandler);
List fieldList = new ArrayList<>(list.size());
for (Field field : list) {
if (excludeProperty.contains(field.getName())) {
continue;
}
boolean isPK = false;
OrderBy orderBy = annotationHandler.getAnnotation(field, OrderBy.class);
boolean isOrderBy = orderBy != null;
/* 主键ID 初始化 */
if (existTableId) {
TableId tableId = annotationHandler.getAnnotation(field, TableId.class);
if (tableId != null) {
if (isReadPK) {
throw ExceptionUtils.mpe("@TableId can't more than one in Class: \"%s\".", clazz.getName());
}
initTableIdWithAnnotation(globalConfig, tableInfo, field, tableId);
isPK = isReadPK = true;
}else {
jakarta.persistence.Id id = annotationHandler.getAnnotation(field, jakarta.persistence.Id.class);
if(id != null){
if (isReadPK) {
throw ExceptionUtils.mpe("@TableId can't more than one in Class: \"%s\".", clazz.getName());
}
initTableIdWithAnnotation(globalConfig, tableInfo, field, id);
isPK = isReadPK = true;
}
}
} else if (!isReadPK) {
isPK = isReadPK = initTableIdWithoutAnnotation(globalConfig, tableInfo, field);
}
if (isPK) {
if (orderBy != null) {
tableInfo.getOrderByFields().add(new OrderFieldInfo(tableInfo.getKeyColumn(), orderBy.asc(), orderBy.sort()));
}
continue;
}
if(annotationHandler.isAnnotationPresent(field,jakarta.persistence.Column.class)){
final jakarta.persistence.Column tableField = annotationHandler.getAnnotation(field, jakarta.persistence.Column.class);
/* 有 @TableField 注解的字段初始化 */
if (tableField != null) {
TableFieldInfo tableFieldInfo = new TableFieldInfo(globalConfig, tableInfo, field, tableField, reflector, existTableLogic, isOrderBy);
fieldList.add(tableFieldInfo);
postInitTableInfoHandler.postFieldInfo(tableFieldInfo, configuration);
continue;
}
}else {
final TableField tableField = annotationHandler.getAnnotation(field, TableField.class);
/* 有 @TableField 注解的字段初始化 */
if (tableField != null) {
TableFieldInfo tableFieldInfo = new TableFieldInfo(globalConfig, tableInfo, field, tableField, reflector, existTableLogic, isOrderBy);
fieldList.add(tableFieldInfo);
postInitTableInfoHandler.postFieldInfo(tableFieldInfo, configuration);
continue;
}
}
/* 无 @TableField 注解的字段初始化 */
TableFieldInfo tableFieldInfo = new TableFieldInfo(globalConfig, tableInfo, field, reflector, existTableLogic, isOrderBy);
fieldList.add(tableFieldInfo);
postInitTableInfoHandler.postFieldInfo(tableFieldInfo, configuration);
}
/* 字段列表 */
tableInfo.setFieldList(fieldList);
/* 未发现主键注解,提示警告信息 */
if (!isReadPK) {
logger.warn(String.format("Can not find table primary key in Class: \"%s\".", clazz.getName()));
}
}
/**
*
* 判断主键注解是否存在
*
*
* @param clazz 实体类
* @param list 字段列表
* @return true 为存在 {@link TableId} 注解;
*/
public static boolean isExistTableId(Class> clazz, List list) {
TableInfo tableInfo = TableInfoHelper.getTableInfo(clazz);
AnnotationHandler annotationHandler = GlobalConfigUtils.getGlobalConfig(tableInfo.getConfiguration()).getAnnotationHandler();
return isExistTableId(list, annotationHandler);
}
/**
*
* 判断主键注解是否存在
*
*
* @param list 字段列表
* @return true 为存在 {@link TableId} 注解;
*/
public static boolean isExistTableId(List list, AnnotationHandler annotationHandler) {
return list.stream().anyMatch(field -> annotationHandler.isAnnotationPresent(field, TableId.class) || annotationHandler.isAnnotationPresent(field, jakarta.persistence.Id.class));
}
/**
*
* 判断逻辑删除注解是否存在
*
*
* @param clazz 实体类
* @param list 字段列表
* @return true 为存在 {@link TableLogic} 注解;
*/
public static boolean isExistTableLogic(Class> clazz, List list) {
TableInfo tableInfo = TableInfoHelper.getTableInfo(clazz);
AnnotationHandler annotationHandler = GlobalConfigUtils.getGlobalConfig(tableInfo.getConfiguration()).getAnnotationHandler();
return isExistTableLogic(list, annotationHandler);
}
/**
*
* 判断逻辑删除注解是否存在
*
*
* @param list 字段列表
* @return true 为存在 {@link TableLogic} 注解;
*/
public static boolean isExistTableLogic(List list, AnnotationHandler annotationHandler) {
return list.stream().anyMatch(field -> annotationHandler.isAnnotationPresent(field, TableLogic.class));
}
/**
*
* 判断排序注解是否存在
*
*
* @param clazz 实体类
* @param list 字段列表
* @return true 为存在 {@link OrderBy} 注解;
*/
public static boolean isExistOrderBy(Class> clazz, List list) {
TableInfo tableInfo = TableInfoHelper.getTableInfo(clazz);
AnnotationHandler annotationHandler = GlobalConfigUtils.getGlobalConfig(tableInfo.getConfiguration()).getAnnotationHandler();
return isExistOrderBy(list, annotationHandler);
}
/**
*
* 判断排序注解是否存在
*
*
* @param list 字段列表
* @param annotationHandler 注解处理类
* @return true 为存在 {@link OrderBy} 注解;
*/
public static boolean isExistOrderBy(List list, AnnotationHandler annotationHandler) {
return list.stream().anyMatch(field -> annotationHandler.isAnnotationPresent(field, OrderBy.class));
}
/**
*
* 主键属性初始化
*
*
* @param globalConfig 全局配置信息
* @param tableInfo 表信息
* @param field 字段
* @param tableId 注解
*/
private static void initTableIdWithAnnotation(GlobalConfig globalConfig, TableInfo tableInfo, Field field, TableId tableId) {
GlobalConfig.DbConfig dbConfig = globalConfig.getDbConfig();
boolean underCamel = tableInfo.isUnderCamel();
final String property = field.getName();
if (globalConfig.getAnnotationHandler().isAnnotationPresent(field, TableField.class)) {
logger.warn(String.format("This \"%s\" is the table primary key by @TableId annotation in Class: \"%s\",So @TableField annotation will not work!",
property, tableInfo.getEntityType().getName()));
}
/* 主键策略( 注解 > 全局 ) */
// 设置 Sequence 其他策略无效
if (IdType.NONE == tableId.type()) {
tableInfo.setIdType(dbConfig.getIdType());
} else {
tableInfo.setIdType(tableId.type());
}
/* 字段 */
String column = property;
if (StringUtils.isNotBlank(tableId.value())) {
column = tableId.value();
} else {
// 开启字段下划线申明
if (underCamel) {
column = StringUtils.camelToUnderline(column);
}
// 全局大写命名
if (dbConfig.isCapitalMode()) {
column = column.toUpperCase();
}
}
final Class> keyType = tableInfo.getReflector().getGetterType(property);
if (keyType.isPrimitive()) {
logger.warn(String.format("This primary key of \"%s\" is primitive !不建议如此请使用包装类 in Class: \"%s\"",
property, tableInfo.getEntityType().getName()));
}
if (StringUtils.isEmpty(tableId.value())) {
String columnFormat = dbConfig.getColumnFormat();
if (StringUtils.isNotBlank(columnFormat)) {
column = String.format(columnFormat, column);
}
}
tableInfo.setKeyRelated(checkRelated(underCamel, property, column))
.setKeyColumn(column)
.setKeyProperty(property)
.setKeyType(keyType);
}
/**
*
* 主键属性初始化
*
*
* @param globalConfig 全局配置信息
* @param tableInfo 表信息
* @param field 字段
* @param tableId 注解
*/
private static void initTableIdWithAnnotation(GlobalConfig globalConfig, TableInfo tableInfo, Field field, jakarta.persistence.Id tableId) {
GlobalConfig.DbConfig dbConfig = globalConfig.getDbConfig();
boolean underCamel = tableInfo.isUnderCamel();
final String property = field.getName();
tableInfo.setIdType(dbConfig.getIdType());
/* 字段 */
String column = property;
Column columnAn = field.getAnnotation(Column.class);
if (columnAn != null && StringUtils.isNotBlank(columnAn.name())) {
column = columnAn.name();
} else {
// 开启字段下划线申明
if (underCamel) {
column = StringUtils.camelToUnderline(column);
}
// 全局大写命名
if (dbConfig.isCapitalMode()) {
column = column.toUpperCase();
}
}
final Class> keyType = tableInfo.getReflector().getGetterType(property);
if (keyType.isPrimitive()) {
logger.warn(String.format("This primary key of \"%s\" is primitive !不建议如此请使用包装类 in Class: \"%s\"",
property, tableInfo.getEntityType().getName()));
}
String columnFormat = dbConfig.getColumnFormat();
if (StringUtils.isNotBlank(columnFormat)) {
column = String.format(columnFormat, column);
}
tableInfo.setKeyRelated(checkRelated(underCamel, property, column))
.setKeyColumn(column)
.setKeyProperty(property)
.setKeyType(keyType);
}
/**
*
* 主键属性初始化
*
*
* @param globalConfig 全局配置
* @param tableInfo 表信息
* @param field 字段
* @return true 继续下一个属性判断,返回 continue;
*/
private static boolean initTableIdWithoutAnnotation(GlobalConfig globalConfig, TableInfo tableInfo, Field field) {
GlobalConfig.DbConfig dbConfig = globalConfig.getDbConfig();
final String property = field.getName();
if (DEFAULT_ID_NAME.equalsIgnoreCase(property)) {
if (globalConfig.getAnnotationHandler().isAnnotationPresent(field, TableField.class)) {
logger.warn(String.format("This \"%s\" is the table primary key by default name for `id` in Class: \"%s\",So @TableField will not work!",
property, tableInfo.getEntityType().getName()));
}
String column = property;
if (dbConfig.isCapitalMode()) {
column = column.toUpperCase();
}
final Class> keyType = tableInfo.getReflector().getGetterType(property);
if (keyType.isPrimitive()) {
logger.warn(String.format("This primary key of \"%s\" is primitive !不建议如此请使用包装类 in Class: \"%s\"",
property, tableInfo.getEntityType().getName()));
}
String columnFormat = dbConfig.getColumnFormat();
if (StringUtils.isNotBlank(columnFormat)) {
column = String.format(columnFormat, column);
}
tableInfo.setKeyRelated(checkRelated(tableInfo.isUnderCamel(), property, column))
.setIdType(dbConfig.getIdType())
.setKeyColumn(column)
.setKeyProperty(property)
.setKeyType(keyType);
return true;
}
return false;
}
/**
* 判定 related 的值
*
* 为 true 表示不符合规则
*
* @param underCamel 驼峰命名
* @param property 属性名
* @param column 字段名
* @return related
*/
public static boolean checkRelated(boolean underCamel, String property, String column) {
column = StringUtils.getTargetColumn(column);
String propertyUpper = property.toUpperCase(Locale.ENGLISH);
String columnUpper = column.toUpperCase(Locale.ENGLISH);
if (underCamel) {
// 开启了驼峰并且 column 包含下划线
return !(propertyUpper.equals(columnUpper) ||
propertyUpper.equals(columnUpper.replace(StringPool.UNDERSCORE, StringPool.EMPTY)));
} else {
// 未开启驼峰,直接判断 property 是否与 column 相同(全大写)
return !propertyUpper.equals(columnUpper);
}
}
/**
*
* 获取该类的所有属性列表
*
*
* @param clazz 反射类
* @return 属性集合
*/
public static List getAllFields(Class> clazz) {
TableInfo tableInfo = TableInfoHelper.getTableInfo(clazz);
AnnotationHandler annotationHandler = GlobalConfigUtils.getGlobalConfig(tableInfo.getConfiguration()).getAnnotationHandler();
return getAllFields(clazz, annotationHandler);
}
/**
*
* 获取该类的所有属性列表
*
*
* @param clazz 反射类
* @param annotationHandler 注解处理类
* @return 属性集合
*/
public static List getAllFields(Class> clazz, AnnotationHandler annotationHandler) {
List fieldList = ReflectionKit.getFieldList(ClassUtils.getUserClass(clazz));
return fieldList.stream()
.filter(field -> {
/* 过滤注解非表字段属性 */
TableField tableField = annotationHandler.getAnnotation(field, TableField.class);
return (tableField == null || tableField.exist()) && !annotationHandler.isAnnotationPresent(field, jakarta.persistence.Transient.class);
}).collect(toList());
}
public static KeyGenerator genKeyGenerator(String baseStatementId, TableInfo tableInfo, MapperBuilderAssistant builderAssistant) {
List keyGenerators = GlobalConfigUtils.getKeyGenerators(builderAssistant.getConfiguration());
if (CollectionUtils.isEmpty(keyGenerators)) {
throw new IllegalArgumentException("not configure IKeyGenerator implementation class.");
}
IKeyGenerator keyGenerator = null;
if (keyGenerators.size() > 1) {
// 多个主键生成器
KeySequence keySequence = tableInfo.getKeySequence();
if (null != keySequence && DbType.OTHER != keySequence.dbType()) {
keyGenerator = keyGenerators.stream().filter(k -> k.dbType() == keySequence.dbType()).findFirst().orElse(null);
}
}
// 无法找到注解指定生成器,默认使用第一个生成器
if (null == keyGenerator) {
keyGenerator = keyGenerators.get(0);
}
Configuration configuration = builderAssistant.getConfiguration();
String id = builderAssistant.getCurrentNamespace() + StringPool.DOT + baseStatementId + SelectKeyGenerator.SELECT_KEY_SUFFIX;
ResultMap resultMap = new ResultMap.Builder(builderAssistant.getConfiguration(), id, tableInfo.getKeyType(), new ArrayList<>()).build();
MappedStatement mappedStatement = new MappedStatement.Builder(builderAssistant.getConfiguration(), id,
new StaticSqlSource(configuration, keyGenerator.executeSql(tableInfo.getKeySequence().value())), SqlCommandType.SELECT)
.keyProperty(tableInfo.getKeyProperty())
.resultMaps(Collections.singletonList(resultMap))
.build();
configuration.addMappedStatement(mappedStatement);
return new SelectKeyGenerator(mappedStatement, true);
}
}