1. 程式人生 > >spring boot 多資料庫配置問題

spring boot 多資料庫配置問題

application.yml配置:

spring:   jpa:     show-sql: true   application:     name: xxx   thymeleaf:     cache: false #thymeleaf     mode: LEGACYHTML5   datasource:       oracle2:         type: com.alibaba.druid.pool.DruidDataSource         name: oracle2         # 初始化大小,最小,最大         initialSize: 5 #       minIdle: 5         maxActive: 20         # 配置獲取連線等待超時的時間        maxWait: 60000         # 配置間隔多久才進行一次檢測,檢測需要關閉的空閒連線,單位是毫秒         timeBetweenEvictionRunsMillis: 60000         # 配置一個連線在池中最小生存的時間,單位是毫秒          minEvictableIdleTimeMillis: 40000         validationQuery: SELECT 1 FROM DUAL         validationQueryTimeout: 10000         testWhileIdle: true         testOnBorrow: false         testOnReturn: false         # 開啟PSCache,並且指定每個連線上PSCache的大小          poolPreparedStatements: true         maxPoolPreparedStatementPerConnectionSize: 20         filters: stat,wall         # 通過connectProperties屬性來開啟mergeSql功能;慢SQL記錄         connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000         # 合併多個DruidDataSource的監控資料         useGlobalDataSourceStat: true          driver-class-name: oracle.jdbc.driver.OracleDriver         url: jdbc:oracle:thin:@192.168.1.102:1521:orcl         username: xx         password: xx       oracle1:         type: com.alibaba.druid.pool.DruidDataSource         name: oracle1         # 初始化大小,最小,最大         initialSize: 5         minIdle: 5         maxActive: 20         # 配置獲取連線等待超時的時間         maxWait: 60000         # 配置間隔多久才進行一次檢測,檢測需要關閉的空閒連線,單位是毫秒          timeBetweenEvictionRunsMillis: 60000         # 配置一個連線在池中最小生存的時間,單位是毫秒          minEvictableIdleTimeMillis: 40000         validationQuery: SELECT 1 FROM DUAL         validationQueryTimeout: 10000         testWhileIdle: true         testOnBorrow: false         testOnReturn: false         # 開啟PSCache,並且指定每個連線上PSCache的大小          poolPreparedStatements: true         maxPoolPreparedStatementPerConnectionSize: 20         filters: stat,wall         # 通過connectProperties屬性來開啟mergeSql功能;慢SQL記錄         connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000         # 合併多個DruidDataSource的監控資料         useGlobalDataSourceStat: true          driver-class-name: oracle.jdbc.driver.OracleDriver         url: "jdbc:oracle:thin:@192.168.1.103:1521:orcl"         username: xx         password: xx       mysql1:         type: com.alibaba.druid.pool.DruidDataSource        # 初始化大小,最小,最大         name: mysql1         initialSize: 5         minIdle: 5         maxActive: 20         # 配置獲取連線等待超時的時間         maxWait: 60000         # 配置間隔多久才進行一次檢測,檢測需要關閉的空閒連線,單位是毫秒          timeBetweenEvictionRunsMillis: 60000         # 配置一個連線在池中最小生存的時間,單位是毫秒          minEvictableIdleTimeMillis: 30         validationQuery: SELECT 1          validationQueryTimeout: 10000         testWhileIdle: true         testOnBorrow: false         testOnReturn: false         # 開啟PSCache,並且指定每個連線上PSCache的大小          poolPreparedStatements: true         maxPoolPreparedStatementPerConnectionSize: 20         filters: stat,wall         # 通過connectProperties屬性來開啟mergeSql功能;慢SQL記錄         connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000         # 合併多個DruidDataSource的監控資料         useGlobalDataSourceStat: true          driver-class-name: com.mysql.jdbc.Driver         url: "jdbc:mysql://192.168.1.103:3306/lkjbase?useUnicode=true&characterEncoding=UTF-8"         username: xx         password: xx

 DataSourcesConfig: @Configuration @EnableAutoConfiguration public class DataSourcesConfig {       @Bean(name="oracle1DataSource")     @Qualifier(value="oracle1DataSource")     @ConfigurationProperties(prefix="spring.datasource.oracle1")     public DataSource oracle1DataSource() {           return new DruidDataSource();     }       @Bean(name="oracle18DataSource")     @Qualifier(value="oracle18DataSource")     @ConfigurationProperties(prefix="spring.datasource.oracle2")     public DataSource oracle18DataSource() {         DruidDataSource datasource = new DruidDataSource();         return datasource;     }       @Primary     @Bean(name="mysql1DataSource")     @Qualifier(value="mysql1DataSource")     @ConfigurationProperties(prefix="spring.datasource.mysql1")     public DataSource mysql1DataSource() {           return new DruidDataSource();     } } Mysql1DataSourceConfig: @Configuration @EnableTransactionManagement @EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactoryMysql1",   //EntityManagerFactory引用 transactionManagerRef = "transactionManagerMysql1",      //transactionManager引用 basePackages = {"com.dxt.cloud.mysql1.repository"})                      //設定 基因網orderDiscountDataSource應用到的包 public class Mysql1DataSourceConfig {

    @Autowired     @Qualifier("mysql1DataSource")     private DataSource mysql1DataSource;

    /**      * 注入JPA配置實體      */     @Autowired     private JpaProperties jpaProperties;         @Bean         @Primary         public JpaVendorAdapter jpaVendorAdapter() {             HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();             adapter.setGenerateDdl(true);             adapter.setShowSql(true);             return adapter;         }     /**      * 通過呼叫JPA配置實體中的解析方法,解析datasource中各屬性的值      */     private Map<String,String> getVendorProperties(  DataSource dataSource){         jpaProperties.setDatabase(Database.MYSQL);         Map<String,String> map = new HashMap<>();         map.put("hibernate.dialect","org.hibernate.dialect.MySQL5Dialect");         map.put("hibernate.hbm2ddl.auto","update");         jpaProperties.setProperties(map);         return  jpaProperties.getHibernateProperties(dataSource);     }

    /**      * 配置EntityManagerFactory實體      * @param builder      * @return      實體管理工廠      * packages     掃描@Entity註釋的軟體包名稱      * persistenceUnit  永續性單元的名稱。 如果只建立一個EntityManagerFactory,你可以省略這個,但是如果在同一個應用程式中有多個,你應該給它們不同的名字      * properties       標準JPA或供應商特定配置的通用屬性。 這些屬性覆蓋建構函式中提供的任何值。      *      */     @Primary     @Bean(name = "entityManagerFactoryMysql1")     public LocalContainerEntityManagerFactoryBean entityManagerFactoryMysql1(EntityManagerFactoryBuilder builder){         return builder                 .dataSource(mysql1DataSource)                 .properties(getVendorProperties(mysql1DataSource))                 .packages(new String[]{"com.dxt.cloud.mysql1.entity"})                 .persistenceUnit("mysql1PersistenceUnit")                 .build();     }     @Primary     @Bean(name = "transactionManagerMysql1")     public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {         JpaTransactionManager manager = new JpaTransactionManager();         manager.setEntityManagerFactory(entityManagerFactory);         return manager;     }

    @Bean     public BeanPostProcessor persistenceTranslation() {         return new PersistenceAnnotationBeanPostProcessor();     }

    /**      * 配置EntityManager實體      * @param builder      * @return      實體管理器      */     @Primary     @Bean(name = "entityManagerMysql1")     public EntityManager entityManager(EntityManagerFactoryBuilder builder){         return entityManagerFactoryMysql1(builder).getObject().createEntityManager();     }

    /**      * 配置事務transactionManager      * @param builder      * @return      事務管理器      */     @Primary     @Bean(name = "transactionManagerMysql1")     public PlatformTransactionManager transactionManagerMysql1(EntityManagerFactoryBuilder builder){         return  new JpaTransactionManager(entityManagerFactoryMysql1(builder).getObject());     }

}

