简体   繁体   中英

How to config dynamic multiple datasource with Spring boot JPA

I want to choose different datasource in run time, here is my example: There are 2 same structure MySQL table in different databases, let's say testing.io:3306/db/person and production.io:3306/db/person. I want to choose the DB according to some criteria.

Here are some pseudo codes:

The entity class

@Entity
@Data
public class person{
    @Id
    @GeneratedValue
    private Long id;
    private String name;
}

The repository of it:

   @RepositoryRestResource(collectionResourceRel = "Person", path = "Person")
public interface PersonRepository extends CrudRepository<Person, Long>{

}

The application.yml

 spring:
  datasource:
    testing:
      url: jdbc:mysql://testing.io:3306/db?useSSL=false
      username: root
      password: 1111
    production:
      url: jdbc:mysql://production.io:3306/db?useSSL=false
      username: root
      password: 2222
   driver-class-name: com.mysql.jdbc.Driver

I omit the service interface because there is only one method in it.

The controller:

   @RestController
public class PersonrController {
    @Autowired
    PersonService personService ;


    @RequestMapping(value = "/select-person", method= RequestMethod.POST)
    public String selectPerson(@RequestBody parameter) {
        /**
          class Parameter only has one field: env
        /
        return personService.select(Parameter parameter);
    }


}

The service implement:

@Service
public class PersonServiceImpl implements PersonService {
    @Autowired
    @Use("testing") // It means this repo uses the 'testing' config in the application.yml
    PersonRepository testingPersonRepo;

    @Autowired
    @Use("production") // It means this repo uses the 'production' config in the application.yml
    PersonRepository productionPersonRepo;


    @Override
    public String select(Parameter parameter){
        // dynamically use different DB with the same entity
        if (parameter.getEnv().equals("production")){
            return productionPersonRepo.findAll();
        }else{
            return testingPersonRepo.findAll();
        }

    }
}

How to config that with Spring Boot JPA elegantly ?

You should use spring profiles. At the start of the application you tell the environment the variable "spring.profiles.active" to determine if it is a testing or a production, spring.profiles.active=testing or spring.profiles.active=production

Then in your application.yml :

spring:
  profiles:
    active: testing

spring:
  datasource:
      url: jdbc:mysql://testing.io:3306/db?useSSL=false
      username: root
      password: 1111
 driver-class-name: com.mysql.jdbc.Driver

---
spring:
  profiles:
    active: production

spring:
  datasource:
      url: jdbc:mysql://production.io:3306/db?useSSL=false
      username: root
      password: 2222

This will assign your datasource the value depending on whether the profile is one or the other.

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