Get the App
SLTechnology News&Howtos  ›  Database  › 

Hot switching of database by inheriting AbstractRoutingDataSource in Spring+Mybatis project

Shulou Source: shulou.com Published: 2022-06-01 13:31:47 11月15日 Update

When doing an ERP project, there is a need to be able to manage and switch accounts, a set of accounts is a database, then you need to achieve the hot exchange of the database. Found a lot of information on the Internet and combined with the specific needs of the project to achieve a relatively easy to use database hot switch.

The principle is to first inherit AbstractRoutingDataSource and implement the determineCurrentLookupKey method, the content of which is

Protected Object determineCurrentLookupKey () {return DataSourceContextHolder.getDataSourceType ();}

The function of this method is that spring executes the method before executing sql, and determines the data source to be used from the key returned by this method in the data source Map.

Add another method: refreshDataSources

Private void refreshDataSources (List databaseList) {if (databaseList! = null & & databaseList.size () > 0) {BasicDataSource templateDataSource = (BasicDataSource) this.context.getBean ("dataSource"); / / template data source Map targetDataSources = new HashMap (); for (String database: databaseList) {BasicDataSource dataSource = new BasicDataSource (); dataSource.setDriverClassName (templateDataSource.getDriverClassName ()) DataSource.setUrl (regexReplaceUrl (templateDataSource.getUrl (), database)); dataSource.setUsername (templateDataSource.getUsername ()); dataSource.setPassword (templateDataSource.getPassword ()); dataSource.setMaxActive (templateDataSource.getMaxActive ()); dataSource.setMaxIdle (templateDataSource.getMaxIdle ()); dataSource.setDefaultAutoCommit (templateDataSource.getDefaultAutoCommit ()); dataSource.setTimeBetweenEvictionRunsMillis (templateDataSource.getTimeBetweenEvictionRunsMillis ()) DataSource.setMinEvictableIdleTimeMillis (templateDataSource.getMinEvictableIdleTimeMillis ()); targetDataSources.put (database, dataSource);} targetDataSources.put ("sycerp_system", templateDataSource); / / add default dataSource this.setTargetDataSources (targetDataSources); this.setDefaultTargetDataSource (targetDataSources.get ("sycerp_system"));} super.afterPropertiesSet () } / / the function of this method is to replace the database segment in the url of the configured default data source with the string private String regexReplaceUrl (String url, String database) {return Pattern.compile ("[/] [a-z0-9] + [\\?]") .matcher (url) .replaceAll ("/" + database + "?");}

The function of this method is to put the incoming databaseList (list of database names that need to be hot-switched), except for the url of datasource, through the properties configured in the default configured data source, and finally put the encapsulated data source collection into targetDataSources, and then call the afterPropertiesSet method to refresh the data source. The specific content of afterPropertiesSet can be viewed in the source code.

Where the context object in this code is obtained by implementing the setApplicationContext method of the ApplicationContextAware interface, and spring automatically injects the applicationContext object.

Then there is the configuration. We still follow the conventional spring configuration method of integrating mybatis, only with the configuration of one more data source.

DynamicDataSource is the class that implements AbstractRoutingDataSource above, and the dataSource of ref is the default data source. Other places where you configure data ref use this dynamicDataSource instead of dataSource.

Finally, it is how to use it. Because dynamicDataSource is already managed by spring, we just need to make a list of database names where we will use them, which can be queried from other databases, then call the refreshDataSources method, and finally call

DataSourceContextHolder.setDataSourceType ("Database name you want to switch")

Here is the code for DataSourceContextHolder

Public class DataSourceContextHolder {private static final ThreadLocal contextHolder = new ThreadLocal (); public static void setDataSourceType (String dataSourceType) {contextHolder.set (dataSourceType);} public static String getDataSourceType () {return contextHolder.get ();} public static void clearDataSourceType () {contextHolder.remove ();}}

At this point, a complete database hot switching function is all realized, and there are other specific requirements that can be modified on this basis.

Tags: Data method data source database configuration switch that is function name requirement project code content place object property management Zhongtong principle just Apple Docker Huawei Linux macOS MariaDB Microsoft MySQL NVidia OPPO Reno OPPO Reno Xiaomi Huawei macOS Redmi