Spring Boot กำหนดค่าและใช้แหล่งข้อมูลสองแห่ง


207

ฉันจะกำหนดค่าและใช้แหล่งข้อมูลสองแหล่งได้อย่างไร

ตัวอย่างเช่นนี่คือสิ่งที่ฉันมีสำหรับแหล่งข้อมูลแรก:

application.properties

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

#second db ...

คลาสแอปพลิเคชัน

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

ฉันจะแก้ไขapplication.propertiesเพื่อเพิ่มแหล่งข้อมูลอื่นได้อย่างไร ฉันจะตอบกลับอัตโนมัติเพื่อใช้ที่เก็บข้อมูลอื่นได้อย่างไร

คำตอบ:


239

ไปเลย

#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
ลองดูที่baeldung.com/spring-data-jpa-multiple-databaseซึ่งอธิบายสิ่งที่คุณต้องการ
K. Siva Prasad Reddy

บางครั้งคุณอาจต้องกำหนดแหล่งข้อมูล, transactionManager และ SqlSessionFactory เป็นหลักทั้งหมด
Dai Kaixian

@K Siva Prasad Reddy ตกลง แต่ฉันมี JPARepositories ที่แตกต่างกัน 2 ตัว Spring Boot รู้ได้อย่างไรว่า DataSource จะใช้อย่างไร JPARepository ทุก shoudl ใช้ฐานข้อมูลที่แตกต่างกัน
Matley

2
@Matley โพสต์บล็อกนี้javadevjournal.com/spring-boot/ ......อาจเป็นสิ่งที่คุณกำลังมองหา
K. Siva Prasad Reddy

@ K.SivaPrasadReddy เพื่อกำหนดค่าหลายแหล่งข้อมูลฐานข้อมูลทั้งหมดควรอยู่ในเซิร์ฟเวอร์เดียวกันหรือไม่
Krish

45

อัปเดต 2018-01-07 ด้วย Spring Boot 1.5.8 ปล่อย

คำตอบส่วนใหญ่ไม่ได้ให้วิธีการใช้พวกเขา (เป็นแหล่งข้อมูลตัวเองและเป็นธุรกรรม) เพียงวิธีการกำหนดค่า

คุณสามารถดูตัวอย่าง runnable และคำอธิบายบางอย่างในhttps://www.surasint.com/spring-boot-with-multiple-databases-example/

ฉันคัดลอกรหัสบางส่วนที่นี่

ก่อนอื่นคุณต้องตั้ง application.properties แบบนี้

#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

จากนั้นกำหนดพวกเขาเป็นผู้ให้บริการ (@Bean) เช่นนี้:

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

โปรดทราบว่าฉันมี @Bean (name = "datasource1") และ @Bean (name = "datasource2") จากนั้นคุณสามารถใช้งานได้เมื่อเราต้องการแหล่งข้อมูลเป็น @Qualifier ("datasource1") และ @Qualifier ("datasource2") ตัวอย่างเช่น

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

หากคุณสนใจธุรกรรมคุณต้องกำหนด DataSourceTransactionManager สำหรับทั้งคู่เช่นนี้

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

จากนั้นคุณสามารถใช้มันเหมือน

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

หรือ

@Transactional("tm2")

นี้ควรจะเพียงพอ ดูตัวอย่างและรายละเอียดในลิงค์ด้านบน


สวัสดี @Surasin Tancharoen เราพยายามที่จะเก็บสองแหล่งข้อมูลด้วยข้อมูลเดียวกันดังนั้นหากล้มเหลวแอปพลิเคชันจะทำงานบนแหล่งข้อมูลอื่น จะเป็นวิธีการข้างต้นได้ดี?
อรุณสุดาการัน

24

อ้างถึงเอกสารทางการ


การสร้างแหล่งข้อมูลมากกว่าหนึ่งแหล่งจะทำงานเหมือนกับการสร้างแหล่งข้อมูลแรก คุณอาจต้องการทำเครื่องหมายหนึ่งในนั้นเป็น @Primary หากคุณใช้การกำหนดค่าอัตโนมัติเริ่มต้นสำหรับ JDBC หรือ JPA (จากนั้นจะถูกรับโดยการฉีด @Autowired ใด ๆ )

@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

ฉันต้องตั้งค่าการเชื่อมต่อกับ 2 แหล่งข้อมูลจากแอปพลิเคชัน Spring Boot และมันไม่ง่ายเลย - วิธีแก้ปัญหาที่กล่าวถึงในเอกสารประกอบ Spring Bootไม่ทำงาน หลังจากการขุดค้นทางอินเทอร์เน็ตมาเป็นเวลานานฉันก็ใช้งานได้และแนวคิดหลักก็มาจากบทความนี้และที่อื่น ๆ

