有個項目須要做SQL Server到MySQL的數據遷移,並且兩邊的schema也有很多差別,這時候用工具去遷移就很難了,須要寫程序去控制每一個字段的變換。因而採用Spring Data JPA來作這件事,自動搞定各類DAO,並且底層的Hibernate也輕鬆支持SQL Server和MySQL的java
作這個事情的第一步就是配置兩個數據源,一個連MySQL,一個連SQL Server。不少須要支持讀寫分離多數據源的和這個相似,只會更簡單,由於只用支持MySQL就能夠。下面看代碼:mysql
application.yml的內容是:spring
spring: datasource: mssql: type: org.apache.tomcat.jdbc.pool.DataSource driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver url: jdbc:sqlserver://localhost:1433;database=old; username: sa password: password mysql: type: org.apache.tomcat.jdbc.pool.DataSource driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/new?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useSSL=false username: root password: password jpa: show-sql: false
能夠看到,很清楚的兩個數據源配置,下面來看怎樣使用這兩個配置sql
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.transaction.PlatformTransactionManager; import javax.sql.DataSource; import java.util.Properties; @Configuration public class DataSourceConfiguration { @Bean @Primary @ConfigurationProperties(prefix = "spring.datasource.mssql") public DataSource mssqlDataSource() { return DataSourceBuilder.create().build(); } @Bean @ConfigurationProperties(prefix = "spring.datasource.mysql") public DataSource mysqlDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "mssqlEntityManagerFactory") @Primary public LocalContainerEntityManagerFactoryBean mssqlEntityManagerFactory( EntityManagerFactoryBuilder builder) { LocalContainerEntityManagerFactoryBean em = builder .dataSource(mssqlDataSource()) .packages(OldBuy.class) .persistenceUnit("mssql") .build(); Properties properties = new Properties(); properties.setProperty("hibernate.physical_naming_strategy", "org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl"); em.setJpaProperties(properties); return em; } @Bean(name = "mysqlEntityManagerFactory") public LocalContainerEntityManagerFactoryBean mysqlEntityManagerFactory( EntityManagerFactoryBuilder builder) { LocalContainerEntityManagerFactoryBean em = builder .dataSource(mysqlDataSource()) .packages(Buy.class) .persistenceUnit("mysql") .build(); Properties properties = new Properties(); properties.setProperty("hibernate.physical_naming_strategy", "org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy"); em.setJpaProperties(properties); return em; } @Bean(name = "mssqlTransactionManager") @Primary PlatformTransactionManager mssqlTransactionManager(EntityManagerFactoryBuilder builder) { return new JpaTransactionManager(mssqlEntityManagerFactory(builder).getObject()); } @Bean(name = "mysqlTransactionManager") @Primary PlatformTransactionManager mysqlTransactionManager(EntityManagerFactoryBuilder builder) { return new JpaTransactionManager(mysqlEntityManagerFactory(builder).getObject()); } }
這裏主要分三塊:apache
最上面的兩個DataSource
類,根據配置文件產生數據源,注意必須一個是Primary的,否則Spring會報錯,由於找到了bean的兩個實現,默認不知道選哪一個tomcat
中間的兩個LocalContainerEntityManagerFactoryBean
則是根據兩個數據源產生對應的EntityManager
,這裏就能夠作些hibernate的特定配置了,好比取名策略、sql方言之類的app
最後兩個PlatformTransactionManager
則是根據兩個EntityManager
產生對應的事務管理器,這樣咱們才能用事務工具
如今萬事俱備,只欠東風了,也就是指定咱們哪些Repository
用上面配置好的兩套DataSource
、EntityManager
、Transaction Manager
:sqlserver
import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.transaction.annotation.EnableTransactionManagement; @Configuration @EnableTransactionManagement @EnableJpaRepositories( basePackageClasses = MsSQLXXXRepository.class, entityManagerFactoryRef = "mssqlEntityManagerFactory", transactionManagerRef = "mssqlTransactionManager" ) public class MssqlConfiguration { }
import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.transaction.annotation.EnableTransactionManagement; @Configuration @EnableTransactionManagement @EnableJpaRepositories( basePackageClasses = MySQLYYYRepository.class, entityManagerFactoryRef = "mysqlEntityManagerFactory", transactionManagerRef = "mysqlTransactionManager" ) public class MysqlConfiguration { }
上面就是兩種Repository
的配置了,很簡單。basePackageClasses
指向的那個類,同一個包裏面的全部Repository
都會用這個數據源的配置ui