@Configuration @EnableTransactionManagement @EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactoryOracle1",   //EntityManagerFactory引用 transactionManagerRef = "transactionManagerOracle1",      //transactionManager引用 basePackages = {"com.dxt.cloud.oracle1.repository"})     public class Oracle1DataSourceConfig {     @Autowired     @Qualifier(value="oracle1DataSource")     private DataSource oracle1DataSource;

    /**      * 注入JPA配置實體      */     @Autowired     private JpaProperties jpaProperties;         @Bean         public JpaVendorAdapter jpaVendorAdapter() {             HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter(); //            adapter.setDatabasePlatform("org.hibernate.dialect.OracleDialect");             return adapter;         }     /**      * 通過呼叫JPA配置實體中的解析方法,解析datasource中各屬性的值      * @param dataSource    資料來源      * @return     本資料來源中各引數      */     private Map<String,String> getVendorProperties( DataSource dataSource){         jpaProperties.setDatabase(Database.ORACLE);         jpaProperties.isShowSql();          Map<String,String> map = new HashMap<>();        jpaProperties.setProperties(map);           Map<String, String> hibernateProperties = jpaProperties.getHibernateProperties(dataSource);           return hibernateProperties;     }

    /**      * 配置EntityManagerFactory實體      * @param builder      * @return      實體管理工廠      * packages     掃描@Entity註釋的軟體包名稱      * persistenceUnit  永續性單元的名稱。 如果只建立一個EntityManagerFactory,你可以省略這個,但是如果在同一個應用程式中有多個,你應該給它們不同的名字      * properties       標準JPA或供應商特定配置的通用屬性。 這些屬性覆蓋建構函式中提供的任何值。      *      */     @Bean(name = "entityManagerFactoryOracle1")     public LocalContainerEntityManagerFactoryBean entityManagerFactoryOracle1(EntityManagerFactoryBuilder builder){         return builder                 .dataSource(oracle1DataSource)                 .properties(getVendorProperties(oracle1DataSource))                 .packages(new String[]{"com.dxt.cloud.oracle1.entity"})                 .persistenceUnit("oracle1PersistenceUnit")                 .build();     }     @Bean(name = "transactionManagerOracle1")     public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {         JpaTransactionManager manager = new JpaTransactionManager();         manager.setEntityManagerFactory(entityManagerFactory);         return manager;     }

    @Bean     public BeanPostProcessor persistenceTranslation() {         return new PersistenceAnnotationBeanPostProcessor();     }

    /**      * 配置EntityManager實體      * @param builder      * @return      實體管理器      */     @Bean(name = "entityManagerOracle1")     public EntityManager entityManager(EntityManagerFactoryBuilder builder){         return entityManagerFactoryOracle1(builder).getObject().createEntityManager();     }

    /**      * 配置事務transactionManager      * @param builder      * @return      事務管理器      */    @Bean(name = "transactionManagerOracle1")     public PlatformTransactionManager transactionManagerOracle1(EntityManagerFactoryBuilder builder){        return  new JpaTransactionManager(entityManagerFactoryOracle1(builder).getObject());     } }

