Spring Boot Cấu hình và sử dụng hai nguồn dữ liệu


206

Làm cách nào để định cấu hình và sử dụng hai nguồn dữ liệu?

Ví dụ ở đây là những gì tôi có cho nguồn dữ liệu đầu tiên:

ứng dụng

#first db
spring.datasource.url = [url]
spring.datasource.username = [username]
spring.datasource.password = [password]
spring.datasource.driverClassName = oracle.jdbc.OracleDriver

#second db ...

Lớp ứng dụng

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

Làm cách nào để sửa đổi application.propertiesđể thêm nguồn dữ liệu khác? Làm thế nào để tôi tự động cho nó được sử dụng bởi một kho lưu trữ khác nhau?

Câu trả lời:


237

Bạn đi đây

#first db
spring.datasource.url = [url]
spring.datasource.username = [username]
spring.datasource.password = [password]
spring.datasource.driverClassName = oracle.jdbc.OracleDriver

#second db ...
spring.secondDatasource.url = [url]
spring.secondDatasource.username = [username]
spring.secondDatasource.password = [password]
spring.secondDatasource.driverClassName = oracle.jdbc.OracleDriver


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

@Bean
@ConfigurationProperties(prefix="spring.secondDatasource")
public DataSource secondaryDataSource() {
    return DataSourceBuilder.create().build();
}

19
Hãy xem baeldung.com/spring-data-jpa-mult Môn-cơ sở dữ liệu mô tả chính những gì bạn đang tìm kiếm.
K. Siva Prasad Reddy

Đôi khi bạn có thể cần gán nguồn dữ liệu, giao dịchQuản lý và SqlSessionFactory làm chính.
Đại Kaixian

@K. Siva Prasad Reddy OK nhưng tôi có 2 kho lưu trữ JPAR khác nhau - làm thế nào để Spring Boot biết nên sử dụng DataSource nào? Mỗi shoudl JPAR sử dụng cơ sở dữ liệu khác nhau
Matley

2
@Matley Bài đăng trên blog này javadevjournal.com/spring-boot/ từ có thể là những gì bạn đang tìm kiếm.
K. Siva Prasad Reddy

@ K.SivaPrasadReddy để cấu hình nhiều nguồn dữ liệu tất cả các cơ sở dữ liệu phải ở trong cùng một máy chủ?
KR ngày

44

Cập nhật 2018-01-07 với Spring Boot 1.5.8.RELEASE

Hầu hết các câu trả lời không cung cấp cách sử dụng chúng (như chính nguồn dữ liệu và giao dịch), chỉ có cách định cấu hình chúng.

Bạn có thể xem ví dụ có thể chạy được và một số lời giải thích trong https://www.surasint.com/spring-boot-with-multipl-database-example/

Tôi đã sao chép một số mã ở đây.

Trước tiên, bạn phải thiết lập application.properations như thế này

#Database
database1.datasource.url=jdbc:mysql://localhost/testdb
database1.datasource.username=root
database1.datasource.password=root
database1.datasource.driver-class-name=com.mysql.jdbc.Driver

database2.datasource.url=jdbc:mysql://localhost/testdb2
database2.datasource.username=root
database2.datasource.password=root
database2.datasource.driver-class-name=com.mysql.jdbc.Driver

Sau đó, xác định họ là nhà cung cấp (@Bean) như thế này:

@Bean(name = "datasource1")
@ConfigurationProperties("database1.datasource")
@Primary
public DataSource dataSource(){
    return DataSourceBuilder.create().build();
}

@Bean(name = "datasource2")
@ConfigurationProperties("database2.datasource")
public DataSource dataSource2(){
    return DataSourceBuilder.create().build();
}

Lưu ý rằng tôi có @Bean (name = "dataource1") và @Bean (name = "dataource2"), sau đó bạn có thể sử dụng nó khi chúng tôi cần nguồn dữ liệu như @Qualifier ("dataource1") và @Qualifier ("dataource2"), ví dụ

@Qualifier("datasource1")
@Autowired
private DataSource dataSource;

Nếu bạn quan tâm đến giao dịch, bạn phải xác định DataSourceTransactionManager cho cả hai, như thế này:

@Bean(name="tm1")
@Autowired
@Primary
DataSourceTransactionManager tm1(@Qualifier ("datasource1") DataSource datasource) {
    DataSourceTransactionManager txm  = new DataSourceTransactionManager(datasource);
    return txm;
}