วิธีการแก้ปัญหาต่อไปนี้ถูกเขียนในKotlinและทำงานร่วมกับฤดูใบไม้ผลิ Boot 2.1.3และHibernate หลัก 5.3.7 ปัญหาหลักคือมันไม่เพียงพอที่จะตั้งค่าการกำหนดค่าDataSource ที่แตกต่างกันแต่ยังจำเป็นต้องกำหนดค่าEntityManagerFactoryและTransactionManagerสำหรับฐานข้อมูลทั้งสอง

นี่คือการกำหนดค่าสำหรับฐานข้อมูล (หลัก) แรก:

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

และนี่คือการกำหนดค่าสำหรับฐานข้อมูลที่สอง:

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

คุณสมบัติสำหรับแหล่งข้อมูลเป็นดังนี้:

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=

ปัญหาเกี่ยวกับคุณสมบัติคือฉันต้องกำหนดjdbc-urlแทนurlเพราะไม่เช่นนั้นฉันก็มีข้อยกเว้น

ป.ล. คุณอาจมีแผนการตั้งชื่อต่างกันในฐานข้อมูลของคุณซึ่งเป็นกรณีของฉัน เนื่องจาก Hibernate 5 ไม่รองรับรูปแบบการตั้งชื่อก่อนหน้านี้ทั้งหมดฉันจึงต้องใช้วิธีแก้ปัญหาจากคำตอบนี้ - บางทีมันอาจจะช่วยใครบางคนเช่นกัน


1
ฉันมีปัญหากับการตั้งชื่อเอนทิตีและตาราง และมันก็ช่วยฉันพร้อมกับคำตอบของคุณ: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

นี่คือทางออกที่สมบูรณ์

#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

เนื่องจากเรากำลังจะเข้าถึงฐานข้อมูลที่แตกต่างกันสองฐานข้อมูล (db1, db2) เราจำเป็นต้องกำหนดค่าแต่ละแหล่งข้อมูลแยกจากกันเช่น:

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

แหล่งข้อมูลที่สอง:

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

ที่นี่คุณจะพบตัวอย่างที่สมบูรณ์ในบล็อกของฉัน: Spring Boot พร้อมการกำหนดค่าแหล่งข้อมูลหลายรายการ


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

ฉันใช้ mybatis - springboot 2.0 stack stack วิธีแก้ปัญหา:

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



    }

หมายเหตุ: 1) @Primary -> @primary

2) ---. "jdbc-url" ในคุณสมบัติ -> หลังจากการโยกย้าย Spring Boot 2.0: จำเป็นต้องใช้ jdbcUrl กับ driverClassName


1

คำอธิบายประกอบ @Primary เมื่อใช้กับวิธีการด้านล่างทำงานได้ดีถ้าแหล่งข้อมูลทั้งสองอยู่ในตำแหน่ง / เซิร์ฟเวอร์ฐานข้อมูลเดียวกัน

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

หากแหล่งข้อมูลอยู่บนเซิร์ฟเวอร์ที่แตกต่างกันควรใช้ @Component พร้อมกับคำอธิบายประกอบ@Primary ข้อมูลโค้ดต่อไปนี้ทำงานได้ดีบนแหล่งข้อมูลสองแห่งในสถานที่ต่างกัน

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

ความต้องการของฉันแตกต่างกันเล็กน้อย แต่ใช้แหล่งข้อมูลสองแห่ง

ฉันใช้แหล่งข้อมูลสองแหล่งสำหรับเอนทิตี JPA เดียวกันจากแพ็คเกจเดียวกัน หนึ่งสำหรับการดำเนินการ DDL ที่เซิร์ฟเวอร์เริ่มต้นเพื่อสร้าง / ปรับปรุงตารางและอีกคนหนึ่งสำหรับ DML ที่รันไทม์

ควรปิดการเชื่อมต่อ DDL หลังจากดำเนินการคำสั่ง DDL เพื่อป้องกันการใช้งาน preville ของผู้ใช้ขั้นสูงได้ทุกที่ในรหัส

คุณสมบัติ

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

คลาส config แหล่งข้อมูล

// คลาสการกำหนดค่าอันดับที่ 1 สำหรับแหล่งข้อมูล 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;
    }
}

// คลาสการกำหนดค่า 2nd สำหรับแหล่งข้อมูล 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;
    }


  }

// การใช้งานแหล่งข้อมูล DDL ในรหัส

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) {}
}

// การใช้งานแหล่งข้อมูล DML ในโค้ด

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

  public void createRecord(User user) {
     userDao.save(user);
  }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.