本文主要分析一下sharding的上下文ShardingContent,ShardingContent主要做了那些功能呢?主要有两部分:
- 数据源分片元数据
主要根据数据源连接获取对应的url,通过解析url参数来封装数据源分片元数据;数据源分片元数据主要后续SQL路由DCL(比如:授权、创建用户等)操作使用
- 表分片元数据
主要根据数据节点来获取真实表的元数据;而表分片元数据主要后续SQL解析填充使用
源码分析
1.ShardingContext构造,主要分析ShardingTableMetaData
public ShardingContext(final Map<String, DataSource> dataSourceMap, final ShardingRule shardingRule, final DatabaseType databaseType, final Properties props) throws SQLException {
this.shardingRule = shardingRule;
//获取数据源原始元数据信息
this.cachedDatabaseMetaData = createCachedDatabaseMetaData(dataSourceMap);
//数据源类型
this.databaseType = databaseType;
//sharding 配置参数
//比如:sql打印、线程池大小配置等
shardingProperties = new ShardingProperties(null == props ? new Properties() : props);
//Statement、PrepareStatement执行线程池大小
//一个分片数据源将使用独立的线程池,它不会在同一个JVM中共享线程池甚至不同的数据源
//默认无限制
int executorSize = shardingProperties.getValue(ShardingPropertiesConstant.EXECUTOR_SIZE);
//执行引擎
executeEngine = new ShardingExecuteEngine(executorSize);
//数据源分片元数据
//以mysql为例,建立连接获取mysql url,将解析后的url参数信息封装到ShardingDataSourceMetaData
ShardingDataSourceMetaData shardingDataSourceMetaData = new ShardingDataSourceMetaData(getDataSourceURLs(dataSourceMap), shardingRule, databaseType);
//表分片元数据
//以mysql为例,会建立连接获取表的元信息(字段、字段类型、索引)
ShardingTableMetaData shardingTableMetaData = new ShardingTableMetaData(getTableMetaDataInitializer(dataSourceMap, shardingDataSourceMetaData).load(shardingRule));
//封装数据源分片元数据、表分片元数据
metaData = new ShardingMetaData(shardingDataSourceMetaData, shardingTableMetaData);
//解析结果缓存
parsingResultCache = new ParsingResultCache();
}
//
private TableMetaDataInitializer getTableMetaDataInitializer(final Map<String, DataSource> dataSourceMap, final ShardingDataSourceMetaData shardingDataSourceMetaData) {
return new TableMetaDataInitializer(shardingDataSourceMetaData, executeEngine, new JDBCTableMetaDataConnectionManager(dataSourceMap),
shardingProperties.<Integer>getValue(ShardingPropertiesConstant.MAX_CONNECTIONS_SIZE_PER_QUERY),
shardingProperties.<Boolean>getValue(ShardingPropertiesConstant.CHECK_TABLE_METADATA_ENABLED));
}
2.加载TableMetaDataInitializer#load
public TableMetaDataInitializer(final ShardingDataSourceMetaData shardingDataSourceMetaData, final ShardingExecuteEngine executeEngine,
final TableMetaDataConnectionManager connectionManager, final int maxConnectionsSizePerQuery, final boolean isCheckingMetaData) {
//数据源分片元数据
this.shardingDataSourceMetaData = shardingDataSourceMetaData;
//数据源连接管理器
this.connectionManager = connectionManager;
//表元数据加载器
tableMetaDataLoader = new TableMetaDataLoader(shardingDataSourceMetaData, executeEngine, connectionManager, maxConnectionsSizePerQuery, isCheckingMetaData);
}
/**
* Load table meta data.
*
* @param logicTableName logic table name
* @param shardingRule sharding rule
* @return table meta data
*/
@SneakyThrows
public TableMetaData load(final String logicTableName, final ShardingRule shardingRule) {
return tableMetaDataLoader.load(logicTableName, shardingRule);
}
/**
* Load all table meta data.
*
* @param shardingRule sharding rule
* @return all table meta data
*/
@SneakyThrows
public Map<String, TableMetaData> load(final ShardingRule sh