写在前面:
开始只是简单的想实现集成mybatis+双数据源。在网上随便找了一个博客临摹(ctrl+c,ctrl+v)。很顺利的实现了想要的功能。随后发现之前配置的jpa不好使了。所以就在网上又找了另一篇博客继续临摹。哈哈哈哈哈哈!
1、首先,不论有多少个数据源,都只能有一个主数据源(primaryDataSource)。
2、有多少个数据源就写几个数据库配置,因为只是写例子,偷个懒,两个链接是同一个服务器上面的两个数据库。
# 数据源 Frist spring.datasource.first.url=jdbc:mysql://10.10.14.199:22066/private_yxd?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC spring.datasource.first.username=root spring.datasource.first.password=DsideaL147258369 spring.datasource.first.driverClassName=com.mysql.cj.jdbc.Driver # 数据源 Second spring.datasource.second.url=jdbc:mysql://10.10.14.199:22066/yxd_test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC spring.datasource.second.username=root spring.datasource.second.password=DsideaL147258369 spring.datasource.second.driverClassName=com.mysql.cj.jdbc.Driver
3、配置数据源model,读取配置文件
import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; /** * @author yxd * @description 数据源1 * @date 2019/7/12 */ @Data @Component @ConfigurationProperties(prefix = "spring.datasource.first") public class FirstDataBaseProperties { String url; String username; String password; String driverClassName; }
import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; /** * @author yxd * @description 数据源1 * @date 2019/7/12 */ @Data @Component @ConfigurationProperties(prefix = "spring.datasource.second") public class SecondDataBaseProperties { String url; String username; String password; String driverClassName; }
上面两个类除了类名不同外,只有@ConfigurationProperties读取的配置前缀不同。
@Data标签可以省略get/set方法,也可以不加,显示的写各个字段的get/set方法方
4、配置数据源
import com.yxd.springboot.model.dataSource.FirstDataBaseProperties; import com.yxd.springboot.model.dataSource.SecondDataBaseProperties; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import javax.sql.DataSource; /** * @author * @description * @date 2019/7/13 */ @Configuration public class DataSourceConfiguration { @Autowired private FirstDataBaseProperties first; // 创建数据源 @Bean(name = "firstDS") @Qualifier("firstDS") // @ConfigurationProperties(prefix = "spring.datasource.first") @Primary public DataSource getFirstDataSource() { DataSource build = DataSourceBuilder.create() .driverClassName(first.getDriverClassName()) .url(first.getUrl()) .username(first.getUsername()) .password(first.getPassword()) .build();; return build; } @Autowired private SecondDataBaseProperties second; @Bean(name = "secondDS") @Qualifier("secondDS") // @ConfigurationProperties(prefix = "spring.datasource.second") public DataSource getSecondDataSource() { DataSource build = DataSourceBuilder.create() .driverClassName(second.getDriverClassName()) .url(second.getUrl()) .username(second.getUsername()) .password(second.getPassword()) .build();; return build; } }
数据源1和数据源2分别加载的l两个数据库配置项。@Primary是两个数据源标签的唯一区别、也就是第一步说的主数据源。
5、配置mybatis
import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.SqlSessionTemplate; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import javax.sql.DataSource; /** * @author yxd * @description 第一数据源 * @date 2019/7/12 */ @Configuration //basePackages指定了使用当前SqlSession的map路径 @MapperScan(basePackages = {"com.yxd.springboot.mapper.first"},sqlSessionTemplateRef ="firstSqlSessionTemplate") public class FirstMybatisConfig { // 创建SessionFactory @Bean(name = "firstSqlSessionFactory") @Primary public SqlSessionFactory firstSqlSessionFactory(@Qualifier("firstDS") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); bean.setMapperLocations(new PathMatchingResourcePatternResolver() .getResources("classpath:mapper/*.xml"));; return bean.getObject(); } // 创建事务管理器 @Bean("firstTransactionManger") @Primary public DataSourceTransactionManager firstTransactionManger(@Qualifier("firstDS") DataSource dataSource){ return new DataSourceTransactionManager(dataSource); } // 创建SqlSessionTemplate @Bean(name = "firstSqlSessionTemplate") @Primary public SqlSessionTemplate firstSqlSessionTemplate(@Qualifier("firstSqlSessionFactory") SqlSessionFactory sqlSessionFactory){ return new SqlSessionTemplate(sqlSessionFactory); } private Class getType(String type) { try { return Class.forName(type); } catch (ClassNotFoundException e) { e.printStackTrace(); } return null; } }
import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.SqlSessionTemplate; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import javax.sql.DataSource; /** * @author yxd * @description 第二数据源 * @date 2019/7/12 */ @Configuration @MapperScan(basePackages = "com.yxd.springboot.mapper.second",sqlSessionTemplateRef ="secondSqlSessionTemplate") public class SecondMybatisConfig { // 创建SessionFactory @Bean(name = "secondSqlSessionFactory") public SqlSessionFactory secondSqlSessionFactory(@Qualifier("secondDS") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); return bean.getObject(); } // 创建事务管理器 @Bean("secondTransactionManger") public DataSourceTransactionManager secondTransactionManger(@Qualifier("secondDS") DataSource dataSource){ return new DataSourceTransactionManager(dataSource); } // 创建SqlSessionTemplate @Bean(name = "secondSqlSessionTemplate") public SqlSessionTemplate secondSqlSessionTemplate(@Qualifier("secondSqlSessionFactory") SqlSessionFactory sqlSessionFactory){ return new SqlSessionTemplate(sqlSessionFactory); } private Class getType(String type) { try { return Class.forName(type); } catch (ClassNotFoundException e) { e.printStackTrace(); } return null; } }
a.@MapperScan,basePackages路径指定哪些mapper使用下面的配置。
b.@Qualifier("xxx")表示使用哪个数据源。对应第4步的数据源。
c.第一个配置中所有的bean都添加了@Primary,表示默认使用的配置,不能两个配置都添加该标签
6、配置Jpa
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.sql.DataSource; /** * @author * @description * @date 2019/7/13 */ @Configuration @EnableJpaRepositories(entityManagerFactoryRef ="jpaEntityManagerFactory",transactionManagerRef ="jpaTransactionManager",basePackages ="com.yxd.springboot.Repository") @EnableTransactionManagement public class JpaConfiguration { @Autowired @Qualifier("firstDS") private DataSource jpaDataSource; @Bean(name ="jpaEntityManager") @Primary public EntityManager entityManager() { return entityManagerFactory().getObject().createEntityManager(); } @Bean(name ="jpaEntityManagerFactory") @Primary public LocalContainerEntityManagerFactoryBean entityManagerFactory() { HibernateJpaVendorAdapter japVendor =new HibernateJpaVendorAdapter(); japVendor.setGenerateDdl(false); LocalContainerEntityManagerFactoryBean entityManagerFactory =new LocalContainerEntityManagerFactoryBean(); entityManagerFactory.setDataSource(jpaDataSource); entityManagerFactory.setJpaVendorAdapter(japVendor); entityManagerFactory.setPackagesToScan("com.yxd.springboot.model"); return entityManagerFactory; } @Bean(name ="jpaTransactionManager") @Primary public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) { JpaTransactionManager manager =new JpaTransactionManager(); manager.setEntityManagerFactory(entityManagerFactory); return manager; } @Bean public BeanPostProcessor persistenceTranslation() { return new PersistenceAnnotationBeanPostProcessor(); } }
a.@EnableJpaRepositories.basePackages路径指定那些Repository使用下面的配置。
b.@EnableTransactionManagement支持事务处理
c.@Qualifier("firstDS")指定了使用第一个数据库配置
d.entityManagerFactory.setPackagesToScan("com.yxd.springboot.model");指定了model路径
以上所有的配置已完成。
----------------------------------------------------华丽分割线----------------------------------------------------
测试类不写了,有一点注意一下就可以了。根据上面mybatis和jpa的配置
mybatis+数据源1的mapper路径:com.yxd.springboot.mapper.first
mybatis+数据源2的mapper路径:com.yxd.springboot.mapper.second
jpa的repository路径:com.yxd.springboot.Repository