mybatis主从数据源配置

概述

本文将mybatis应用于spring boot中,详细介绍了全注解形式的配置mybatis多数据源。同时,会用到阿里巴巴的开源数据源Druid。开发语言为kotlin,也从此角度说明了kotlin的使用方式。

依赖

  • Spring Boot易用性的特点是通过Starter实现的,我们只需依赖mybatis的
  • spring-boot-starter即可
  • Druid是数据源
  • 本文的开发语言为kotlin

数据源配置

  1. 主数据源
    多数据源配置要求必须有一个是主数据源,配置如下:
@Configuration
@MapperScan(basePackages = ["tech.dev.app.dao.master.mapper"], sqlSessionFactoryRef = "sqlSessionFactory")
class MasterDruidConfig {
    private val logger: Logger = LoggerFactory.getLogger(MasterDruidConfig::class.java)

    // master
    @Value("\${spring.master.datasource.url}")
    private lateinit var masterUrl: String

    @Value("\${spring.master.datasource.username}")
    private lateinit var masterUserName: String

    @Value("\${spring.master.datasource.password}")
    private lateinit var masterPassword: String

    @Value("\${spring.master.datasource.driver-class-name}")
    private lateinit var masterDriverClassName: String

    // pool
    @Value("\${spring.datasource-pool.initialSize}")
    private lateinit var initialSize: String

    @Value("\${spring.datasource-pool.minIdle}")
    private lateinit var minIdle: String

    @Value("\${spring.datasource-pool.maxActive}")
    private lateinit var maxActive: String

    @Value("\${spring.datasource-pool.maxWait}")
    private lateinit var maxWait: String

    @Value("\${spring.datasource-pool.timeBetweenEvictionRunsMillis}")
    private lateinit var timeBetweenEvictionRunsMillis: String

    @Value("\${spring.datasource-pool.minEvictableIdleTimeMillis}")
    private lateinit var minEvictableIdleTimeMillis: String

    @Value("\${spring.datasource-pool.validationQuery}")
    private lateinit var validationQuery: String

    @Value("\${spring.datasource-pool.testWhileIdle}")
    private lateinit var testWhileIdle: String

    @Value("\${spring.datasource-pool.testOnBorrow}")
    private lateinit var testOnBorrow: String

    @Value("\${spring.datasource-pool.testOnReturn}")
    private lateinit var testOnReturn: String

    @Value("\${spring.datasource-pool.poolPreparedStatements}")
    private lateinit var poolPreparedStatements: String

    @Value("\${spring.datasource-pool.maxPoolPreparedStatementPerConnectionSize}")
    private lateinit var maxPoolPreparedStatementPerConnectionSize: String

    @Value("\${spring.datasource-pool.filters}")
    private lateinit var filters: String

    @Value("\${spring.datasource-pool.connectionProperties}")
    private lateinit var connectionProperties: String

    @Primary
    @Bean("masterDataSource")
    fun masterDataSource(): DataSource {
        val dataSource = DruidDataSource()
        dataSource.url = this.masterUrl
        dataSource.username = this.masterUserName
        dataSource.password = this.masterPassword
        dataSource.driverClassName = this.masterDriverClassName

        dataSource.initialSize = this.initialSize.toInt()
        dataSource.minIdle = this.minIdle.toInt()
        dataSource.maxActive = this.maxActive.toInt()
        dataSource.maxWait = this.maxWait.toLong()
        dataSource.timeBetweenEvictionRunsMillis = this.timeBetweenEvictionRunsMillis.toLong()
        dataSource.minEvictableIdleTimeMillis = this.minEvictableIdleTimeMillis.toLong()
        dataSource.validationQuery = this.validationQuery
        dataSource.isTestWhileIdle = this.testWhileIdle.toBoolean()
        dataSource.isTestOnBorrow = this.testOnBorrow.toBoolean()
        dataSource.isTestOnReturn = this.testOnReturn.toBoolean()
        dataSource.isPoolPreparedStatements = this.poolPreparedStatements.toBoolean()
        dataSource.maxPoolPreparedStatementPerConnectionSize = this.maxPoolPreparedStatementPerConnectionSize.toInt()
        try {
            dataSource.setFilters(this.filters)
        } catch (e: SQLException) {
            logger.error("master druid configuration initialization filter", e)
        }
        dataSource.setConnectionProperties(this.connectionProperties)
        logger.info("master dataSource instance created...")
        return dataSource
    }

