淘先锋技术网

首页 1 2 3 4 5 6 7

前言

一个SpringBoot项目对应一个数据库,正常情况下能满足大部分的需求。但有时因为特殊需求,项目中要同时操作多个数据源,这时候就需要为SpringBoot配置多个数据源。
本文以IDEA + SpringBoot + Mybatis + Mysql为例,来实现多个数据源的访问控制。

开始之前先看一下项目最终的目录结构:
在这里插入图片描述

一. 新建SpringBoot项目

参考我的使用IDEA 搭建Spring Boot项目文章,新建一个SpringBoot项目

二. 添加第三方库

在pom.xml中添加以下内容

        <!--mysql连接所需jar包-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>

        <!--mybatis所需jar包-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.1</version>
        </dependency>

        <!-- alibaba JSON解析库 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.47</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

三. 配置文件application.properties

在这里插入图片描述
在配置文件中添加两个数据库相关的参数信息,端口号我这里设置成8081,不一定要同一台服务器,可以不同服务器,我为了测试方便,都连接到了本地的服务器。
红色框部分不一定要按照图中的写,可以自定义(后面编写配置类的时候要用到

四. 配置类

因为要连接两个数据库,我写了两个配置类

@Configuration
@MapperScan(basePackages = {"com.springboot.demo.mapper.first"}, sqlSessionFactoryRef = "firstSqlSessionFactory")
public class FirstDBConfig {
    @Primary
    @Bean(name = "firstDataSource")
    @ConfigurationProperties(prefix="spring.datasource.first")
    public DataSource firstDataSource(){
        return DataSourceBuilder.create().build();
    }

    @Primary
    @Bean(name = "firstSqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("firstDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
        sessionFactoryBean.setDataSource(dataSource);
        sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath*:mapper/first/*.xml"));
        return sessionFactoryBean.getObject();
    }
}
@Configuration
@MapperScan(basePackages = {"com.springboot.demo.mapper.second"}, sqlSessionFactoryRef = "secondSqlSessionFactory")
public class SecondDBConfig {
    @Bean(name = "secondDataSource")
    @ConfigurationProperties(prefix="spring.datasource.second")
    public DataSource secondDataSource(){
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "secondSqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("secondDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
        sessionFactoryBean.setDataSource(dataSource);
        sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath*:mapper/second/*.xml"));
        return sessionFactoryBean.getObject();
    }
}

其中:
prefix = 上图中红色框部分
basePackages = 你的项目中mapper类的目录
getResources = 你的项目中mapper对应的xml文件
如果目录结构和我的项目一致,可以直接复制粘贴

另外,需要在启动类中添加红色框部分,禁用默认的数据库配置
在这里插入图片描述

五. 实体类

// 第一个数据库中的表
@Data
public class User {
    private int id;
    private String name;
    private int age;
}
// 第二个数据库中的表
@Data
public class Member {
    private int id;
    private String name;
    private int age;
}

六. Service类

@Service
public class UserService {
    @Autowired
    UserMapper userMapper;

    public List<User> getList() {
        return userMapper.getList();
    }
}
@Service
public class MemberService {
    @Autowired
    MemberMapper memberMapper;

    public List<Member> getList() {
        return memberMapper.getList();
    }
}

这里我简单写了个查询接口

七. Mapper接口

@Mapper
public interface UserMapper {
    List<User> getList();
}
@Mapper
public interface MemberMapper {
    List<Member> getList();
}

八. Mapper对应的xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--UserMapper.xml-->
<mapper namespace="com.springboot.demo.mapper.first.UserMapper">
    <resultMap id="BaseResultMap" type="com.springboot.demo.entity.first.User">
        <id column="id" jdbcType="INTEGER" property="id"/>
        <result column="name" jdbcType="VARCHAR" property="name"/>
        <result column="age" jdbcType="INTEGER" property="age"/>
    </resultMap>
    <select id="getList" resultMap="BaseResultMap">
        SELECT * FROM `users`
    </select>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--MemberMapper.xml-->
<mapper namespace="com.springboot.demo.mapper.second.MemberMapper">
    <resultMap id="BaseResultMap" type="com.springboot.demo.entity.second.Member">
        <id column="id" jdbcType="INTEGER" property="id"/>
        <result column="name" jdbcType="VARCHAR" property="name"/>
        <result column="age" jdbcType="INTEGER" property="age"/>
    </resultMap>
    <select id="getList" resultMap="BaseResultMap">
        SELECT * FROM `members`
    </select>
</mapper>

注意把namespace和type的值改成你项目对应文件的路径

九. 控制器和请求方法

@RestController
public class DemoController {
    @Autowired
    UserService userService;

    @Autowired
    MemberService memberService;

    @RequestMapping(value="/index", method = RequestMethod.GET)
    public Object index(HttpServletRequest request) {
        List<User> userList = userService.getList();
        List<Member> memberList = memberService.getList();
        JSONObject resultObj = new JSONObject();
        resultObj.put("users", userList);
        resultObj.put("members", memberList);
        return resultObj;
    }
}

这里简单地写了个控制器和请求方法,分别查询数据库一中的用户列表和数据库二中的会员列表,然后返回。

十. 运行测试

运行DemoApplication,在浏览器中输入http://localhost:8081/index,返回以下结果,同时查询到两个数据库中两张表的数据
在这里插入图片描述
2个以上数据源也是同样的方法
完毕!