In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)05/31 Report--
This article introduces the relevant knowledge of "how to use AbstractRoutingDataSource for Spring multi-tenant data source management". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
1. Basic principles
The core of dynamic switching of multiple data sources is that spring provides AbstractRoutingDataSource classes for data source routing. AbstractRoutingDataSource implements the DataSource interface, so we can inject it directly into the properties of DataSource.
We mainly inherit this class and implement the method determineCurrentLookupKey (), which only needs to return the name of a database.
For example, Controller distributes business logic by getting the values passed by the front-end business. It can manually set the database identity of the current request and then route it to the correct database table.
@ Controllerpublic class ARDTestController {@ GetMapping ("test") public void chifeng () {/ / db-a should be the attribute passed down from the upper layer, we can put it in ThreadLocal DataSourceContextHolder.setDbKey ("db-a");}}
So when the sql statement is executed, how does it know which data source it needs to switch to? Do you need to pass on the db-an attribute all the time?
In Java, you can use ThreadLocal to bind this transparent property. The principle of implementation, such as Spring's nested transactions, is also based on ThreadLocal. So, DataSourceContextHolder. Is essentially a class that operates on ThreadLocal.
Public class DataSourceContextHolder {private static InheritableThreadLocal dbKey = new InheritableThreadLocal (); public static void setDbKey (String key) {dbKey.set (key);} public static String getDbKey () {return dbKey.get ();} 2. Configuration code
First, we customize the format of the configuration file. As in the following code, two databases, db-an and db-b, are configured.
Multi: dbs: db-a: driver-class-name: org.h3.Driver url: jdbc:h3:mem:dba;MODE=MYSQL;DATABASE_TO_UPPER=false; db-b: driver-class-name: org.h3.Driver url: jdbc:h3:mem:dbb;MODE=MYSQL;DATABASE_TO_UPPER=false
Then, we parse it as properties.
ConfigurationProperties (prefix = "multi") @ Configurationpublic class DbsProperties {private Map dbs = new HashMap (); public Map getDbs () {return dbs;} public void setDbs (Map dbs) {this.dbs = dbs;}}
Next, you need to configure the default data source for the entire application. As you can see, its main logic is to extract the pre-set value from ThreadLocal at run time.
Public class DynamicDataSource extends AbstractRoutingDataSource {@ Override protected Object determineCurrentLookupKey () {return DataSourceContextHolder.getDbKey ();}}
As a final step, set the default DataSource throughout the project. Note that after we generate the DynamicDataSource, we also need to provide the values of the targetDataSource and defaultTargetDataSource properties in order to work properly.
@ Configurationpublic class DynamicDataSourceConfiguration {@ Autowired DbsProperties properties; @ Bean public DataSource dataSource () {DynamicDataSource dataSource = new DynamicDataSource (); final Map targetDataSource = getTargetDataSource (); dataSource.setTargetDataSources (targetDataSource); / / TODO default database needs to set dataSource.setDefaultTargetDataSource (targetDataSource.values (). Iterator (). Next ()); return dataSource;} private Map getTargetDataSource () {Map dataSources = new HashMap () This.properties.getDbs (). EntrySet (). Stream () .forEach (e-> {DriverManagerDataSource dmd = new DriverManagerDataSource (); dmd.setUrl (e.getValue (). Get ("url")); dmd.setDriverClassName (e.getValue (). Get ("driver-class-name")) DataSources.put (e.getKey (), dmd);}); return dataSources;}} 3. problem
Through the above simple code, you can achieve Spring simple multi-data source management. But obviously, it still has a lot of problems.
Product design selection mode is required for business switching.
The front end can be placed in the localStroage to save the properties, and the interceptor can be used to pass the variable each time.
The backend needs to bring the target db with each request, which can be put in the ThreadLocal. However, ThreadLocal has the problem of thread transparent transmission. If child threads are opened in the task, variables cannot be shared.
Because tables are dynamically selected, schemas such as JPA automatic creation and update will not be available. It is not convenient for testing and unit testing, and you also need to force the library to point to each time when testing the interface.
Because it is the mode of modifying the data source, each time you add the library, you need to restart the online service. If you want to be dynamic, data source destruction is a problem.
This is the end of the content of "how to use Spring Multi-tenant data Source Management AbstractRoutingDataSource". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.