频道栏目
首页 > 程序开发 > 软件开发 > Java > 正文
SpringBoot集成实现多数据源详情
2017-11-09 15:04:15      个评论    来源:不清不慎的博客  
收藏   我要投稿

一,前面我们介绍了springboot的快速启动,大家肯定对springboot也有所了解,下面我们来介绍一下springboot怎么集成多数据源。

在有的项目开发中需要在一个项目中访问多个数据源或者两个项目之间通信(实质上是互相访问对方的数据库),在这里,我们介绍一下在一个项目中如何集成多个数据源(即访问多个不同的数据库),因为在项目中有时会有这种需求,比如在一个大型项目开发中,一个数据库中保存数据的索引,各种使用频繁的数据,另一个数据库中保存其他的数据。

1.下面我们来讨论一个问题,怎么集成多数据源,就是怎么让一个项目访问多个数据库?
有的人会说使用注解,没错,这是一种办法,因为springboot对的最大好处就是避免了繁琐的xml配置文件,大量的使用注解来开发,方便简洁,但是在这里如果集成多数据源使用注解的话会很麻烦,有没有其他的办法呢?答案是肯定的,我们可以分模板来访问多个数据库,也就是分包。

2.如何分包来访问多个数据源?
在这里,我们用一个简单的案例来说明,我们访问新建一个spingboot项目,访问test1,test2这两个数据库,首先,我们先看代码。

首先,我们需要导入相关依赖在pom文件中,这里,因为我的项目已经提前有了父pom,所以不再考虑依赖的版本问题,怎么建立父pom可参考上一篇文章。

  4.0.0
  
    cn.shinelon.springboot
    microboot
    0.0.1-SNAPSHOT
  
  springboot-MultiDatasources
  war


  
    
        
            
                org.apache.maven.plugins
                maven-war-plugin
                2.3
                
                    false
                
            
        
    
    
        
            org.springframework.boot
            spring-boot-starter-web
        
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        

    
    
        org.springframework
        springloaded
    
    
        org.springframework.boot
        spring-boot-devtools
    
    
    
        org.springframework.boot
        spring-boot-starter-tomcat
    
    
        org.apache.tomcat.embed
        tomcat-embed-jasper
    
    
    
        org.mybatis.spring.boot
        mybatis-spring-boot-starter
        1.3.0
    
    
        mysql
        mysql-connector-java
    
  

在上面配置的pom文件中,有点要说明,因为要访问数据库,所以我整合了mybatis,还有一个是整合jsp,不过在这个项目中无关,是我之前写代码留下来的,可不必关心。

下面,我们还要在scr/main/sources目录下新建一个application.properties资源文件,注意,这个文件名必须是application,这个是固定的,springboot默认访问该文件,不要自己乱改名称。然后在这个资源文件中配置自定义数据源。

spring.datasource.test1.driverClassName=com.mysql.jdbc.Driver
spring.datasource.test1.url=jdbc:mysql://localhost:3306/test1
spring.datasource.test1.username=root
spring.datasource.test1.password=.....


spring.datasource.test2.driverClassName=com.mysql.jdbc.Driver
spring.datasource.test2.url=jdbc:mysql://localhost:3306/test2
spring.datasource.test2.username=root
spring.datasource.test2.password=.....

配置好数据源后我们就可以开进行分模块来访问这两个数据源了。首先在src/mian/java目录下创建好各个包,然后开始开发,新建一个datasource包来放置需要访问的两个数据源的代码,然后在新建两个模块包test1和test2,从包名我们就可以看出来这两个包是用来操作这两个数据库,在这两个包下可以分别建立DAO层和service层的包,然后建立一个controller控制层。下面是项目的目录树图。

这里写图片描述

然后我们来写DataSource中的代码,其实就是像我们以前在xml文件中配置的SqlSessionFactory和数据源一个原理。

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
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;

