多数据源在项目开发中是经常遇到的,如果同一个项目的不同模块使用的是不同数据库,就需要多数据源的处理。现在先写之前使用JPA的时候遇到多数据源的配置,后续可能再来个关于mybatis的多数据源配置。
现在有这样的需求,项目中有两个模块,分别是flow与imap,flow需要使用默认数据源,imap需要使用imap数据源。
先来个maven依赖,使用的连接池是durid。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!--阿里巴巴druid数据库连接池--><!--http://localhost:8080/druid/index.html--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.1</version> </dependency>先来个application.yml配置,配置多个数据源。
server: port: 8080 spring: application: name: xichuan profiles: active: dev --- spring: profiles: dev datasource: driverClassName: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/db_flow?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false username: root password: root type: com.alibaba.druid.pool.DruidDataSource initialSize: 1 minIdle: 1 maxActive: 20 maxWait: 60000 timeBetweenEvictionRunsMillis: 60000 minEvictableIdleTimeMillis: 300000 validationQuery: SELECT 1 FROM DUAL testWhileIdle: true testOnBorrow: true testOnReturn: false poolPreparedStatements: false maxPoolPreparedStatementPerConnectionSize: 20 filters: stat,wall,log4j connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 imap_datasource: driverClassName: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/db_imap?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false username: root password: root type: com.alibaba.druid.pool.DruidDataSource initialSize: 1 minIdle: 1 maxActive: 20 maxWait: 60000 timeBetweenEvictionRunsMillis: 60000 minEvictableIdleTimeMillis: 300000 validationQuery: SELECT 1 FROM DUAL testWhileIdle: true testOnBorrow: true testOnReturn: false poolPreparedStatements: false maxPoolPreparedStatementPerConnectionSize: 20 filters: stat,wall,log4j connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 jpa: database : MYSQL show-sql : true hibernate: ddl-auto: update properties: hibernate.format_sql: true hibernate.naming.physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl hibernate.cache.use_second_level_cache: false hibernate.search.default.directory_provider: filesystem hibernate.search.default.indexBase: ./indexes open-in-view: true druid: allow: ip: 127.0.0.1 login: user_name: root password: root添加durid的配置,之前有写过springboot整合durid的博文:https://blog.csdn.net/zc_ad/article/details/83340067
@Configuration public class DruidConfig { private static final Logger log = LoggerFactory.getLogger(DruidConfig.class); @Value("${druid.login.user_name}") private String userName; @Value("${druid.login.password}") private String password; @Value("${druid.allow.ip}") private String allowIp; /** * 配置默认数据源 * @return */ @Bean(name = "flow_databaseSource") @Qualifier("flow_databaseSource") @Primary @ConfigurationProperties(prefix="spring.datasource") public DataSource flowDataSource() { return new DruidDataSource(); } /** * 配置imap数据源 * @return */ @Bean(name = "imap_databaseSource") @Qualifier("imap_databaseSource") @ConfigurationProperties(prefix="spring.imap_datasource") public DataSource imapDataSource() { return new DruidDataSource(); } @Bean public ServletRegistrationBean druidServlet() { log.info("init Druid Servlet Configuration, username:{},password:{},allowip:{}",userName,password,allowIp); ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(); servletRegistrationBean.setServlet(new StatViewServlet()); servletRegistrationBean.addUrlMappings("/druid/*"); Map<String, String> initParameters = new HashMap<>(); initParameters.put("loginUsername", userName);// 用户名 initParameters.put("loginPassword", password);// 密码 //initParameters.put("resetEnable", "false");// 禁用HTML页面上的“Reset All”功能 initParameters.put("allow", ""); // IP白名单 (没有配置或者为空,则允许所有访问) //initParameters.put("deny", "");// IP黑名单 (存在共同时,deny优先于allow) servletRegistrationBean.setInitParameters(initParameters); return servletRegistrationBean; } @Bean public FilterRegistrationBean filterRegistrationBean() { FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); filterRegistrationBean.setFilter(new WebStatFilter()); filterRegistrationBean.addUrlPatterns("/*"); filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"); return filterRegistrationBean; } }默认数据源配置:
@Configuration @EnableJpaRepositories( entityManagerFactoryRef="flow_entityManagerFactory", transactionManagerRef = "flow_transactionManager", basePackages = { "com.xichuan.dev.flow.repository" } ) @EnableTransactionManagement public class FlowDatabaseConfig { @Autowired @Qualifier("flow_databaseSource") private DataSource flowDataSource; @Autowired private JpaProperties jpaProperties; /** * 设置实现JPA实现的特定属性 * @return */ @Bean //@Primary public JpaVendorAdapter jpaVendorAdapter() { HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter(); adapter.setDatabase(Database.MYSQL); adapter.setShowSql(true); adapter.setGenerateDdl(true); adapter.setDatabasePlatform("org.hibernate.dialect.MySQL5Dialect"); return adapter; } /** *实体管理 * @param builder * @return */ @Bean(name = "flow_entityManagerFactoryBean") @Primary public LocalContainerEntityManagerFactoryBean flowEntityManagerFactoryBean(EntityManagerFactoryBuilder builder) { return builder .dataSource(flowDataSource) .properties(jpaProperties.getHibernateProperties(flowDataSource)) .packages("com.xichuan.dev.flow.entity") //设置实体类所在位置 .persistenceUnit("aPersistenceUnit") .build(); } /** * EntityManagerFactory类似于Hibernate的SessionFactory,mybatis的SqlSessionFactory * 总之,在执行操作之前,我们总要获取一个EntityManager,这就类似于Hibernate的Session, * mybatis的sqlSession. * @param builder * @return */ @Bean(name = "flow_entityManagerFactory") public EntityManagerFactory flowEntityManagerFactory(EntityManagerFactoryBuilder builder) { return this.flowEntityManagerFactoryBean(builder).getObject(); } /** * 配置默认数据源的事务 * @param flowDataSource * @return */ @Bean(name = "flow_transactionManager") public PlatformTransactionManager flowTransactionManager(@Qualifier("flow_databaseSource") DataSource flowDataSource) { return new DataSourceTransactionManager(flowDataSource); } /** * 配置JdbcOperations,可以使用JdbcOperations进行原生态的JDBC操作 * @param flowDataSource * @return */ @Bean(name = "flow_JdbcOperations") public JdbcOperations prodJdbcOperations(@Qualifier("flow_databaseSource") DataSource flowDataSource) { return new JdbcTemplate(flowDataSource); /** * 对JdbcOperations(是JdbcTemplate的抽象类)引用例子 * @Autowired * @Qualifier("default_JdbcOperations") * private JdbcOperations jdbcOperations; * * * 对 JdbcOperations使用 * jdbcOperations.execute(SQL); * */ } }imap数据源配置:
@Configuration @EnableJpaRepositories ( entityManagerFactoryRef="imap_entityManagerFactory", transactionManagerRef = "imap_transactionManager", basePackages = { "com.xichuan.dev.imap.repository" } ) @EnableTransactionManagement public class ImapDatabaseConfig { @Autowired @Qualifier("imap_databaseSource") private DataSource imapDataSource; @Autowired private JpaProperties jpaProperties; /** *实体管理 * @param builder * @return */ @Bean(name = "imap_entityManagerFactoryBean") public LocalContainerEntityManagerFactoryBean imapEntityManagerFactoryBean(EntityManagerFactoryBuilder builder) { return builder .dataSource(imapDataSource) .properties(jpaProperties.getHibernateProperties(imapDataSource)) .packages("com.xichaun.dev.imap.entity") //设置实体类所在位置 .persistenceUnit("bPersistenceUnit") .build(); } /** * EntityManagerFactory类似于Hibernate的SessionFactory,mybatis的SqlSessionFactory * 总之,在执行操作之前,我们总要获取一个EntityManager,这就类似于Hibernate的Session, * mybatis的sqlSession. * @param builder * @return */ @Bean(name = "imap_entityManagerFactory") public EntityManagerFactory imapEntityManagerFactory(EntityManagerFactoryBuilder builder) { return this.imapEntityManagerFactoryBean(builder).getObject(); } /** * 配置imap的jpa事务 * @param builder * @return */ @Bean(name = "imap_transactionManager") public PlatformTransactionManager writeTransactionManager(EntityManagerFactoryBuilder builder) { return new JpaTransactionManager(imapEntityManagerFactory(builder)); } }配置完后,就可以在flow模块使用使用DAO、service,默认到的数据库是db_flow库查询。imap默认到的数据库是db_imap库。
但如果要需要事务的话,需要在不同模块所需的方法上添加不同的事务。如在flow模块添加事务:
@Transactional("flow_transactionManager") public Objetc init(String code, String content)throws Exception{ ... ... }