@Bean(name="tm2")
@Autowired
DataSourceTransactionManager tm2(@Qualifier ("datasource2") DataSource datasource) {
    DataSourceTransactionManager txm  = new DataSourceTransactionManager(datasource);
    return txm;
}

Sau đó, bạn có thể sử dụng nó như

@Transactional //this will use the first datasource because it is @primary

hoặc là

@Transactional("tm2")

Điều này là đủ. Xem ví dụ và chi tiết trong liên kết ở trên.


Xin chào @Surasin Tancharoen, chúng tôi đang cố gắng giữ hai nguồn dữ liệu có cùng dữ liệu để nếu một lỗi, ứng dụng sẽ chạy trên nguồn dữ liệu khác. Cách tiếp cận trên sẽ ổn chứ?
Arun Sudhakaran

24

Tham khảo tài liệu chính thức


Tạo nhiều nguồn dữ liệu hoạt động giống như tạo nguồn đầu tiên. Bạn có thể muốn đánh dấu một trong số chúng là @Primary nếu bạn đang sử dụng cấu hình tự động mặc định cho JDBC hoặc JPA (sau đó chúng sẽ được chọn bởi bất kỳ mũi tiêm @Autowired nào).

@Bean
@Primary
@ConfigurationProperties(prefix="datasource.primary")
public DataSource primaryDataSource() {
    return DataSourceBuilder.create().build();
}

@Bean
@ConfigurationProperties(prefix="datasource.secondary")
public DataSource secondaryDataSource() {
    return DataSourceBuilder.create().build();
}

8

Tôi cũng phải thiết lập kết nối với 2 nguồn dữ liệu từ ứng dụng Spring Boot và điều đó không dễ dàng - giải pháp được đề cập trong tài liệu Spring Boot không hoạt động. Sau một thời gian dài tìm hiểu qua internet, tôi đã làm cho nó hoạt động và ý tưởng chính được lấy từ bài viết này và một loạt các địa điểm khác.

Giải pháp sau đây được viết bằng Kotlin và hoạt động với Spring Boot 2.1.3Hibernate Core 5.3.7 . Vấn đề chính là không đủ để thiết lập các cấu hình DataSource khác nhau , nhưng cũng cần phải cấu hình EntityManagerFactoryTransactionManager cho cả hai cơ sở dữ liệu.

Đây là cấu hình cho cơ sở dữ liệu (Chính) đầu tiên:

@Configuration
@EnableJpaRepositories(
    entityManagerFactoryRef = "firstDbEntityManagerFactory",
    transactionManagerRef = "firstDbTransactionManager",
    basePackages = ["org.path.to.firstDb.domain"]
)
@EnableTransactionManagement
class FirstDbConfig {

    @Bean
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource.firstDb")
    fun firstDbDataSource(): DataSource {
        return DataSourceBuilder.create().build()
    }

    @Primary
    @Bean(name = ["firstDbEntityManagerFactory"])
    fun firstDbEntityManagerFactory(
        builder: EntityManagerFactoryBuilder,
        @Qualifier("firstDbDataSource") dataSource: DataSource
    ): LocalContainerEntityManagerFactoryBean {
        return builder
            .dataSource(dataSource)
            .packages(SomeEntity::class.java)
            .persistenceUnit("firstDb")
            // Following is the optional configuration for naming strategy
            .properties(
                singletonMap(
                    "hibernate.naming.physical-strategy",
                    "org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl"
                )
            )
            .build()
    }

    @Primary
    @Bean(name = ["firstDbTransactionManager"])
    fun firstDbTransactionManager(
        @Qualifier("firstDbEntityManagerFactory") firstDbEntityManagerFactory: EntityManagerFactory
    ): PlatformTransactionManager {
        return JpaTransactionManager(firstDbEntityManagerFactory)
    }
}

Và đây là cấu hình cho cơ sở dữ liệu thứ hai:

@Configuration
@EnableJpaRepositories(
    entityManagerFactoryRef = "secondDbEntityManagerFactory",
    transactionManagerRef = "secondDbTransactionManager",
    basePackages = ["org.path.to.secondDb.domain"]
)
@EnableTransactionManagement
class SecondDbConfig {

