美文网首页Java 杂谈Java
SpringBoot+Mybatis(Mysql/Postgre

SpringBoot+Mybatis(Mysql/Postgre

作者: Java酸不酸 | 来源:发表于2019-02-20 13:59 被阅读7次

    前言

    由于项目中需要使用到多个数据库进行数据验证,所以一开始在网上找了很多资料,但是大部分都是有关SpringBoot + JPA的多数据源整合。之后找到了微笑大神的一篇blog,在这里感谢纯洁的微笑大神,记录下个人实战过程的注意点以及相关配置。

    预先说明

    • 在整合多数据源时,两个或两个以上,一定得定好一个==主数据源==,不然会报错,比如:事物方面会报错
    • @Primary:SpringBoot自动装配时,当出现多个Bean候选者时,被注解为@Primary的Bean将作为首选者。
    • application.properties:在配置数据源url时,单个数据源直接spring.datasource.url即可;而在多数据源配置时,请使用spring.datasource.first.jdbc-url,注意:这里的first只是用来区分数据源,关键是jdbc-url,如果直接写spring.datasource.first.url,会报错:jdbcUrl is required with driverClassName。
    • Demo基于SpringBoot 2.0.2.RELEASE
    • Demo中使用的都是MySQL数据库,在实战中其他数据库也是可以的。比如:PostgreSQL,MySQL+PostgreSQL混合.....

    具体代码

    1. 项目结构
    在这里插入图片描述
    2. 相关依赖
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    
    3. 配置文件
    ###############################################
    ## Data Source Setting
    ###############################################
    spring.datasource.first.jdbc-url=jdbc:mysql://localhost:3306/datasource_first
    spring.datasource.first.username=root
    spring.datasource.first.password=root
    spring.datasource.first.driverClassName=com.mysql.jdbc.Driver
    
    spring.datasource.second.jdbc-url=jdbc:mysql://localhost:3306/datasource_second
    spring.datasource.second.username=root
    spring.datasource.second.password=root
    spring.datasource.second.driverClassName=com.mysql.jdbc.Driver
    
    mybatis.first.mapper-locations=classpath:mapper/first/*.xml
    mybatis.second.mapper-locations=classpath:mapper/second/*.xml
    
    • 这里使用first和second来区分两个数据源以及映射文件存放的路径
    4. 数据源配置类
    @Configuration
    @MapperScan(basePackages = "com.jtcoding.springbootmultidatasource.dao.first",
            sqlSessionTemplateRef = "firstSqlSessionTemplate")
    public class FirstDataSourceConfig {
    
        // 获取映射文件所在的路径
        @Value("${mybatis.first.mapper-locations}")
        private String firstMapperPath;
    
        /**
        * @Author jason.tang
        * @Description: 根据配置文件,注入数据源
        * @Date: 15:53 2019/2/13
        * @Param []
        * @return javax.sql.DataSource 
        */
        @Bean(name = "firstDataSource")
        @Primary
        @ConfigurationProperties(prefix = "spring.datasource.first")
        public DataSource firstDataSource() {
            return DataSourceBuilder.create().build();
        }
    
        /**
        * @Author jason.tang
        * @Description: 注入SqlSessionFactory,指定数据源和映射文件路径
        * @Date: 15:54 2019/2/13
        * @Param [dataSource]
        * @return org.apache.ibatis.session.SqlSessionFactory 
        */
        @Bean(name = "firstSqlSessionFactory")
        @Primary
        public SqlSessionFactory sqlSessionFactory(@Qualifier("firstDataSource") DataSource dataSource) throws Exception {
            SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
            sqlSessionFactoryBean.setDataSource(dataSource);
            Resource[] resources = new PathMatchingResourcePatternResolver().getResources(firstMapperPath);
            sqlSessionFactoryBean.setMapperLocations(resources);
            return sqlSessionFactoryBean.getObject();
        }
    
        /**
        * @Author jason.tang
        * @Description: 注入DataSourceTransactionManager事物管理器
        * @Date: 15:55 2019/2/13
        * @Param [dataSource]
        * @return org.springframework.jdbc.datasource.DataSourceTransactionManager 
        */
        @Bean(name = "firstTransactionManager")
        @Primary
        public DataSourceTransactionManager transactionManager(@Qualifier("firstDataSource") DataSource dataSource) {
            return new DataSourceTransactionManager(dataSource);
        }
    
        /**
        * @Author jason.tang
        * @Description: 注入SqlSessionTemplate模板
        * @Date: 15:55 2019/2/13
        * @Param [sqlSessionFactory]
        * @return org.mybatis.spring.SqlSessionTemplate 
        */
        @Bean(name = "firstSqlSessionTemplate")
        @Primary
        public SqlSessionTemplate sqlSessionTemplate(@Qualifier("firstSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
            return new SqlSessionTemplate(sqlSessionFactory);
        }
    }
    
    • @MapperScan扫描指定的DAO,并给指定的DAO层注入指定的SqlSessionTemplate,这样就能实现不同的数据源操作不同的数据库中的表。网上有关类似的是通过AOP实现数据源切换,个人觉得这种直接指定更加粗暴简单。另外一个数据源配置同理。
    @MapperScan(basePackages = "com.jtcoding.springbootmultidatasource.dao.first",
            sqlSessionTemplateRef = "firstSqlSessionTemplate")
    
    5. 实体类介绍
    @EqualsAndHashCode(callSuper = true)
    @Data
    @ToString
    public class User extends SrcUser {
        private Integer userNum;
        private String username;
        private String password;
    }
    
    @Data
    @ToString
    public class SrcUser {
        private Integer userNum;
        private String status;
        private String money;
    }
    
    • 这里的User为主表对应的实体类;SrcUser为从表对应的实体类。这样设计的意义是:主表存储关键信息,从表就是存储主表的详细信息
    6. 具体实现(Service层)
    @Service
    public class UserServiceImpl implements UserService {
    
        @Autowired
        private UserDao userDao;
        @Autowired
        private SrcUserService srcUserService;
    
        @Transactional
        @Override
        public User addUser(User user) {
            int rtn = userDao.addUser(user);
            if (rtn != 0) {
                if (user.getMoney().isEmpty()) {
                    user.setMoney("0");
                }
                rtn = srcUserService.addSrcUser(user);
            }
            return user;
        }
    
        @Transactional
        @Override
        public int deleteUser(Integer userNum) {
            int rtn = userDao.deleteUser(userNum);
    
            if (rtn != 0) {
                rtn = srcUserService.deleteSrcUser(userNum);
            }
            return rtn;
        }
    }
    
    • 在新增User时,同时往SrcUser中添加数据,删除与更新同理
    7. 总结

    以上是个人在参考和实现过程中,所发现的一下细节问题以及注意点,若有不对之处,请指出,谢谢!
    码云源码:请点击这里

    参考Blog:纯洁的微笑

    相关文章

      网友评论

        本文标题:SpringBoot+Mybatis(Mysql/Postgre

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