springboot配置多数据源之Spring Date JPA

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zc_ad/article/details/83379746

多数据源在项目开发中是经常遇到的,如果同一个项目的不同模块使用的是不同数据库,就需要多数据源的处理。现在先写之前使用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{
	...
	...
}

猜你喜欢

转载自blog.csdn.net/zc_ad/article/details/83379746
今日推荐