@Configuration
@MapperScan(basePackages="cn.shinelon.test1",sqlSessionFactoryRef="test1SqlSessionFactory")
public class Datasource1 {
    /**
     * 配置test1数据库
     * @return
     */
    @Bean(name="test1Datasource")
    @ConfigurationProperties(prefix="spring.datasource.test1")
    public DataSource testDatasource() {
        return DataSourceBuilder.create().build();
    }
    /**
     * 创建SqlSessionFactory
     * @param dataSource
     * @return
     * @throws Exception
     */
    @Bean(name="test1SqlSessionFactory")
    public SqlSessionFactory testSqlSessionFactory(@Qualifier("test1Datasource")DataSource dataSource) 
            throws Exception {
        SqlSessionFactoryBean bean=new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        //如果还有分页等其他事务
//      bean.setMapperLocations(new PathMatchingResourcePatternResolver().
//              getResources("classpath:mybatis/test1/*.xml"));
        return bean.getObject();
    }
    /**
     * 配置事务管理
     * @param dataSource
     * @return
     */
    @Bean(name="test1TransactionManager")
    public DataSourceTransactionManager testTransactionManager(
            @Qualifier("test1Datasource")DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name="test1SqlSessionTemplate")
    public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("test1SqlSessionFactory")
    SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

上面的是访问的test1数据库的配置,需要注意的是@ConfigurationProperties(prefix=”spring.datasource.test1”)这个配置中的属性prefix的值必须和资源文件中的前缀是一样的,否则是访问不到的,还有@Primary ,如果不加这个注解,启动将会报错,因为服务器先要有一个默认不知道默认要先访问的数据源是哪个,必须指明,下面是test2数据库的配置,和上面一样的。

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
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;

@Configuration
@MapperScan(basePackages="cn.shinelon.test2",sqlSessionFactoryRef="test2SqlSessionFactory")
@Primary        //指定 默认的访问的数据源
public class Datasource2 {
    /**
     * 配置test2数据库
     * @return
     */
    @Bean(name="test2Datasource")
    @ConfigurationProperties(prefix="spring.datasource.test2")
    @Primary        //指定 默认的访问的数据源
    public DataSource testDatasource() {
        return DataSourceBuilder.create().build();
    }
    /**
     * 创建SqlSessionFactory
     * @param dataSource
     * @return
     * @throws Exception
     */
    @Bean(name="test2SqlSessionFactory")
    @Primary        //指定 默认的访问的数据源
    public SqlSessionFactory testSqlSessionFactory(@Qualifier("test2Datasource")DataSource dataSource) 
            throws Exception {
        SqlSessionFactoryBean bean=new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        //如果还有分页等其他事务
//      bean.setMapperLocations(new PathMatchingResourcePatternResolver().
//              getResources("classpath:mybatis/test2/*.xml"));
        return bean.getObject();
    }
    /**
     * 配置事务管理
     * @param dataSource
     * @return
     */
    @Bean(name="test2TransactionManager")
    @Primary        //指定 默认的访问的数据源
    public DataSourceTransactionManager testTransactionManager(
            @Qualifier("test2Datasource")DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name="test2SqlSessionTemplate")
    public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("test2SqlSessionFactory")
    SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

然后我们在每一个模块中写DAO层和service代码来进行操作。
DAO层代码如下

public interface User1Dao {
    @Insert("insert into user values(null,#{username},#{age})")
    public void insert(@Param("username")String username,@Param("age")int age);
}

在这里,我们向数据库插入一条数据。
service层代码如下

@Service
public class User1Service {
    @Autowired
    public User1Dao user1Dao;

    public void insert(String username,int age) {
        user1Dao.insert(username, age);
    }
}

test2包下DAO层和service层的代码都是同样的,这里就省略了。
然后我们来开始写controller层的代码。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import cn.shinelon.test1.services.User1Service;
import cn.shinelon.test2.services.User2Service;

@SpringBootApplication
@ComponentScan(basePackages={"cn.shinelon.datasource","cn.shinelon.test1","cn.shinelon.test2"})
@RestController
public class UserController {
    @Autowired
    public User1Service user1Service;
    @Autowired
    public User2Service user2Service;
    @RequestMapping("/add")
    public String insert(String username,int age) {
        user1Service.insert(username, age);
        user2Service.insert(username, age);
        return "insert success";
    }

    public static void main(String[] args) {
        SpringApplication.run(UserController.class, args);
    }
}

在上面代码中 ,需要注意的是@ComponentScan(basePackages={“cn.shinelon.datasource”,”cn.shinelon.test1”,”cn.shinelon.test2”})这个注解,必须添加,这样服务器才会扫描到这几个包中的配置。

下面我们补全代码,还要建立一个实体类

public class User {
    private int id;
    private String username;
    private int age;
    //省略get,set方法
    }

最后的整个项目图如下
这里写图片描述

点击复制链接 与好友分享!回本站首页
上一篇:myeclipse导出可运行jar包
下一篇:Java算法之二分法查找代码实例
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站