Hibernate 使用spring boot的多个数据库的通用配置

Hibernate 使用spring boot的多个数据库的通用配置,hibernate,spring-boot,jpa,multiple-databases,Hibernate,Spring Boot,Jpa,Multiple Databases,我的项目有多个数据库,其中一个主数据库和35个其他数据库(具有相同的模式和相同的配置) 现在,我们正在使用c3p0连接池,并使用jdbc从连接池获取连接 我尝试了不同的方法将现有的实现迁移到hibernate/JPA中,但这会导致繁重的样板代码,我需要为每个db模式声明数据源和dao。() 我希望以这样的方式设计db流:当请求连接时,我的db配置类应该能够返回JPA连接,并且我可以在我的服务类上执行相应的功能 让我知道我是否可以通过使用Spring BootAbstractRoutingDat

我的项目有多个数据库,其中一个主数据库和35个其他数据库(具有相同的模式和相同的配置)

现在,我们正在使用c3p0连接池,并使用jdbc从连接池获取连接

我尝试了不同的方法将现有的实现迁移到hibernate/JPA中,但这会导致繁重的样板代码,我需要为每个db模式声明数据源和dao。()

我希望以这样的方式设计db流:当请求连接时,我的db配置类应该能够返回JPA连接,并且我可以在我的服务类上执行相应的功能


让我知道我是否可以通过使用Spring Boot
AbstractRoutingDatasource实现,让我了解我的查询是否可以理解,或者我的方法是否存在任何缺陷

我定义了一个国家数据库(也是默认数据库)和两个国家数据库

1) 我已经在下面的类中定义了所有db数据源

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;
    }
}
3) 然后,下面是自定义
AbstractRoutingDatasource
类的定义

@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;
    }
}
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;
    }


}
这是设置多个应用程序所需的所有配置

最后,我们定义了控制器、服务和实体类

@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";
    }
服务类
(最初,我只使用JpaRepository来获取记录。后来,我发现我也可以使用
EntityManagerFactory
来执行HQL查询,而不是使用JpaRepository。因此,开发人员觉得方便就可以使用它)

可以通过将db配置放在属性文件上来优化代码

我希望你会发现答案很有帮助

参考资料:


我通过使用Spring Boot
AbstractRoutingDatasource
实现,找到了
多租户
解决方案

我定义了一个国家数据库(也是默认数据库)和两个国家数据库

1) 我已经在下面的类中定义了所有db数据源

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;
    }
}
3) 然后,下面是自定义
AbstractRoutingDatasource
类的定义

@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;
    }
}
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;
    }


}
这是设置多个应用程序所需的所有配置

最后,我们定义了控制器、服务和实体类

@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";
    }
服务类
(最初,我只使用JpaRepository来获取记录。后来,我发现我也可以使用
EntityManagerFactory
来执行HQL查询,而不是使用JpaRepository。因此,开发人员觉得方便就可以使用它)

可以通过将db配置放在属性文件上来优化代码

我希望你会发现答案很有帮助

参考资料:


是否希望使用应用程序中的所有数据库?到目前为止,您是如何配置c3p0驱动程序的?我猜您在代码中使用的是Sql查询?那么为什么要使用Hibernate呢?您能描述一个使用多个DAO的用例吗?您正在实现多租户吗?如果是,请阅读Hibernate文档:是否希望使用应用程序中的所有数据库?到目前为止,您是如何配置c3p0驱动程序的?我猜您在代码中使用的是Sql查询?那么为什么要使用Hibernate呢?您能描述一个使用多个DAO的用例吗?您正在实现多租户吗?如果是,请阅读Hibernate文档: