общая конфигурация для нескольких баз данных с весенней загрузкой - PullRequest
1 голос
/ 07 января 2020

Мой проект имеет несколько баз данных, имеющих одну основную базу данных и 35 других баз данных (имеющих ту же схему и ту же конфигурацию)

В настоящее время мы используем пул соединений c3p0 и jdb c для получения соединений из пула.

Я пробовал разные способы для перемещения существующей реализации в hibernate / JPA, но это приводит к тяжелому шаблонному коду, где мне нужно объявлять источники данных и dao для каждой схемы БД. (https://o7planning.org/en/11653/using-multiple-datasources-with-spring-boot-and-jpa)

Я хочу спроектировать поток БД таким образом, чтобы при запросе соединения мой класс конфигурации БД мог иметь возможность возвращать соединение JPA и Я мог бы сделать соответствующую функциональность в своем классе обслуживания

enter image description here

Дайте мне знать, если я могу сделать мой запрос понятным или любой недостаток в моем подходе

1 Ответ

0 голосов
/ 26 февраля 2020

Я нашел mulit tenancy решение путем реализации Spring Boot AbstractRoutingDatasource.

Я определил одну национальную базу данных (также как базу данных по умолчанию) и две базы данных состояний.

1) I определили все источники данных БД в следующем классе.

public class DatabaseLookupMap {

    public static Map<Object,Object> getDataSourceHashMap() {
        Map<Object,Object> dbMap = new HashMap<Object, Object>();

        DriverManagerDataSource dnational = new DriverManagerDataSource();
        dnational.setDriverClassName("org.postgresql.Driver");
        dnational.setUrl("jdbc:postgresql://127.0.0.1:5432/master");
        dnational.setUsername("postgres");
        dnational.setPassword("root");

        DriverManagerDataSource dstate1 = new DriverManagerDataSource();
        dstate1.setDriverClassName("org.postgresql.Driver");
        dstate1.setUrl("jdbc:postgresql://127.0.0.1:5432/b_22");
        dstate1.setUsername("postgres");
        dstate1.setPassword("root");

        DriverManagerDataSource dstate2 = new DriverManagerDataSource();
        dstate2.setDriverClassName("org.postgresql.Driver");
        dstate2.setUrl("jdbc:postgresql://127.0.0.1:5432/b_18");
        dstate2.setUsername("postgres");
        dstate2.setPassword("root");

        //dbnational will be marked as default state when application starts up
        dbMap.put(0, dnational);
        dbMap.put(22, dstate1);
        dbMap.put(18, dstate2);

        return dbMap;
    }
}

2) Затем, при определении bean источника данных, я должен был связать эти источники данных с пользовательским AbstractRoutingDatasource class

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@ComponentScan(basePackages = "org.nic")
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "org.nic")
public class PrintcardjobApplication {

    public static void main(String[] args) {
        SpringApplication.run(PrintcardjobApplication.class, args);
    }

    //this is used to define entityManagerFactory to the application
    @Bean
    public DataSource dataSource() {
        ClientDataSourceRouter router = new ClientDataSourceRouter();

        router.setTargetDataSources(DatabaseLookupMap.getDataSourceHashMap());
        return  router;
    }
}

3) Далее приведено определение нашего пользовательского AbstractRoutingDatasource класса

public class ClientDataSourceRouter extends AbstractRoutingDataSource{

    public static Integer currentState;


    @Override
    protected Object determineCurrentLookupKey() {

        //At application startup, current state is null
        if(currentState != null) {
            return currentState;
        }

        //in this scenario, nhps schema should be returned to application 
        return 0;
    }


}

. Это все настройки, необходимые для установки мультитантического приложения

Наконец, мы определяем наш класс Controller, Service и Entity.

@RequestMapping("/testjpa/{statecode}")
    public @ResponseBody String testJPAController(@PathVariable("statecode") String state) {
        System.out.println("statecode=>>>"+state);

        try {
            ClientDataSourceRouter.currentState = Integer.parseInt(state);

            testService.testjpa(state);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return "checking";
    }

Service Class (Изначально я использовал только JpaRepository для получения записей. Позже я обнаружил, что могу также использовать EntityManagerFactory для выполнения HQL-запросов вместо использования JpaRepository. Итак, до разработчику все, что им удобно)

@Service
@Transactional
public class TestService {

    @Autowired
    private RecordMasterDao dao;

    @Autowired
    private EntityManagerFactory factory;

    public void testjpa(String statecode) throws Exception {

        EntityManager em = factory.createEntityManager();

        Query query = em.createQuery("select a from RecordMasterEntity a where a.nhaid = :pmrssmid");
        query.setParameter("pmrssmid", "PLSNZ26M");

        RecordMasterEntity result = (RecordMasterEntity) query.getSingleResult();

        System.out.println(result);

        em.close();
        /*Optional<RecordMasterEntity> entity = dao.findById("PLSNZ26M");

        if(entity.isPresent()) {
            System.out.println(entity.get());   
        }
        else {
            System.err.println("no record found");

        }*/


    }
}

Наконец, код класса сущности

    @Entity
    @Table(name = "tablename")
    public class RecordMasterEntity {

        @Id
        private String myid;

        private String scode;

        private String sname;

        private String name_eng;

        private String yearofbirth;

        private String gender;

        private String photo;

        private String hhidtype;

        getters and setters

}

можно оптимизировать, поместив конфигурацию базы данных в файл свойств.

Надеюсь, вы найдете ответ полезным

Рекомендации:

https://www.baeldung.com/spring-abstract-routing-data-source

https://javadeveloperzone.com/spring-boot/spring-boot-jpa-multi-tenancy-example/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...