@Configuration @EnableTransactionManagement @EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactoryOracle18",   //EntityManagerFactory引用 transactionManagerRef = "transactionManagerOracle1",      //transactionManager引用 basePackages = {"com.dxt.cloud.oracle18.repository"})     public class Oracle18DataSourceConfig {     @Autowired     @Qualifier(value="oracle18DataSource")     private DataSource oracle18DataSource;

    /**      * 注入JPA配置實體      */     @Autowired     private JpaProperties jpaProperties;         @Bean         public JpaVendorAdapter jpaVendorAdapter() {             HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();             return adapter;         }     /**      * 通過呼叫JPA配置實體中的解析方法,解析datasource中各屬性的值      */         private Map<String,String> getVendorProperties( DataSource dataSource){         jpaProperties.setDatabase(Database.ORACLE);         jpaProperties.isShowSql();                   Map<String,String> map = new HashMap<>();  map.put("hibernate.physical_naming_strategy","org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl");        jpaProperties.setProperties(map);           Map<String, String> hibernateProperties = jpaProperties.getHibernateProperties(dataSource);           return hibernateProperties;     }

    /**      * 配置EntityManagerFactory實體      * @param builder      * @return      實體管理工廠      * packages     掃描@Entity註釋的軟體包名稱      * persistenceUnit  永續性單元的名稱。 如果只建立一個EntityManagerFactory,你可以省略這個,但是如果在同一個應用程式中有多個,你應該給它們不同的名字      * properties       標準JPA或供應商特定配置的通用屬性。 這些屬性覆蓋建構函式中提供的任何值。      *      */     @Bean(name = "entityManagerFactoryOracle18")     public LocalContainerEntityManagerFactoryBean entityManagerFactoryOracle18(EntityManagerFactoryBuilder builder){         return builder                 .dataSource(oracle18DataSource)                 .properties(getVendorProperties(oracle18DataSource))                 .packages(new String[]{"com.dxt.cloud.oracle18.entity"})                 .persistenceUnit("oracle18PersistenceUnit")                 .build();     }     @Bean(name = "transactionManagerOracle18")     public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {         JpaTransactionManager manager = new JpaTransactionManager();         manager.setEntityManagerFactory(entityManagerFactory);         return manager;     }

    @Bean     public BeanPostProcessor persistenceTranslation() {         return new PersistenceAnnotationBeanPostProcessor();     }

    /**      * 配置EntityManager實體      * @param builder      * @return      實體管理器      */     @Bean(name = "entityManagerOracle18")     public EntityManager entityManager(EntityManagerFactoryBuilder builder){         return entityManagerFactoryOracle18(builder).getObject().createEntityManager();     }

    /**      * 配置事務transactionManager      * @param builder      * @return      事務管理器      */    @Bean(name = "transactionManagerOracle18")    public PlatformTransactionManager transactionManagerOracle18(EntityManagerFactoryBuilder builder){        return  new JpaTransactionManager(entityManagerFactoryOracle1(builder).getObject());     } }  