    @Bean
    @ConfigurationProperties("spring.datasource.secondDb")
    fun secondDbDataSource(): DataSource {
        return DataSourceBuilder.create().build()
    }

    @Bean(name = ["secondDbEntityManagerFactory"])
    fun secondDbEntityManagerFactory(
        builder: EntityManagerFactoryBuilder,
        @Qualifier("secondDbDataSource") dataSource: DataSource
    ): LocalContainerEntityManagerFactoryBean {
        return builder
            .dataSource(dataSource)
            .packages(EntityFromSecondDb::class.java)
            .persistenceUnit("secondDb")
            .build()
    }

    @Bean(name = ["secondDbTransactionManager"])
    fun secondDbTransactionManager(
        @Qualifier("secondDbEntityManagerFactory") secondDbEntityManagerFactory: EntityManagerFactory
    ): PlatformTransactionManager {
        return JpaTransactionManager(secondDbEntityManagerFactory)
    }
}

Các thuộc tính cho nguồn dữ liệu là như thế này:

spring.datasource.firstDb.jdbc-url=
spring.datasource.firstDb.username=
spring.datasource.firstDb.password=

spring.datasource.secondDb.jdbc-url=
spring.datasource.secondDb.username=
spring.datasource.secondDb.password=

Vấn đề với các thuộc tính là tôi phải xác định jdbc-url thay vì url vì nếu không tôi có ngoại lệ.

ps Ngoài ra, bạn có thể có các sơ đồ đặt tên khác nhau trong cơ sở dữ liệu của bạn, đó là trường hợp đối với tôi. Vì Hibernate 5 không hỗ trợ tất cả các chương trình đặt tên trước đó, tôi đã phải sử dụng giải pháp từ câu trả lời này - có lẽ nó cũng sẽ giúp được ai đó.


1
Tôi đã có vấn đề với việc đặt tên thực thể và bảng. Và nó đã giúp tôi cùng với câu trả lời của bạn:mapOf("hibernate.physical_naming_strategy" to "org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy", "hibernate.implicit_naming_strategy" to "org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy" )
rvit34

3

Đây là giải pháp hoàn chỉnh

#First Datasource (DB1)
db1.datasource.url: url
db1.datasource.username:user
db1.datasource.password:password

#Second Datasource (DB2)
db2.datasource.url:url
db2.datasource.username:user
db2.datasource.password:password

Vì chúng ta sẽ có quyền truy cập hai cơ sở dữ liệu khác nhau (db1, db2), chúng ta cần định cấu hình riêng từng cấu hình nguồn dữ liệu như:

public class DB1_DataSource {
@Autowired
private Environment env;
@Bean
@Primary
public LocalContainerEntityManagerFactoryBean db1EntityManager() {
    LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
    em.setDataSource(db1Datasource());
    em.setPersistenceUnitName("db1EntityManager");
    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    em.setJpaVendorAdapter(vendorAdapter);
    HashMap<string, object=""> properties = new HashMap<>();
    properties.put("hibernate.dialect",
            env.getProperty("hibernate.dialect"));
    properties.put("hibernate.show-sql",
            env.getProperty("jdbc.show-sql"));
    em.setJpaPropertyMap(properties);
    return em;
}

@Primary
@Bean
public DataSource db1Datasource() {

    DriverManagerDataSource dataSource
            = new DriverManagerDataSource();
    dataSource.setDriverClassName(
            env.getProperty("jdbc.driver-class-name"));
    dataSource.setUrl(env.getProperty("db1.datasource.url"));
    dataSource.setUsername(env.getProperty("db1.datasource.username"));
    dataSource.setPassword(env.getProperty("db1.datasource.password"));

    return dataSource;
}

@Primary
@Bean
public PlatformTransactionManager db1TransactionManager() {

    JpaTransactionManager transactionManager
            = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(
            db1EntityManager().getObject());
    return transactionManager;
}
}

Nguồn dữ liệu thứ hai:

