springboot druid mybatis 多數據源配置和事務處理

參數配置

spring:
  datasource:
    # 使用阿里的Druid連接池
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    druid:
      paperpushsystem:
        url: 
        username: 
        password: 
      propertymanagement:
        username: 
        password: 
        url: 
      # 連接池的配置信息
      # 初始化大小,最小,最大
      initial-size: 5
      min-idle: 5
      maxActive: 20
      # 配置獲取連接等待超時的時間
      maxWait: 60000
      # 配置間隔多久才進行一次檢測,檢測需要關閉的空閒連接,單位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # 配置一個連接在池中最小生存的時間,單位是毫秒
      minEvictableIdleTimeMillis: 300000
      validationQuery: SELECT 1
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      # 打開PSCache,並且指定每個連接上PSCache的大小
      poolPreparedStatements: true
      maxPoolPreparedStatementPerConnectionSize: 20
      # 配置監控統計攔截的filters,去掉後監控界面sql無法統計,'wall'用於防火牆
      filters: stat,wall,slf4j
      # 通過connectProperties屬性來打開mergeSql功能;慢SQL記錄
      connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
      # 配置DruidStatFilter
      web-stat-filter:
        enabled: true
        url-pattern: "/*"
        exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
      # 配置DruidStatViewServlet
      stat-view-servlet:
        url-pattern: "/druid/*"
        # IP白名單(沒有配置或者爲空,則允許所有訪問)
        allow: 127.0.0.1,192.168.163.1
        # IP黑名單 (存在共同時,deny優先於allow)
        deny: 192.168.1.73
        #  禁用HTML頁面上的“Reset All”功能
        reset-enable: false
        # 登錄名
        login-username: admin
        # 登錄密碼
        login-password: 123456
      use-global-data-source-stat: true

數據源

數據庫名稱等基礎配置

public class DataSourceConfigurer {

    public static final String DB_PPS = "paperpushsystem";
    public static final String DB_PM = "propertymanagement";


    public static final String PPS_TRANSACTION_MANAGER = "paperpushsystemTransactionManager";
    public static final String PM_TRANSACTION_MANAGER = "propertyManagementTransactionManager";

    public static void setPlugins(SqlSessionFactoryBean sqlSessionFactoryBean) {
        //配置分頁插件
        PageHelper pageHelper = new PageHelper();
        Properties properties = new Properties();
        properties.setProperty("pageSizeZero", "true");//分頁尺寸爲0時查詢所有紀錄不再執行分頁
        properties.setProperty("reasonable", "false");//頁碼<=0 查詢第一頁,頁碼>=總頁數查詢最後一頁
        properties.setProperty("supportMethodsArguments", "true");//支持通過 Mapper 接口參數來傳遞分頁參數
        pageHelper.setProperties(properties);
        //添加插件
        sqlSessionFactoryBean.setPlugins(new Interceptor[]{pageHelper});
    }

    public static MapperScannerConfigurer scannerConfigurer(String db) {
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setSqlSessionFactoryBeanName(db + "SqlSessionFactory");
        mapperScannerConfigurer.setBasePackage("cn.wangjie.dao.mapper." + db);
        //配置通用mappers
        Properties properties = new Properties();
        properties.setProperty("mappers", "tk.mybatis.mapper.common.Mapper");
        properties.setProperty("notEmpty", "false");
        properties.setProperty("IDENTITY", "MYSQL");
        mapperScannerConfigurer.setProperties(properties);
        return mapperScannerConfigurer;
    }

}

數據庫1

@Data
@ConditionalOnProperty(name = "spring.datasource.druid.paperpushsystem.url", matchIfMissing = false)
@org.springframework.context.annotation.Configuration
public class PaperPushSystemDBConfig extends DataSourceConfigurer {

    @Bean(name = DB_PPS)
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource.druid.paperpushsystem")
    public DataSource paperPushSystemDataSource() {
        return new DruidDataSource();
    }

