简体   繁体   中英

How to use multiple databases with spring?

i need to create web-app (with spring+mysql) which should be a little like "MySQL Workbench online" . In my application, Users will be able to create their own databases. I did it as follows:

User press (button for example) 'create new database' and after that I create a file.sql and write the following code to it:

CREATE SCHEMA 'db_name';

If user choose option "create table" i will open this file again and I will write proper code to it

After all of that when user finally finish his database i have file.sql when i have all SQL code which need to be execute in my java code... Well and the things start to get complicated, here is my question:

This is my datasource in application.properties:

spring.datasource.url=jdbc:mysql://localhost:3306/
spring.datasource.username=root
spring.datasource.password=1234

If you look at that i didnt specify database, i only choose port i have connection only to server not to a specific database. Can i do some operation on databases if i didnt specify single specific database? Before that i had that configuration:

spring.datasource.url=jdbc:mysql://localhost:3306/mydatabase
spring.datasource.username=root
spring.datasource.password=1234

Everything worked fine, for example: my select looked like that:

Select * from table1;

Can i change datasource from localhost:3306/mydatabase to: localhost:3306/ and execute that select?

Select * from mydatabase.table1;

If i can what else i need to configure? I all time have errors "No database selected".

(I need get connection only to server not to a specific database because i want to execute sql code "Create schema" in java code)

Spring Boot simplifies the configuration of datasource.

By default, Spring Boot will instantiate its default DataSource with the configuration properties prefixed by spring.datasource.*:

spring.datasource.jdbcUrl = [url]
spring.datasource.username = [username]
spring.datasource.password = [password]

We now want to keep on using the same way to configure the second DataSource, but with a different property namespace:

spring.second-datasource.jdbcUrl = [url]
spring.second-datasource.username = [username]
spring.second-datasource.password = [password]

Because we want the Spring Boot autoconfiguration to pick up those different properties (and actually instantiate two different DataSources), we'll define 2 configuration classes similar to the ones in the previous sections:

@Configuration
@PropertySource({"classpath:persistence-multiple-db-boot.properties"})
@EnableJpaRepositories(
  basePackages = "com.myProj.multipledb.dao.user",
  entityManagerFactoryRef = "userEntityManager",
  transactionManagerRef = "userTransactionManager")
public class PersistenceUserAutoConfiguration {

    @Primary
    @Bean
    @ConfigurationProperties(prefix="spring.datasource")
    public DataSource userDataSource() {
        return DataSourceBuilder.create().build();
    }
    // userEntityManager bean 

    // userTransactionManager bean
}

And then this

@Configuration
@PropertySource({"classpath:persistence-multiple-db-boot.properties"})
@EnableJpaRepositories(
  basePackages = "com.myProj.multipledb.dao.product", 
  entityManagerFactoryRef = "productEntityManager", 
  transactionManagerRef = "productTransactionManager")
public class PersistenceProductAutoConfiguration {

    @Bean
    @ConfigurationProperties(prefix="spring.second-datasource")
    public DataSource productDataSource() {
        return DataSourceBuilder.create().build();
    }

    // productEntityManager bean 

    // productTransactionManager bean
}

We have defined the data source properties inside persistence-multiple-db-boot.properties according to the Boot auto-configuration convention.

The interesting part is annotating the data source bean creation method with @ConfigurationProperties. We just need to specify the corresponding config prefix. Inside this method, we're using a DataSourceBuilder, and Spring Boot will automatically take care of the rest. But how do the configured properties actually get injected into the DataSource configuration?

When calling the build() method on the DataSourceBuilder, it'll call its private bind() method:

public T build() {
    Class<? extends DataSource> type = getType();
    DataSource result = BeanUtils.instantiateClass(type);
    maybeGetDriverClassName();
    bind(result);
    return (T) result;
}

This private method performs much of the autoconfiguration magic, binding the resolved configuration to the actual DataSource instance:

private void bind(DataSource result) {
    ConfigurationPropertySource source = new MapConfigurationPropertySource(this.properties);
    ConfigurationPropertyNameAliases aliases = new ConfigurationPropertyNameAliases();
    aliases.addAliases("url", "jdbc-url");
    aliases.addAliases("username", "user");
    Binder binder = new Binder(source.withAliases(aliases));
    binder.bind(ConfigurationPropertyName.EMPTY, Bindable.ofInstance(result));

Although we don't have to touch any of this code ourselves, it's still useful to know what's happening under the hood of the Spring Boot autoconfiguration.

Besides this, the Transaction Manager and Entity Manager beans configuration is the same as the standard Spring application.

kindly refer the below link for an example: https://medium.com/@joeclever/using-multiple-datasources-with-spring-boot-and-spring-data-6430b00c02e7

A microservices architecture solve your problem. Using Spring is more easy to create it.

In short, you will create one database (called gateway ) and other databases for your services. All requests go through the gateway to other databases.

Read this article for more information! ⬇️

https://spring.io/blog/2015/07/14/microservices-with-spring

Moreover, if you search there are more guides.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM