Sharding-JDBC系列
2、Sharding-JDBC分库分表之SpringBoot分片策略
3、Sharding-JDBC分库分表之SpringBoot主从配置
4、SpringBoot集成Sharding-JDBC-5.3.0分库分表
5、SpringBoot集成Sharding-JDBC-5.3.0实现按月动态建表分表
8、【源码】Sharding-JDBC源码分析之Yaml分片配置文件解析原理
9、【源码】Sharding-JDBC源码分析之Yaml分片配置原理(一)
10、【源码】Sharding-JDBC源码分析之Yaml分片配置原理(二)
11、【源码】Sharding-JDBC源码分析之Yaml分片配置转换原理
12、【源码】Sharding-JDBC源码分析之ShardingSphereDataSource的创建原理
13、【源码】Sharding-JDBC源码分析之ContextManager创建中mode分片配置信息的持久化存储的原理
前言
在【源码】Sharding-JDBC源码分析之ShardingSphereDataSource的创建原理-CSDN博客博文的3.1.2中介绍了ContextManager的创建,本文从源码角度分享一下ContextManager的创建过程中,通过配置的mode,进行配置信息的持久化存储原理。
ContextManagerBuilder
ContextManager是通过ContextManagerBuilder.build()方法进行创建的。ContextManagerBuilder是一个接口类,只有build()一个接口方法。有两个实现类,分别为ClusterContextManagerBuilder和StandaloneContextManagerBuilder,分别对应集群和单机两种模式。
在ShardingSphereDataSource的createContextManager()方法中,会根据配置的mode的类型(Standalone和Cluster),通过SPI获取ContextManagerBuilder。默认是Standalone,即StandaloneContextManagerBuilder,本文以StandaloneContextManagerBuilder为例。
StandaloneContextManagerBuilder
StandaloneContextManagerBuilder的源码如下:
package org.apache.shardingsphere.mode.manager.standalone;
/**
* 单机上下文管理创建者。持久化配置信息到H2或Mysql
*/
public final class StandaloneContextManagerBuilder implements ContextManagerBuilder {
@Override
public ContextManager build(final ContextManagerBuilderParameter param) throws SQLException {
// 获取配置的元数据持久化信息
PersistRepositoryConfiguration repositoryConfig = param.getModeConfiguration().getRepository();
// 获取持久化接口对象,默认为JDBCRepository对象
StandalonePersistRepository repository = null == repositoryConfig
? RequiredSPIRegistry.getRegisteredService(StandalonePersistRepository.class)
: TypedSPIRegistry.getRegisteredService(StandalonePersistRepository.class, repositoryConfig.getType(), repositoryConfig.getProps());
// 新建元数据持久化service类
MetaDataPersistService persistService = new MetaDataPersistService(repository);
// 持久化配置信息,默认保存到h2数据库中
persistConfigurations(persistService, param);
InstanceContext instanceContext = buildInstanceContext(param);
// 监听,处理Standalone的订阅者
new ProcessStandaloneSubscriber(instanceContext.getEventBusContext());
// 创建MetaDataContexts,创建ShardingSphereDatabase,保存到MetaDataContexts中
MetaDataContexts metaDataContexts = MetaDataContextsFactory.create(persistService, param, instanceContext);
ContextManager result = new ContextManager(metaDataContexts, instanceContext);
setContextManagerAware(result);
return result;
}
/**
* 持久化配置信息
*/
private void persistConfigurations(final MetaDataPersistService persistService, final ContextManagerBuilderParameter param) {
if (!param.isEmpty()) {
persistService.persistConfigurations(param.getDatabaseConfigs(), param.getGlobalRuleConfigs(), param.getProps());
}
}
/**
* 创建InstanceContext。创建StandaloneModeContextManager、GlobalLockContext,传入InstanceContext构造器
*/
private InstanceContext buildInstanceContext(final ContextManagerBuilderParameter param) {
return new InstanceContext(new ComputeNodeInstance(param.getInstanceMetaData()),
new StandaloneWorkerIdGenerator(), param.getModeConfiguration(), new StandaloneModeContextManager(), new GlobalLockContext(null), new EventBusContext());
}
/**
* 为StandaloneModeContextManager对象设置ContextManager
* @param contextManager
*/
private void setContextManagerAware(final ContextManager contextManager) {
((StandaloneModeContextManager) contextManager.getInstanceContext().getModeContextManager()).setContextManagerAware(contextManager);
}
@Override
public String getType() {
return "Standalone";
}
@Override
public boolean isDefault() {
return true;
}
}
build()方法执行如下:
1)通过mode的配置信息,获取对应的持久化配置对象,此处为StandalonePersistRepositoryConfiguration对象;
StandalonePersistRepositoryConfiguration记录对应的持久化类型(在单机中,为JDBC)及对应属性(有provider、jdbc_url、username、password)。其中provider为对应的持久化库,如H2、MySQL等。
2)获取持久化接口对象,为JDBCRepository对象;
3)创建元数据持久化service类,MetaDataPersistService对象;
该对象保存了数据库、数据库规则、全局规则、属性等对应的持久化存储Service对象,对应的Service持久化存储对象提供了保存对应配置信息的接口。
4)执行persistConfigurations()方法,调用MetaDataPersistService,持久化存储配置信息;
5)创建InstanceContext;
创建StandaloneModeContextManager、GlobalLockContext,传入InstanceContext构造器。
6)添加监听,处理Standalone模式的订阅者;
7)创建MetaDataContexts,创建ShardingSphereDatabase,保存到MetaDataContexts中;
8)创建ContextManager对象;
9)将ContextManager对象赋值给StandaloneModeContextManager;
10)返回创建的ContextManager对象;
JDBCRepository
JDBCRepository的源码如下:
package org.apache.shardingsphere.mode.repository.standalone.jdbc;
/**
* JDBC存储库。用于存储属性配置信息
*/
@Slf4j
public final class JDBCRepository implements StandalonePersistRepository {
private static final String SEPARATOR = "/";
private static final String H2_FILE_MODE_KEY = "file:";
// JDBC存储库提供者。实现类有H2JDBCRepositoryProvider、MySQLJDBCRepositoryProvider和JDBCRepositoryProviderFixture。
// 提供固定的表repository的创建、删除、插入、查询
private JDBCRepositoryProvider provider;
private HikariDataSource hikariDataSource;
@SneakyThrows(SQLException.class)
@Override
public void init(final Properties props) {
// JDBC存储库属性。如果构造方法中传入的props没有值,则默认使用H2数据库保存
JDBCRepositoryProperties jdbcRepositoryProps = new JDBCRepositoryProperties(props);
// 创建JDBC存储库的数据源
hikariDataSource = new HikariDataSource();
String jdbcUrl = jdbcRepositoryProps.getValue(JDBCRepositoryPropertyKey.JDBC_URL);
hikariDataSource.setJdbcUrl(jdbcUrl);
hikariDataSource.setUsername(jdbcRepositoryProps.getValue(JDBCRepositoryPropertyKey.USERNAME));
hikariDataSource.setPassword(jdbcRepositoryProps.getValue(JDBCRepositoryPropertyKey.PASSWORD));
try (
// 通过数据源,默认创建一个H2的数据库连接
Connection connection = hikariDataSource.getConnection();
Statement statement = connection.createStatement()) {
// 获取类型
String type = jdbcRepositoryProps.getValue(JDBCRepositoryPropertyKey.PROVIDER);
// 获取对应类型的JDBCRepository提供者
provider = null == type ? RequiredSPIRegistry.getRegisteredService(JDBCRepositoryProvider.class) : TypedSPIRegistry.getRegisteredService(JDBCRepositoryProvider.class, type);
// 创建对应的存储库的表。表名:repository
if (!jdbcUrl.contains(H2_FILE_MODE_KEY)) {
statement.execute(provider.dropTableSQL());
}
statement.execute(provider.createTableSQL());
}
}
/**
* 获取某个key的配置信息,key的值如:props等
* @return
*/
@Override
public String getDirectly(final String key) {
try (
Connection connection = hikariDataSource.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(provider.selectByKeySQL())) {
preparedStatement.setString(1, key);
try (ResultSet resultSet = preparedStatement.executeQuery()) {
if (resultSet.next()) {
return resultSet.getString("value");
}
}
} catch (final SQLException ex) {
log.error("Get {} data by key: {} failed", getType(), key, ex);
}
return "";
}
/**
* 获取某个key的子key
* @return
*/
@Override
public List<String> getChildrenKeys(final String key) {
try (
Connection connection = hikariDataSource.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(provider.selectByParentKeySQL())) {
preparedStatement.setString(1, key);
try (ResultSet resultSet = preparedStatement.executeQuery()) {
List<String> resultChildren = new LinkedList<>();
while (resultSet.next()) {
String childrenKey = resultSet.getString("key");
if (Strings.isNullOrEmpty(childrenKey)) {
continue;
}
int lastIndexOf = childrenKey.lastIndexOf(SEPARATOR);
resultChildren.add(childrenKey.substring(lastIndexOf + 1));
}
return new ArrayList<>(resultChildren);
}
} catch (final SQLException ex) {
log.error("Get children {} data by key: {} failed", getType(), key, ex);
}
return Collections.emptyList();
}
@Override
public boolean isExisted(final String key) {
return !Strings.isNullOrEmpty(getDirectly(key));
}
/**
* 持久化保存
* @param key key of data
* @param value value of data
*/
@Override
public void persist(final String key, final String value) {
try {
if (isExisted(key)) {
update(key, value);
return;
}
String tempPrefix = "";
String parent = SEPARATOR;
String[] paths = Arrays.stream(key.split(SEPARATOR)).filter(each -> !Strings.isNullOrEmpty(each)).toArray(String[]::new);
// Create key level directory recursively.
for (int i = 0; i < paths.length - 1; i++) {
String tempKey = tempPrefix + SEPARATOR + paths[i];
String tempKeyVal = getDirectly(tempKey);
if (Strings.isNullOrEmpty(tempKeyVal)) {
if (i != 0) {
parent = tempPrefix;
}
insert(tempKey, "", parent);
}
tempPrefix = tempKey;
parent = tempKey;
}
insert(key, value, parent);
} catch (final SQLException ex) {
log.error("Persist {} data to key: {} failed", getType(), key, ex);
}
}
private void insert(final String key, final String value, final String parent) throws SQLException {
try (
Connection connection = hikariDataSource.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(provider.insertSQL())) {
preparedStatement.setString(1, UUID.randomUUID().toString());
preparedStatement.setString(2, key);
preparedStatement.setString(3, value);
preparedStatement.setString(4, parent);
preparedStatement.executeUpdate();
}
}
@Override
public void update(final String key, final String value) {
try (
Connection connection = hikariDataSource.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(provider.updateSQL())) {
preparedStatement.setString(1, value);
preparedStatement.setString(2, key);
preparedStatement.executeUpdate();
} catch (final SQLException ex) {
log.error("Update {} data to key: {} failed", getType(), key, ex);
}
}
@Override
public void delete(final String key) {
try (
Connection connection = hikariDataSource.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(provider.deleteSQL())) {
preparedStatement.setString(1, key);
preparedStatement.executeUpdate();
} catch (final SQLException ex) {
log.error("Delete {} data by key: {} failed", getType(), key, ex);
}
}
@Override
public void close() {
hikariDataSource.close();
}
@Override
public String getType() {
return "JDBC";
}
}
4.1 构造方法
构造方法主要执行如下:
1)创建一个JDBCRepositoryProperties对象,传入配置的props;
JDBCRepositoryProperties解析props,将配置的信息按照JDBCRepositoryPropertyKey枚举类中配置的key,获取props中对应的key的值。如果对应的key在props中没有配置,则使用JDBCRepositoryPropertyKey枚举的默认值,采用H2持久化存储。
JDBCRepositoryPropertyKey的源码如下:
package org.apache.shardingsphere.mode.repository.standalone.jdbc.props;
/**
* JDBC存储库的属性key。枚举类。默认为H2
*/
@RequiredArgsConstructor
@Getter
public enum JDBCRepositoryPropertyKey implements TypedPropertyKey {
PROVIDER("provider", "H2", String.class),
JDBC_URL("jdbc_url", "jdbc:h2:mem:config;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MYSQL", String.class),
USERNAME("username", "sa", String.class),
PASSWORD("password", "", String.class);
private final String key;
private final String defaultValue;
private final Class<?> type;
}
2)创建HikariDataSource对象,通过JDBCRepositoryProperties中的信息设置HikariDataSource对象的jdbcUrl、username、password;
3)通过HikariDataSource获取一个Connection连接和Statement对象;
4)通过配置的provider,采用SPI获取对应的JDBCRepositoryProvider;
JDBCRepositoryProvider是一个接口,不同的provider有不同的实现,如针对MySQL的MySQLJDBCRepositoryProvider、针对H2的H2JDBCRepositoryProvider。在实现类中,提供了持久化存储配置信息的表的维护、表数据的维护的SQL语句。以下以MySQLJDBCRepositoryProvider为例。
MySQLJDBCRepositoryProvider的源码如下:
package org.apache.shardingsphere.mode.repository.standalone.jdbc.mysql;
/**
* MySQL持久化提供器。定义了表、表数据维护的SQL语句。
*/
public final class MySQLJDBCRepositoryProvider implements JDBCRepositoryProvider {
@Override
public String dropTableSQL() {
return "DROP TABLE IF EXISTS `repository`";
}
@Override
public String createTableSQL() {
return "CREATE TABLE IF NOT EXISTS `repository`(id varchar(36) PRIMARY KEY, `key` TEXT, `value` TEXT, parent TEXT)";
}
@Override
public String selectByKeySQL() {
return "SELECT `value` FROM `repository` WHERE `key` = ?";
}
@Override
public String selectByParentKeySQL() {
return "SELECT `key` FROM `repository` WHERE parent = ? ORDER BY `key` ASC";
}
@Override
public String insertSQL() {
return "INSERT INTO `repository` VALUES(?, ?, ?, ?)";
}
@Override
public String updateSQL() {
return "UPDATE `repository` SET `value` = ? WHERE `key` = ?";
}
@Override
public String deleteSQL() {
return "DELETE FROM `repository` WHERE `key` = ?";
}
@Override
public String getType() {
return "MySQL";
}
}
代码比较简单,定义了repository表的创建、删除,以及repository表的增删改查操作的SQL语句。
5)通过JDBCRepositoryProvider对象获取创建表的SQL语句,通过Statement执行SQL语句,创建表;
4.2 persist()持久化方法
persist()配置信息持久化方法主要执行如下:
1)解析key的路径;
2)遍历key的路径,执行insert()方法,按路径、父路径、值,将信息持久化到表中;
在insert()方法中,通过4.1中的JDBCRepositoryProvider,获取插入语句的SQL。再通过HikariDataSource获取Connection,执行SQL语句;
3)按key和value,执行insert()插入配置的信息;
4.3 其他方法
在JDBCRepository类中,还提供了修改update()、删除delete()、查询getDirectly()及查询子目录getChildrenKeys()方法。
MetaDataPersistService
MetaDataPersistService元数据持久化Service类,针对不同的配置信息,提供了不同的持久化Service,源码如下:
package org.apache.shardingsphere.mode.metadata.persist;
/**
* 元数据持久化service类。
*/
@Getter
public final class MetaDataPersistService {
// 持久存储库。存储元数据的持久化接口。可以将元数据存储在H2文件、数据库、nacos、zookeeper、etcd等中。如JDBCRepository
private final PersistRepository repository;
// 数据源配置信息持久化的Service
private final DataSourcePersistService dataSourceService;
// 数据库配置信息持久化的Service
private final DatabaseMetaDataPersistService databaseMetaDataService;
// 数据库规则配置信息持久化的Service
private final DatabaseRulePersistService databaseRulePersistService;
// 数据库信息配置信息持久化的Service
private final GlobalRulePersistService globalRuleService;
// 属性持久化的Service类
private final PropertiesPersistService propsService;
// 元数据版本持久化的Service
private final MetaDataVersionPersistService metaDataVersionPersistService;
// ShardingSphere数据的持久化Service
private final ShardingSphereDataPersistService shardingSphereDataPersistService;
public MetaDataPersistService(final PersistRepository repository) {
this.repository = repository;
dataSourceService = new DataSourcePersistService(repository);
databaseMetaDataService = new DatabaseMetaDataPersistService(repository);
databaseRulePersistService = new DatabaseRulePersistService(repository);
globalRuleService = new GlobalRulePersistService(repository);
propsService = new PropertiesPersistService(repository);
metaDataVersionPersistService = new MetaDataVersionPersistService(repository);
shardingSphereDataPersistService = new ShardingSphereDataPersistService(repository);
}
/**
* 持久化配置信息。根据配置类型,使用对应的Service,持久化配置信息
*/
public void persistConfigurations(final Map<String, ? extends DatabaseConfiguration> databaseConfigs,
final Collection<RuleConfiguration> globalRuleConfigs, final Properties props) {
// 持久化
globalRuleService.conditionalPersist(globalRuleConfigs);
propsService.conditionalPersist(props);
for (Entry<String, ? extends DatabaseConfiguration> entry : databaseConfigs.entrySet()) {
String databaseName = entry.getKey();
// 获取满足对应DataSource配置的属性信息
Map<String, DataSourceProperties> dataSourcePropertiesMap = getDataSourcePropertiesMap(entry.getValue().getDataSources());
if (dataSourcePropertiesMap.isEmpty() && entry.getValue().getRuleConfigurations().isEmpty()) {
databaseMetaDataService.addDatabase(databaseName);
} else {
// 持久化DataSource配置的属性信息
dataSourceService.conditionalPersist(databaseName, getDataSourcePropertiesMap(entry.getValue().getDataSources()));
databaseRulePersistService.conditionalPersist(databaseName, entry.getValue().getRuleConfigurations());
}
}
}
/**
* 获取满足对应DataSource配置的属性信息
*/
private Map<String, DataSourceProperties> getDataSourcePropertiesMap(final Map<String, DataSource> dataSourceMap) {
Map<String, DataSourceProperties> result = new LinkedHashMap<>(dataSourceMap.size(), 1);
for (Entry<String, DataSource> entry : dataSourceMap.entrySet()) {
result.put(entry.getKey(), DataSourcePropertiesCreator.create(entry.getValue()));
}
return result;
}
/**
* 获取有效的数据源
*/
public Map<String, DataSource> getEffectiveDataSources(final String databaseName, final Map<String, ? extends DatabaseConfiguration> databaseConfigs) {
// 从数据库(H2或Mysql)表中获取对应逻辑数据库名的yaml配置信息,转化成DataSourceProperties
Map<String, DataSourceProperties> persistedDataPropsMap = dataSourceService.load(databaseName);
return databaseConfigs.containsKey(databaseName)
? mergeEffectiveDataSources(persistedDataPropsMap, databaseConfigs.get(databaseName).getDataSources())
: DataSourcePoolCreator.create(persistedDataPropsMap);
}
/**
* 合并有效的数据库信息
*/
private Map<String, DataSource> mergeEffectiveDataSources(final Map<String, DataSourceProperties> persistedDataSourcePropsMap, final Map<String, DataSource> localConfiguredDataSources) {
Map<String, DataSource> result = new LinkedHashMap<>(persistedDataSourcePropsMap.size(), 1);
for (Entry<String, DataSourceProperties> entry : persistedDataSourcePropsMap.entrySet()) {
// 获取配置的数据源名称,如order_ds
String dataSourceName = entry.getKey();
// 获取数据源配置的信息,如:url、username、password
DataSourceProperties persistedDataSourceProps = entry.getValue();
DataSource localConfiguredDataSource = localConfiguredDataSources.get(dataSourceName);
if (null == localConfiguredDataSource) {
// 为空的话,直接将datasource中的配置信息转化为DataSourceProperties,加入到result中
result.put(dataSourceName, DataSourcePoolCreator.create(persistedDataSourceProps));
} else if (DataSourcePropertiesCreator.create(localConfiguredDataSource).equals(persistedDataSourceProps)) {
// 将datasource中的配置信息转化为DataSourceProperties,如何和persistedDataSourceProps相同,则加入到result中
result.put(dataSourceName, localConfiguredDataSource);
} else {
// 如果不等,从池中创建一个连接,通过反射创建一个datasource
result.put(dataSourceName, DataSourcePoolCreator.create(persistedDataSourceProps));
// 回收旧的datasource
new DataSourcePoolDestroyer(localConfiguredDataSource).asyncDestroy();
}
}
return result;
}
}
5.1 构造方法
在构造方法中,针对不同的配置信息,创建对应的持久化存储Service。在Service中,保存了传入的PersistRepository。如JDBCRepository对象。
5.2 persistConfigurations()持久化方法
在该方法中,针对不同的配置信息,调用对应的Service,执行持久化存储。
如全局配置信息的存储,调用globalRuleService的conditionalPersist()方法。
GlobalRulePersistService
全局配置信息GlobalRulePersistService的源码如下:
package org.apache.shardingsphere.mode.metadata.persist.service.config.global;
/**
* 全局规则持久化Service。通过调用PersistRepository的persist()方法,持久化配置信息
*/
@RequiredArgsConstructor
public final class GlobalRulePersistService implements GlobalPersistService<Collection<RuleConfiguration>> {
// 持久化存储器,如JDBCRepository,提供了针对MySQL、H2数据库数据的增删改查接口
private final PersistRepository repository;
@Override
public void conditionalPersist(final Collection<RuleConfiguration> globalRuleConfigs) {
if (!globalRuleConfigs.isEmpty() && !isExisted()) {
persist(globalRuleConfigs);
}
}
/**
* 持久化全局规则配置信息到数据库持久化存储库中
*/
@Override
public void persist(final Collection<RuleConfiguration> globalRuleConfigs) {
// 获取全局规则的接口的key,即路径。值为/rules,即在表中存储的key为/rules的,表示全局规则
// 将配置的RuleConfiguration对象转换为YamlRuleConfiguration对象,通过YamlEngine.marshal()转换为字符串
repository.persist(GlobalNode.getGlobalRuleNode(), YamlEngine.marshal(new YamlRuleConfigurationSwapperEngine().swapToYamlRuleConfigurations(globalRuleConfigs)));
}
@Override
@SuppressWarnings("unchecked")
public Collection<RuleConfiguration> load() {
return isExisted()
? new YamlRuleConfigurationSwapperEngine().swapToRuleConfigurations(YamlEngine.unmarshal(repository.getDirectly(GlobalNode.getGlobalRuleNode()), Collection.class))
: Collections.emptyList();
}
private boolean isExisted() {
return !Strings.isNullOrEmpty(repository.getDirectly(GlobalNode.getGlobalRuleNode()));
}
/**
* 从持久化存储库中获取全局规则中的审计规则人员信息
*/
public Collection<ShardingSphereUser> loadUsers() {
Optional<AuthorityRuleConfiguration> authorityRuleConfig = load().stream().filter(each -> each instanceof AuthorityRuleConfiguration)
.map(each -> (AuthorityRuleConfiguration) each).findFirst();
return authorityRuleConfig.isPresent() ? authorityRuleConfig.get().getUsers() : Collections.emptyList();
}
}
在GlobalRulePersistService中提供的persist、load方法都是通过传入的PersistRepository(如JDBCRepository对象)对象执行对应的方法实现的。
小结
限于篇幅,本篇先分享到这里。以下做一个小结。
ShardingSphere通过ContextManagerBuilder的build()方法创建ContextManager对象。ContextManagerBuilder是一个接口类,只有build()一个接口方法。有两个实现类,分别为ClusterContextManagerBuilder和StandaloneContextManagerBuilder,分别对应集群和单机两种模式。
本篇以Standalone为例,在StandaloneContextManagerBuilder的build()方法中,执行了分片配置信息的持久化存储,流程如下:
1)通过mode的配置信息,获取对应的持久化配置对象。对于Standalone,此处为StandalonePersistRepositoryConfiguration对象;
本篇以Standalone为例,对于Cluster,实现思路类似,只是对应的持久化存储由MySQL、H2换为分布式配置中心中间件,如Nacos、Zookeeper、Etc、Consul等。
2)创建持久化StandalonePersistRepository对象,此处为JDBCRepository对象;
2.1)JDBCRepository根据mode配置中的props的provider(默认为H2),获取对应的JDBCRepositoryProvider。如MySQL的MySQLJDBCRepositoryProvider,其提供了repository表的创建、删除,以及repository表的增删改查操作的SQL语句;
2.2)根据mode配置中的props中的jdbc_url、username、password,创建HikariDataSource对象;
2.3)获取JDBCRepositoryProvider中创建repository表的SQL语句,通过HikariDataSource对象获取连接,执行SQL语句,实现持久化存储库的表的创建;
2.4)提供了repository表的插入、修改、删除方法;
3)创建元数据持久化service类,MetaDataPersistService对象;
3.1)该对象保存了数据库、数据库规则、全局规则、属性等对应的持久化存储Service对象,对应的Service持久化存储对象提供了保存对应配置信息的接口;
3.2)Service类中对应的持久化方法是通过 2)中的JDBCRepository对象,实现了对应配置信息持久化;
3.3)配置项以多路径的方式作为key存储在repository表中;
4)执行persistConfigurations()方法,调用MetaDataPersistService的持久化方法,持久化存储配置信息;
关于本篇内容你有什么自己的想法或独到见解,欢迎在评论区一起交流探讨下吧。