美文网首页
Spring Boot教程 - 整合MyBatis 多数据源

Spring Boot教程 - 整合MyBatis 多数据源

作者: FX_SKY | 来源:发表于2017-08-17 13:27 被阅读1492次

    日常开发中,我们可能需要连接多个数据源,例如数据库进行了主从配置,写操作走主库,读操作走从库。本来结合Spring Boot + MyBatis + Druid 来演示如何配置多个数据源。

    1. pom.xml

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <!-- Inherit defaults from Spring Boot -->
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.5.6.RELEASE</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>spring-boot-mybatis3-multi-datasource</artifactId>
        <packaging>jar</packaging>
    
        <name>spring-boot-mybatis3-multi-datasource</name>
        <url>http://maven.apache.org</url>
    
        <properties>
            <mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version>
            <druid.version>1.0.25</druid.version>
            <mysql.connector.version>5.1.39</mysql.connector.version>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <!--mybatis-->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis.spring.boot.version}</version>
            </dependency>
    
            <!-- db-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.connector.version}</version>
            </dependency>
    
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>${druid.version}</version>
            </dependency>
        </dependencies>
    
        <build>
            <finalName>spring-boot-mybatis3-multi-datasource</finalName>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <configuration>
                        <classifier>exec</classifier>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </project>
    
    

    2. application.properties

    mybatis.config-locations=classpath:mybatis-config.xml
    
    spring.datasource.master.driverClassName=com.mysql.jdbc.Driver
    spring.datasource.master.url=jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf-8
    spring.datasource.master.username=root
    spring.datasource.master.password=root
    
    spring.datasource.slave.driverClassName=com.mysql.jdbc.Driver
    spring.datasource.slave.url=jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf-8
    spring.datasource.slave.username=root
    spring.datasource.slave.password=root
    

    3. 数据源配置

    多数据源配置的时候注意,必须要有一个主数据源(使用 @Primary 标识),本例中即 MasterDataSourceConfig 配置:

    package com.mindflow.springboot.mybatis.config.datasource;
    
    import com.alibaba.druid.pool.DruidDataSource;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.mybatis.spring.SqlSessionFactoryBean;
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.beans.factory.annotation.Value;
    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 Ricky Fung
     */
    @Configuration
    @MapperScan(basePackages = MasterDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "masterSqlSessionFactory")
    public class MasterDataSourceConfig {
    
        static final String PACKAGE = "com.mindflow.springboot.mybatis.mapper.master";
        static final String MAPPER_LOCATION = "classpath:mapper/master/*.xml";
    
        @Value("${spring.datasource.master.url}")
        private String url;
    
        @Value("${spring.datasource.master.username}")
        private String user;
    
        @Value("${spring.datasource.master.password}")
        private String password;
    
        @Value("${spring.datasource.master.driverClassName}")
        private String driverClass;
    
        @Bean(name = "masterDataSource")
        @Primary
        public DataSource masterDataSource() {
            DruidDataSource dataSource = new DruidDataSource();
            dataSource.setDriverClassName(driverClass);
            dataSource.setUrl(url);
            dataSource.setUsername(user);
            dataSource.setPassword(password);
            dataSource.setInitialSize(5);
            dataSource.setMaxActive(50);
            dataSource.setMinIdle(0);
            return dataSource;
        }
    
        @Bean(name = "masterTransactionManager")
        @Primary
        public DataSourceTransactionManager masterTransactionManager() {
            return new DataSourceTransactionManager(masterDataSource());
        }
    
        @Bean(name = "masterSqlSessionFactory")
        @Primary
        public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource masterDataSource)
                throws Exception {
            final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
            sessionFactory.setDataSource(masterDataSource);
            sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                    .getResources(MasterDataSourceConfig.MAPPER_LOCATION));
            return sessionFactory.getObject();
        }
    }
    
    

    @Primary 标志这个 Bean 如果在多个同类 Bean 候选时,该 Bean 优先被考虑。「多数据源配置的时候注意,必须要有一个主数据源,用 @Primary 标志该 Bean」;
    @MapperScan 扫描 Mapper 接口并容器管理,包路径精确到 master,为了和下面 slave数据源做到精确区分;
    sqlSessionFactoryRef 表示定义了 key ,表示一个唯一 SqlSessionFactory 实例。

    同理,SlaveDataSourceConfig 如下:

    package com.mindflow.springboot.mybatis.config.datasource;
    
    import com.alibaba.druid.pool.DruidDataSource;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.mybatis.spring.SqlSessionFactoryBean;
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
    import org.springframework.jdbc.datasource.DataSourceTransactionManager;
    
    import javax.sql.DataSource;
    
    /**
     * @author Ricky Fung
     */
    @Configuration
    @MapperScan(basePackages = SlaveDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "slaveSqlSessionFactory")
    public class SlaveDataSourceConfig {
        static final String PACKAGE = "com.mindflow.springboot.mybatis.mapper.slave";
        static final String MAPPER_LOCATION = "classpath:mapper/slave/*.xml";
    
        @Value("${spring.datasource.slave.url}")
        private String url;
    
        @Value("${spring.datasource.slave.username}")
        private String user;
    
        @Value("${spring.datasource.slave.password}")
        private String password;
    
        @Value("${spring.datasource.slave.driverClassName}")
        private String driverClass;
    
        @Bean(name = "slaveDataSource")
        public DataSource clusterDataSource() {
            DruidDataSource dataSource = new DruidDataSource();
            dataSource.setDriverClassName(driverClass);
            dataSource.setUrl(url);
            dataSource.setUsername(user);
            dataSource.setPassword(password);
            dataSource.setInitialSize(5);
            dataSource.setMaxActive(50);
            return dataSource;
        }
    
        @Bean(name = "slaveTransactionManager")
        public DataSourceTransactionManager clusterTransactionManager() {
            return new DataSourceTransactionManager(clusterDataSource());
        }
    
        @Bean(name = "slaveSqlSessionFactory")
        public SqlSessionFactory clusterSqlSessionFactory(@Qualifier("slaveDataSource") DataSource clusterDataSource)
                throws Exception {
            final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
            sessionFactory.setDataSource(clusterDataSource);
            sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                    .getResources(SlaveDataSourceConfig.MAPPER_LOCATION));
            return sessionFactory.getObject();
        }
    }
    
    

    4. service层

    service照常注入了两个 DAO,如同以前一样正常工作。不用关心和指定到具体说明数据源。

    UserService :

    package com.mindflow.springboot.mybatis.service.impl;
    
    import com.mindflow.springboot.mybatis.domain.UserDO;
    import com.mindflow.springboot.mybatis.domain.UserDOExample;
    import com.mindflow.springboot.mybatis.mapper.master.UserDOMapper;
    import com.mindflow.springboot.mybatis.service.UserService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import java.util.List;
    
    /**
     * @author Ricky Fung
     */
    @Service
    public class UserServiceImpl implements UserService {
        @Autowired
        private UserDOMapper userDOMapper;
    
        @Override
        public UserDO getUserByName(String username) {
            UserDOExample example = new UserDOExample();
            List<UserDO> list = userDOMapper.selectByExample(example);
            if(list==null || list.isEmpty()) {
                return null;
            }
            return list.get(0);
        }
    
        @Override
        public int insert(UserDO userDO) {
            return userDOMapper.insertSelective(userDO);
        }
    }
    
    

    OrderService :

    package com.mindflow.springboot.mybatis.service.impl;
    
    import com.mindflow.springboot.mybatis.domain.OrderDO;
    import com.mindflow.springboot.mybatis.domain.OrderDOExample;
    import com.mindflow.springboot.mybatis.mapper.slave.OrderDOMapper;
    import com.mindflow.springboot.mybatis.service.OrderService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.util.List;
    
    /**
     * @author Ricky Fung
     */
    @Service
    public class OrderServiceImpl implements OrderService {
    
        @Autowired
        private OrderDOMapper orderDOMapper;
    
        @Override
        public List<OrderDO> getOrders(Long userId) {
            OrderDOExample example = new OrderDOExample();
            example.createCriteria().andUserIdEqualTo(userId);
            return orderDOMapper.selectByExample(example);
        }
    
        @Override
        public int insert(OrderDO orderDO) {
            return orderDOMapper.insert(orderDO);
        }
    }
    
    

    源码

    spring-boot-tutorials

    相关文章

      网友评论

          本文标题:Spring Boot教程 - 整合MyBatis 多数据源

          本文链接:https://www.haomeiwen.com/subject/ebwgrxtx.html