    @Bean
    public Configuration paperPushSystemConfiguration() {
        Configuration configuration = new Configuration();
        //開啓駝峯
        configuration.setMapUnderscoreToCamelCase(true);
        return configuration;
    }

    @Bean(DB_PPS+"SqlSessionFactory")
    @Primary
    public SqlSessionFactory paperPushSystemSqlSessionFactoryBean() throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(paperPushSystemDataSource());
        sqlSessionFactoryBean.setConfiguration(paperPushSystemConfiguration());
        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath*:mapper/"+DB_PPS+"/*.xml"));
        return sqlSessionFactoryBean.getObject();
    }

    @Bean(PPS_TRANSACTION_MANAGER)
    @Primary
    public DataSourceTransactionManager paperPushSystemTransactionManager() {
        return new DataSourceTransactionManager(paperPushSystemDataSource());
    }


    @ConditionalOnProperty(name = "spring.datasource.druid.paperpushsystem.url", matchIfMissing = false)
    @org.springframework.context.annotation.Configuration
    @AutoConfigureAfter(name=DB_PPS+"SqlSessionFactory")
    public static class MyBatisMapperScannerConfigurer {

        @Bean
        public MapperScannerConfigurer paperpushsystemScannerConfigurer() {
            return scannerConfigurer(DB_PPS);
        }
    }
}

數據庫2

@Data
@org.springframework.context.annotation.Configuration
@ConditionalOnProperty(name = "spring.datasource.druid.propertymanagement.url", matchIfMissing = false)
public class PropertyManagementDBConfig extends DataSourceConfigurer {

    @Bean(name = DB_PM)
    @ConfigurationProperties(prefix ="spring.datasource.druid.propertymanagement")
    DataSource dataSource(){
        return new DruidDataSource();
    }

    @Bean
    public Configuration configuration() {
        Configuration configuration = new Configuration();
        //開啓駝峯
        configuration.setMapUnderscoreToCamelCase(true);
        return configuration;
    }
    @Bean(name = DB_PM+"SqlSessionFactory")
    public SqlSessionFactory sessionFactoryBean() throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource());
        sqlSessionFactoryBean.setConfiguration(configuration());
        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath*:mapper/"+DB_PM+"/*.xml"));
        return sqlSessionFactoryBean.getObject();
    }

    @Bean(PM_TRANSACTION_MANAGER)
    public DataSourceTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dataSource());
    }

    @ConditionalOnProperty(name = "spring.datasource.druid.propertymanagement.url", matchIfMissing = false)
    @org.springframework.context.annotation.Configuration
    @AutoConfigureAfter(name = DB_PM+"SqlSessionFactory")
    public static class MyBatisMapperScannerConfigurer {

        @Bean
        public MapperScannerConfigurer propertymanagementScannerConfigurer() {
            return scannerConfigurer(DB_PM);
        }
    }
}

注意事項:

  1. 使用@Primary設置默認數據源和事務,這樣在使用@Transactional時,如果操作的是默認數據庫,可以不用指定事務管理器transactionManager,而對其他庫使用事務時需要明確指定對應的transactionManager。
  2. 要注意各自的SqlSessionFactory掃描各自的xml文件和dao接口,這一點可以通過包名區分開。

事務

啓動類上使用@EnableTransactionManagement

使用@Transaction註解開啓事務


    @Test
    @Transactional
    public void transactionTest1(){
        AuthorModel authorModel = new AuthorModel();
        authorModel.setName("testTransaction");
        authorDao.insert(authorModel);
        throw new RuntimeException();
    }

    @Test
    @Transactional(transactionManager = DataSourceConfigurer.PM_TRANSACTION_MANAGER)
    public void transactionTest2(){
        NoteModel noteModel = noteDao.selectByPrimaryKey(1);
        noteModel.setId(null);
        noteDao.insert(noteModel);
        throw new RuntimeException();
    }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章