啟動日誌:

2018-11-04 07:47:16 [ERROR] - Properties configuration failed validation 2018-11-04 07:47:16 [ERROR] - Field error in object 'spring.datasource.oracle2' on field 'driverClassName': rejected value [oracle.jdbc.driver.OracleDriver]; codes [methodInvocation.spring.datasource.oracle2.driverClassName,methodInvocation.driverClassName,methodInvocation.java.lang.String,methodInvocation]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [spring.datasource.oracle2.driverClassName,driverClassName]; arguments []; default message [driverClassName]]; default message [Property 'driverClassName' threw exception; nested exception is java.lang.UnsupportedOperationException] 2018-11-04 07:47:16 [ERROR] - Field error in object 'spring.datasource.oracle2' on field 'url': rejected value [jdbc:oracle:thin:@192.168.1.102:1521:orcl]; codes [methodInvocation.spring.datasource.oracle2.url,methodInvocation.url,methodInvocation.java.lang.String,methodInvocation]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [spring.datasource.oracle2.url,url]; arguments []; default message [url]]; default message [Property 'url' threw exception; nested exception is java.lang.UnsupportedOperationException] 2018-11-04 07:47:16 [ERROR] - Field error in object 'spring.datasource.oracle2' on field 'username': rejected value [tj18d]; codes [methodInvocation.spring.datasource.oracle2.username,methodInvocation.username,methodInvocation.java.lang.String,methodInvocation]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [spring.datasource.oracle2.username,username]; arguments []; default message [username]]; default message [Property 'username' threw exception; nested exception is java.lang.UnsupportedOperationException] 2018-11-04 07:47:16 [WARN] - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'oracle18DataSource': Could not bind properties to DruidDataSource (prefix=spring.datasource.oracle2, ignoreInvalidFields=false, ignoreUnknownFields=true, ignoreNestedProperties=false); nested exception is org.springframework.validation.BindException: org.springframework.boot.bind.RelaxedDataBinder$RelaxedBeanPropertyBindingResult: 3 errors Field error in object 'spring.datasource.oracle2' on field 'driverClassName': rejected value [oracle.jdbc.driver.OracleDriver]; codes [methodInvocation.spring.datasource.oracle2.driverClassName,methodInvocation.driverClassName,methodInvocation.java.lang.String,methodInvocation]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [spring.datasource.oracle2.driverClassName,driverClassName]; arguments []; default message [driverClassName]]; default message [Property 'driverClassName' threw exception; nested exception is java.lang.UnsupportedOperationException] Field error in object 'spring.datasource.oracle2' on field 'url': rejected value [jdbc:oracle:thin:@192.168.1.102:1521:orcl]; codes [methodInvocation.spring.datasource.oracle2.url,methodInvocation.url,methodInvocation.java.lang.String,methodInvocation]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [spring.datasource.oracle2.url,url]; arguments []; default message [url]]; default message [Property 'url' threw exception; nested exception is java.lang.UnsupportedOperationException] Field error in object 'spring.datasource.oracle2' on field 'username': rejected value [tj18d]; codes [methodInvocation.spring.datasource.oracle2.username,methodInvocation.username,methodInvocation.java.lang.String,methodInvocation]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [spring.datasource.oracle2.username,username]; arguments []; default message [username]]; default message [Property 'username' threw exception; nested exception is java.lang.UnsupportedOperationException]  

*************************** APPLICATION FAILED TO START ***************************

Description:

Binding to target {     CreateTime:"2018-11-04 07:47:06",     ActiveCount:0,     PoolingCount:0,     CreateCount:1,     DestroyCount:1,     CloseCount:4,     ConnectCount:4,     Connections:[     ] } failed:

    Property: spring.datasource.oracle2.driverClassName     Value: oracle.jdbc.driver.OracleDriver     Reason: Property 'driverClassName' threw exception; nested exception is java.lang.UnsupportedOperationException

    Property: spring.datasource.oracle2.url     Value: jdbc:oracle:thin:@192.168.1.102:1521:orcl     Reason: Property 'url' threw exception; nested exception is java.lang.UnsupportedOperationException

    Property: spring.datasource.oracle2.username     Value: xx     Reason: Property 'username' threw exception; nested exception is java.lang.UnsupportedOperationException

Action:

Update your application's configuration

問題說明:

     1. 在配置mysql1和oracle1兩個資料庫時,專案正常啟動

     2.配置三個資料庫啟動過程中,能夠在oracle2中查出資料,日誌中有列印:資料庫查詢zcptqbzw:1。已查出zcptqbzw表中有一條資料,表示資料庫連線沒有問題

     3.從第一個Error看 [ERROR] - Properties configuration failed validation,在驗證配置上有問題