    @Primary
    @Bean("masterTransactionManager")
    fun masterTransactionManager(@Qualifier("masterDataSource") masterDataSource: DataSource): DataSourceTransactionManager {
        return DataSourceTransactionManager(masterDataSource)
    }

    @Primary
    @Bean("sqlSessionFactory")
    fun sqlSessionFactory(@Qualifier("masterDataSource") masterDataSource: DataSource): SqlSessionFactory {
        val sessionFactory = SqlSessionFactoryBean()
        sessionFactory.setDataSource(masterDataSource)
        sessionFactory.setTypeAliasesPackage("tech.blacklake.dev.def.model")
        sessionFactory.setConfigLocation(DefaultResourceLoader().getResource("classpath:mybatis-config.xml"))
        return sessionFactory.`object`
    }
}
1. @Value将获取Spring Boot全局配置application.yml文件的值。
2. @MapperScan配置要扫描并容器管理的包路径,这里我们精确到包名(tech.dev.app.dao.master.mapper),以便与其他Mapper与其他数据源隔离。
3. sqlSessionFactory要定义key唯一的SqlSessionFactory实例,否则同名的处理是后者被忽略。

2. 相应的从数据源配置如下:

@Configuration
@MapperScan(basePackages = ["tech.dev.app.dao.slave.mapper"], sqlSessionFactoryRef = "slaveSqlSessionFactory")
class SlaveDruidConfig {

    private val logger: Logger = LoggerFactory.getLogger(SlaveDruidConfig::class.java)

    // slave
    @Value("\${spring.slave.datasource.url}")
    private lateinit var slaveUrl: String

    @Value("\${spring.slave.datasource.username}")
    private lateinit var slaveUserName: String

    @Value("\${spring.slave.datasource.password}")
    private lateinit var slavePassword: String

    @Value("\${spring.slave.datasource.driver-class-name}")
    private lateinit var slaveDriverClassName: String

    // pool
    @Value("\${spring.datasource-pool.initialSize}")
    private lateinit var initialSize: String

    @Value("\${spring.datasource-pool.minIdle}")
    private lateinit var minIdle: String

    @Value("\${spring.datasource-pool.maxActive}")
    private lateinit var maxActive: String

    @Value("\${spring.datasource-pool.maxWait}")
    private lateinit var maxWait: String

    @Value("\${spring.datasource-pool.timeBetweenEvictionRunsMillis}")
    private lateinit var timeBetweenEvictionRunsMillis: String

    @Value("\${spring.datasource-pool.minEvictableIdleTimeMillis}")
    private lateinit var minEvictableIdleTimeMillis: String

    @Value("\${spring.datasource-pool.validationQuery}")
    private lateinit var validationQuery: String

    @Value("\${spring.datasource-pool.testWhileIdle}")
    private lateinit var testWhileIdle: String

    @Value("\${spring.datasource-pool.testOnBorrow}")
    private lateinit var testOnBorrow: String

    @Value("\${spring.datasource-pool.testOnReturn}")
    private lateinit var testOnReturn: String

    @Value("\${spring.datasource-pool.poolPreparedStatements}")
    private lateinit var poolPreparedStatements: String

    @Value("\${spring.datasource-pool.maxPoolPreparedStatementPerConnectionSize}")
    private lateinit var maxPoolPreparedStatementPerConnectionSize: String

    @Value("\${spring.datasource-pool.filters}")
    private lateinit var filters: String

    @Value("\${spring.datasource-pool.connectionProperties}")
    private lateinit var connectionProperties: String

    @Bean("slaveDataSource")
    fun slaveDataSource(): DataSource {
        val dataSource = DruidDataSource()
        dataSource.url = this.slaveUrl
        dataSource.username = this.slaveUserName
        dataSource.password = this.slavePassword
        dataSource.driverClassName = this.slaveDriverClassName

        dataSource.initialSize = this.initialSize.toInt()
        dataSource.minIdle = this.minIdle.toInt()
        dataSource.maxActive = this.maxActive.toInt()
        dataSource.maxWait = this.maxWait.toLong()
        dataSource.timeBetweenEvictionRunsMillis = this.timeBetweenEvictionRunsMillis.toLong()
        dataSource.minEvictableIdleTimeMillis = this.minEvictableIdleTimeMillis.toLong()
        dataSource.validationQuery = this.validationQuery
        dataSource.isTestWhileIdle = this.testWhileIdle.toBoolean()
        dataSource.isTestOnBorrow = this.testOnBorrow.toBoolean()
        dataSource.isTestOnReturn = this.testOnReturn.toBoolean()
        dataSource.isPoolPreparedStatements = this.poolPreparedStatements.toBoolean()
        dataSource.maxPoolPreparedStatementPerConnectionSize = this.maxPoolPreparedStatementPerConnectionSize.toInt()
        try {
            dataSource.setFilters(this.filters)
        } catch (e: SQLException) {
            logger.error("slave druid configuration initialization filter", e)
        }
        dataSource.setConnectionProperties(this.connectionProperties)
        logger.info("slave dataSource instance created...")
        return dataSource
    }

    @Bean("slaveTransactionManager")
    fun slaveTransactionManager(@Qualifier("slaveDataSource") slaveDataSource: DataSource): DataSourceTransactionManager {
        return DataSourceTransactionManager(slaveDataSource)
    }

    @Bean("slaveSqlSessionFactory")
    fun slaveSqlSessionFactory(@Qualifier("slaveDataSource") slaveDataSource: DataSource): SqlSessionFactory {
        val sessionFactory = SqlSessionFactoryBean()
        sessionFactory.setTypeAliasesPackage("tech.blacklake.dev.def.model")
        sessionFactory.setDataSource(slaveDataSource)
        sessionFactory.setConfigLocation(DefaultResourceLoader().getResource("classpath:mybatis-config.xml"))
        return sessionFactory.`object`
    }
}

3.应用的配置文件application.yml内容如下:

spring:
  master:
    datasource:
      url: jdbc:mysql://localhost:3306/master?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&useLegacyDatetimeCode=false
      username: root
      password: admin
      driver-class-name: com.mysql.jdbc.Driver
  slave:
    datasource:
      url: jdbc:mysql://localhost:3306/slave?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
      username: root
      password: admin
      driver-class-name: com.mysql.jdbc.Driver
  datasource-pool:
    initialSize: 5
    minIdle: 5
    maxActive: 20
    maxWait: 60000
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT 1 FROM DUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true
    maxPoolPreparedStatementPerConnectionSize: 20
    filters: stat,wall,log4j
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
    useGlobalDataSourceStat: true

  jackson:
    time-zone: GMT+8

mybatis:
  configuration:
    map-underscore-to-camel-case: true

4.应用程序入口:

import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.transaction.annotation.EnableTransactionManagement

@SpringBootApplication
@EnableTransactionManagement
class Application

fun main(args: Array<String>) {
    SpringApplication.run(Application::class.java, *args)
}

开启应用程序后会出现如下日志:

2018-04-10 13:22:41.426  INFO 95284 --- [on(7)-127.0.0.1] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} inited
2018-04-10 13:22:41.714  INFO 95284 --- [on(7)-127.0.0.1] com.alibaba.druid.pool.DruidDataSource   : {dataSource-2} inited

此时,表明主从数据源已配置完毕,并生成相应的实例。

注意,由于多数据源,未使用spring boot默认的配置,因此,如果使用XML文件的mapper,需要在sqlSessionFactory中添加以下自定义配置:

sessionFactory.setConfigLocation(DefaultResourceLoader().getResource("classpath:mybatis-config.xml"))

同理,其他额外自定义配置,也需要手工添加。

阅读更多
个人分类: mybatis
想对作者说点什么? 我来说一句

mybatis-plus+动态数据源

2017年09月28日 64KB 下载

没有更多推荐了,返回首页

不良信息举报

mybatis主从数据源配置

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