我开发了一个多租户spring引导应用程序,其中数据源通过存储在application.properties中的数据库凭证进行初始化,如下所示:
application.properties
spring.multitenancy.datasource1.url=jdbc:mysql://localhost:3306/db1
spring.multitenancy.datasource1.username=root
spring.multitenancy.datasource1.password=****
spring.multitenancy.datasource1.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
spring.multitenancy.datasource2.url=jdbc:mysql://localhost:3306/db2
spring.multitenancy.datasource2.username=root
spring.multitenancy.datasource2.password=****
spring.multitenancy.datasource2.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
spring.multitenancy.datasource3.url=jdbc:mysql://localhost:3306/db3
spring.multitenancy.datasource3.username=root
spring.multitenancy.datasource3.password=****
spring.multitenancy.datasource3.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
DataSourceConfig.java
@Configuration
public class DataSourceConfig {
@Autowired
private MultitenancyProperties multitenancyProperties;
@Bean(name = { "dataSource", "dataSource1" })
@ConfigurationProperties(prefix = "spring.multitenancy.datasource1")
public DataSource dataSource1() {
DataSourceBuilder factory = DataSourceBuilder
.create(this.multitenancyProperties.getDatasource1().getClassLoader())
.driverClassName(this.multitenancyProperties.getDatasource1().getDriverClassName())
.username(this.multitenancyProperties.getDatasource1().getUsername())
.password(this.multitenancyProperties.getDatasource1().getPassword())
.url(this.multitenancyProperties.getDatasource1().getUrl());
return factory.build();
}
@Bean(name = "dataSource2")
@ConfigurationProperties(prefix = "spring.multitenancy.datasource2")
public DataSource dataSource2() {
DataSourceBuilder factory = DataSourceBuilder
.create(this.multitenancyProperties.getDatasource2().getClassLoader())
.driverClassName(this.multitenancyProperties.getDatasource2().getDriverClassName())
.username(this.multitenancyProperties.getDatasource2().getUsername())
.password(this.multitenancyProperties.getDatasource2().getPassword())
.url(this.multitenancyProperties.getDatasource2().getUrl());
return factory.build();
}
@Bean(name = "dataSource3")
@ConfigurationProperties(prefix = "spring.multitenancy.datasource3")
public DataSource dataSource3() {
DataSourceBuilder factory = DataSourceBuilder
.create(this.multitenancyProperties.getDatasource3().getClassLoader())
.driverClassName(this.multitenancyProperties.getDatasource3().getDriverClassName())
.username(this.multitenancyProperties.getDatasource3().getUsername())
.password(this.multitenancyProperties.getDatasource3().getPassword())
.url(this.multitenancyProperties.getDatasource3().getUrl());
return factory.build();
}
}
此处,数据源通过存储在应用程序属性中的值进行初始化。
MultitenancyProperties.java
@ConfigurationProperties("spring.multitenancy")
public class MultitenancyProperties {
@NestedConfigurationProperty
private DataSourceProperties datasource1;
@NestedConfigurationProperty
private DataSourceProperties datasource2;
@NestedConfigurationProperty
private DataSourceProperties datasource3;
public DataSourceProperties getDatasource1() {
return datasource1;
}
public void setDatasource1(DataSourceProperties datasource1) {
this.datasource1 = datasource1;
}
public DataSourceProperties getDatasource2() {
return datasource2;
}
public void setDatasource2(DataSourceProperties datasource2) {
this.datasource2 = datasource2;
}
public DataSourceProperties getDatasource3() {
return datasource3;
}
public void setDatasource3(DataSourceProperties datasource3) {
this.datasource3 = datasource3;
}
}
Spring启动应用程序启动器
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableConfigurationProperties(MultitenancyProperties.class)
public class Application {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class, args);
}
}
如何通过读取存储在主数据源表中的数据库凭证以编程方式读取application.properties和其他数据源(dataSource2,dataSource3)来初始化主数据源。
答案 0 :(得分:2)
假设您的名称为DATABASECONFIG
的primay数据源中有一个数据库,并且具有以下架构:
+-----------+-----------+-----------+-----------+-----------+
| DATABASECONFIG |
+-----------+-----------+-----------+-----------+-----------+
| DB_NAME | URL | USERNAME | PASSWORD | DRIVER |
+-----------+-----------+-----------+-----------+-----------+
您可以将DataSourceConfig
课改为:
@Configuration
public class DataSourceConfig {
@Autowired
private MultitenancyProperties multitenancyProperties;
@Bean(name = { "dataSource", "dataSource1" })
@ConfigurationProperties(prefix = "spring.multitenancy.datasource1")
public DataSource dataSource1() throws SQLException {
ClassLoader classLoader = this.multitenancyProperties.getDatasource1().getClassLoader();
DataSourceBuilder factory = DataSourceBuilder
.create(this.multitenancyProperties.getDatasource1().getClassLoader())
.driverClassName(this.multitenancyProperties.getDatasource1().getDriverClassName())
.username(this.multitenancyProperties.getDatasource1().getUsername())
.password(this.multitenancyProperties.getDatasource1().getPassword())
.url(this.multitenancyProperties.getDatasource1().getUrl());
return factory.build();
}
@Bean(name = "dataSource2")
@ConfigurationProperties(prefix = "spring.multitenancy.datasource2")
public DataSource dataSource2()
throws Exception {
String dataSourceName = "datasource2";
return this.getSecondaryDataSource(dataSourceName);
}
@Bean(name = "dataSource3")
@ConfigurationProperties(prefix = "spring.multitenancy.datasource3")
public DataSource dataSource3()
throws Exception {
String dataSourceName = "datasource3";
return this.getSecondaryDataSource(dataSourceName);
}
private DataSource getSecondaryDataSource(String dataSourceName)
throws Exception {
DataSource d = this.dataSource1();
PreparedStatement preparedStatement = d.getConnection().prepareStatement("SELECT * FROM DATABASECONFIG WHERE DB_NAME = ?");
preparedStatement.setString(1, dataSourceName);
ResultSet resultSet = preparedStatement.executeQuery();
if (!resultSet.next()) {
// No result found --> throw exception
throw new Exception("Error Finding DB Config for DataSource [" + dataSourceName + "].");
}
DataSourceBuilder factory = DataSourceBuilder
.create()
.driverClassName(resultSet.getString("DRIVER"))
.username(resultSet.getString("USERNAME"))
.password(resultSet.getString("PASSWORD"))
.url(resultSet.getString("URL"));
return factory.build();
}
}
答案 1 :(得分:0)
我会做以下事情:
属性文件
spring.multitenancy.datasource1.url=jdbc:mysql://localhost:3306/db1
spring.multitenancy.datasource1.username=root
spring.multitenancy.datasource1.password=****
spring.multitenancy.datasource1.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
Spring配置
@Configuration
public class DataSourceConfig {
@ConfigurationProperties(prefix = "spring.multitenancy.datasource1")
private DataSourceProperties ds;
@Bean
public DataSource dataSource1() {
DataSourceBuilder factory = DataSourceBuilder
.create(ds.getClassLoader())
.driverClassName(ds.getDriverClassName())
.username(ds.getUsername())
.password(ds.getPassword())
.url(ds.getUrl());
return factory.build();
}
@Bean
public DataSource dataSource2() {
createFromDataSource1Conf("key2");
}
@Bean
public DataSource dataSource3() {
createFromDataSource1Conf("key3");
}
private DataSource createFromDataSource1Conf(Object configPrefix) {
// Query db and create datasources
}
}
我不太确定以这种方式使用@ConfigurationProperties会起作用,但你可以像现在一样使用它。
@ConfigurationProperties(prefix = "spring.multitenancy.datasource1")
private DataSourceProperties ds;
答案 2 :(得分:0)
将您的@Configuration类分成两部分。首先在autowire it into the second中创建主数据源;使其可用于从属数据源@Bean方法。
答案 3 :(得分:-1)
首先你可以导入commons-dbcp2.jar,然后你可以创建一个org.apache.commons.dbcp.BasicDataSource,例如,
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/housesearch");
ds.setUsername("root");
ds.setPassword("");
ds.setInitialSize(50);
ds.setMaxIdle(30);
Connection connection = ds.getConnection();
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("select * from pay_info");
if(resultSet.next()){
System.out.println(resultSet.getInt(5));
}
connection.close();
ds.close();
driverClassName,url,password和其他属性可以存储在表中。
我希望我的回答可以帮到你。