public class DB2_DataSource {

@Autowired
private Environment env;

@Bean
public LocalContainerEntityManagerFactoryBean db2EntityManager() {
    LocalContainerEntityManagerFactoryBean em
            = new LocalContainerEntityManagerFactoryBean();
    em.setDataSource(db2Datasource());
    em.setPersistenceUnitName("db2EntityManager");
    HibernateJpaVendorAdapter vendorAdapter
            = new HibernateJpaVendorAdapter();
    em.setJpaVendorAdapter(vendorAdapter);
    HashMap<string, object=""> properties = new HashMap<>();
    properties.put("hibernate.dialect",
            env.getProperty("hibernate.dialect"));
    properties.put("hibernate.show-sql",
            env.getProperty("jdbc.show-sql"));
    em.setJpaPropertyMap(properties);
    return em;
}

@Bean
public DataSource db2Datasource() {
    DriverManagerDataSource dataSource
            = new DriverManagerDataSource();
    dataSource.setDriverClassName(
            env.getProperty("jdbc.driver-class-name"));
    dataSource.setUrl(env.getProperty("db2.datasource.url"));
    dataSource.setUsername(env.getProperty("db2.datasource.username"));
    dataSource.setPassword(env.getProperty("db2.datasource.password"));

    return dataSource;
}

@Bean
public PlatformTransactionManager db2TransactionManager() {
    JpaTransactionManager transactionManager
            = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(
            db2EntityManager().getObject());
    return transactionManager;
}
}

Ở đây bạn có thể tìm thấy ví dụ hoàn chỉnh trên blog của tôi: Spring Boot với nhiều cấu hình nguồn dữ liệu


2
# Here '1stDB' is the database name
spring.datasource.url=jdbc:mysql://localhost/A
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver


# Here '2ndDB' is the database name
spring.second-datasourcee.url=jdbc:mysql://localhost/B
spring.second-datasource.username=root
spring.second-datasource.password=root
spring.second-datasource.driver-class-name=com.mysql.jdbc.Driver


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

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

1

Tôi đã sử dụng ngăn xếp công nghệ mybatis - springboot 2.0, giải pháp:

//application.properties - start
    sp.ds1.jdbc-url=jdbc:mysql://localhost:3306/mydb?useSSL=false
    sp.ds1.username=user
    sp.ds1.password=pwd
    sp.ds1.testWhileIdle=true
    sp.ds1.validationQuery=SELECT 1
    sp.ds1.driverClassName=com.mysql.jdbc.Driver


    sp.ds2.jdbc-url=jdbc:mysql://localhost:4586/mydb?useSSL=false
    sp.ds2.username=user
    sp.ds2.password=pwd
    sp.ds2.testWhileIdle=true
    sp.ds2.validationQuery=SELECT 1
    sp.ds2.driverClassName=com.mysql.jdbc.Driver

//application.properties - end

//configuration class

    @Configuration
    @ComponentScan(basePackages = "com.mypkg")
    public class MultipleDBConfig {


        public static final String SQL_SESSION_FACTORY_NAME_1 = "sqlSessionFactory1";
        public static final String SQL_SESSION_FACTORY_NAME_2 = "sqlSessionFactory2";

        public static final String MAPPERS_PACKAGE_NAME_1 = "com.mypg.mymapper1";
        public static final String MAPPERS_PACKAGE_NAME_2 = "com.mypg.mymapper2";


        @Bean(name = "mysqlDb1")
        @Primary
        @ConfigurationProperties(prefix = "sp.ds1")
        public DataSource dataSource1() {
            System.out.println("db1 datasource");
            return DataSourceBuilder.create().build();
        }

        @Bean(name = "mysqlDb2")
        @ConfigurationProperties(prefix = "sp.ds2")
        public DataSource dataSource2() {
            System.out.println("db2 datasource");
            return  DataSourceBuilder.create().build();
        }

        @Bean(name = SQL_SESSION_FACTORY_NAME_1)
        @Primary
        public SqlSessionFactory sqlSessionFactory1(@Qualifier("mysqlDb1") DataSource dataSource1) throws Exception {
            System.out.println("sqlSessionFactory1");
            SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
            sqlSessionFactoryBean.setTypeHandlersPackage(MAPPERS_PACKAGE_NAME_1);
            sqlSessionFactoryBean.setDataSource(dataSource1);
            SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBean.getObject();
            sqlSessionFactory.getConfiguration().setMapUnderscoreToCamelCase(true);
            sqlSessionFactory.getConfiguration().setJdbcTypeForNull(JdbcType.NULL);
            return sqlSessionFactory;
        }

        @Bean(name = SQL_SESSION_FACTORY_NAME_2)
        public SqlSessionFactory sqlSessionFactory2(@Qualifier("mysqlDb2") DataSource dataSource2) throws Exception {
            System.out.println("sqlSessionFactory2");
            SqlSessionFactoryBean diSqlSessionFactoryBean = new SqlSessionFactoryBean();
            diSqlSessionFactoryBean.setTypeHandlersPackage(MAPPERS_PACKAGE_NAME_2);
            diSqlSessionFactoryBean.setDataSource(dataSource2);
            SqlSessionFactory sqlSessionFactory = diSqlSessionFactoryBean.getObject();
            sqlSessionFactory.getConfiguration().setMapUnderscoreToCamelCase(true);
            sqlSessionFactory.getConfiguration().setJdbcTypeForNull(JdbcType.NULL);
            return sqlSessionFactory;
        }

        @Bean
        @Primary
        public MapperScannerConfigurer mapperScannerConfigurer1() {
            System.out.println("mapperScannerConfigurer1");
            MapperScannerConfigurer configurer = new MapperScannerConfigurer();
            configurer.setBasePackage(MAPPERS_PACKAGE_NAME_1);
            configurer.setSqlSessionFactoryBeanName(SQL_SESSION_FACTORY_NAME_1);
            return configurer;
        }

        @Bean
        public MapperScannerConfigurer mapperScannerConfigurer2() {
            System.out.println("mapperScannerConfigurer2");
            MapperScannerConfigurer configurer = new MapperScannerConfigurer();
            configurer.setBasePackage(MAPPERS_PACKAGE_NAME_2);
            configurer.setSqlSessionFactoryBeanName(SQL_SESSION_FACTORY_NAME_2);
            return configurer;
        }



    }

Lưu ý: 1) @Primary -> @primary

2) ---. "Jdbc-url" trong thuộc tính -> Sau khi di chuyển Spring Boot 2.0: jdbcUrl được yêu cầu với driverClassName


1

Chú thích @Primary khi được sử dụng đối với một phương thức như dưới đây hoạt động tốt nếu hai nguồn dữ liệu nằm trên cùng một vị trí / máy chủ db.

@Bean(name = "datasource1")
@ConfigurationProperties("database1.datasource")
@Primary
public DataSource dataSource(){
  return DataSourceBuilder.create().build();
}

@Bean(name = "datasource2")
@ConfigurationProperties("database2.datasource")
public DataSource dataSource2(){
  return DataSourceBuilder.create().build();
}

Nếu các nguồn dữ liệu trên các máy chủ khác nhau, tốt hơn là sử dụng @Component cùng với chú thích @Primary . Đoạn mã sau hoạt động tốt trên hai nguồn dữ liệu khác nhau tại các vị trí khác nhau

database1.datasource.url = jdbc:mysql://127.0.0.1:3306/db1
database1.datasource.username = root
database1.datasource.password = mysql
database1.datasource.driver-class-name=com.mysql.jdbc.Driver

database2.datasource1.url = jdbc:mysql://192.168.113.51:3306/db2
database2.datasource1.username = root
database2.datasource1.password = mysql
database2.datasource1.driver-class-name=com.mysql.jdbc.Driver

@Configuration
@Primary
@Component
@ComponentScan("com.db1.bean")
class DBConfiguration1{
    @Bean("db1Ds")
    @ConfigurationProperties(prefix="database1.datasource")
    public DataSource primaryDataSource() {
        return DataSourceBuilder.create().build();
    }

}

@Configuration
@Component
@ComponentScan("com.db2.bean")
class DBConfiguration2{
    @Bean("db2Ds")
    @ConfigurationProperties(prefix="database2.datasource1")
    public DataSource primaryDataSource() {
        return DataSourceBuilder.create().build();
    }

}

1

Yêu cầu của tôi hơi khác nhau nhưng sử dụng hai nguồn dữ liệu.

Tôi đã sử dụng hai nguồn dữ liệu cho cùng một thực thể JPA từ cùng một gói. Một để thực hiện DDL khi máy chủ khởi động để tạo / cập nhật bảng và một cái khác dành cho DML khi chạy.

Kết nối DDL phải được đóng lại sau khi các câu lệnh DDL được thực thi, để ngăn việc sử dụng thêm các siêu dự án người dùng ở bất cứ đâu trong mã.

Tính chất

spring.datasource.url=jdbc:postgresql://Host:port
ddl.user=ddluser
ddl.password=ddlpassword
dml.user=dmluser
dml.password=dmlpassword
spring.datasource.driver-class-name=org.postgresql.Driver

Các lớp cấu hình nguồn dữ liệu

// Lớp cấu hình thứ 1 cho nguồn dữ liệu DDL

  public class DatabaseDDLConfig {
        @Bean
        public LocalContainerEntityManagerFactoryBean ddlEntityManagerFactoryBean() {
            LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
            PersistenceProvider persistenceProvider = new 
            org.hibernate.jpa.HibernatePersistenceProvider();
            entityManagerFactoryBean.setDataSource(ddlDataSource());
            entityManagerFactoryBean.setPackagesToScan(new String[] { 
            "com.test.two.data.sources"});
            HibernateJpaVendorAdapter vendorAdapter = new 
            HibernateJpaVendorAdapter();
            entityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter);
            HashMap<String, Object> properties = new HashMap<>();
            properties.put("hibernate.dialect", 
            "org.hibernate.dialect.PostgreSQLDialect");
            properties.put("hibernate.physical_naming_strategy", 
            "org.springframework.boot.orm.jpa.hibernate.
            SpringPhysicalNamingStrategy");
            properties.put("hibernate.implicit_naming_strategy", 
            "org.springframework.boot.orm.jpa.hibernate.
            SpringImplicitNamingStrategy");
            properties.put("hibernate.hbm2ddl.auto", "update");
            entityManagerFactoryBean.setJpaPropertyMap(properties);
            entityManagerFactoryBean.setPersistenceUnitName("ddl.config");
            entityManagerFactoryBean.setPersistenceProvider(persistenceProvider);
            return entityManagerFactoryBean;
        }


    @Bean
    public DataSource ddlDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(env.getProperty("spring.datasource.driver-class-name"));
        dataSource.setUrl(env.getProperty("spring.datasource.url"));
        dataSource.setUsername(env.getProperty("ddl.user");
        dataSource.setPassword(env.getProperty("ddl.password"));
        return dataSource;
    }

    @Bean
    public PlatformTransactionManager ddlTransactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(ddlEntityManagerFactoryBean().getObject());
        return transactionManager;
    }
}

// Lớp cấu hình thứ 2 cho nguồn dữ liệu DML

public class DatabaseDMLConfig {

    @Bean
    @Primary
    public LocalContainerEntityManagerFactoryBean dmlEntityManagerFactoryBean() {
        LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
        PersistenceProvider persistenceProvider = new org.hibernate.jpa.HibernatePersistenceProvider();
        entityManagerFactoryBean.setDataSource(dmlDataSource());
        entityManagerFactoryBean.setPackagesToScan(new String[] { "com.test.two.data.sources" });
        JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        entityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter);
        entityManagerFactoryBean.setJpaProperties(defineJpaProperties());
        entityManagerFactoryBean.setPersistenceUnitName("dml.config");
        entityManagerFactoryBean.setPersistenceProvider(persistenceProvider);
        return entityManagerFactoryBean;
    }

    @Bean
    @Primary
    public DataSource dmlDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(env.getProperty("spring.datasource.driver-class-name"));
        dataSource.setUrl(envt.getProperty("spring.datasource.url"));
        dataSource.setUsername("dml.user");
        dataSource.setPassword("dml.password");
        return dataSource;
    }

    @Bean
    @Primary
    public PlatformTransactionManager dmlTransactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(dmlEntityManagerFactoryBean().getObject());
        return transactionManager;
    }


  }

// Sử dụng các nguồn dữ liệu DDL trong mã.

public class DDLServiceAtStartup {

//Import persistence unit ddl.config for ddl purpose.

@PersistenceUnit(unitName = "ddl.config")
private EntityManagerFactory entityManagerFactory;

public void executeDDLQueries() throws ContentServiceSystemError {
    try {
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        entityManager.getTransaction().begin();
        entityManager.createNativeQuery("query to create/update table").executeUpdate();
        entityManager.flush();
        entityManager.getTransaction().commit();
        entityManager.close();

        //Close the ddl data source to avoid from further use in code.
        entityManagerFactory.close();
    } catch(Exception ex) {}
}

// Sử dụng nguồn dữ liệu DML trong mã.

public class DDLServiceAtStartup {
  @PersistenceUnit(unitName = "dml.config")
  private EntityManagerFactory entityManagerFactory;

  public void createRecord(User user) {
     userDao.save(user);
  }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.