SpringBoot多數據源實現

序言

        在項目中,單個數據庫承受的壓力是有限的,爲了支持業務高併發的場景,多數據源的使用已經成爲必須前提。這裏使用SpringBoot整合MyBatis實現多數據源的使用案例,案例目前就使用兩個數據庫。Springboot整合mybatis實現多數據源有兩種方式:分包和AOP。這裏使用的分包,因爲層次更加清晰。

一、項目環境說明

jdk版本爲jdk1.8.0_172;

數據庫使用的是MySQL的MariaDB;

SpringBoot版本:2.2.5.RELEASE

MyBatis版本:2.1.2

        這裏說明環境是因爲不同版本對應的配置參數可能會有變化,如果出現參數配置了還出現參數配置問題,有可能就是因爲版本更新之後參數變量名有變動或者包名有變動。

二、項目搭建

2.1 初始化項目

      這裏IDE使用IntelliJIdea,項目初始化表方便,File->New->New Project 選擇SpringInitializr初始化一個springboot項目。

2.2 項目目錄說明

    

這裏只對關鍵目錄做出說明:

config目錄:存放數據源配置類,多數據源每個數據源各單獨一個配置類。

controller目錄:存放controller,開放調用接口。

mapper目錄:在這個目錄下有對應數據源ds1、ds2的mapper接口文件。

pojo目錄:存放數據實體類。

service目錄:存放業務類。

resources目錄:存放配置文件的資源目錄,mapper下面ds1、ds2分別爲數據源1數據源2的xml文件目錄。

2.3 代碼實現

        首先我們從應用配置文件application.yml開始配置,配置多數據源需要爲每個數據源的datasource連接參數做出配置.

# Spring 配置
spring:
  #數據源配置
  datasource:
    ds1: #數據源1
      jdbc-url: jdbc:mysql://127.0.0.1:3306/mytest01
      username: root
      password: root
      driver-class-name: com.mysql.jdbc.Driver
    ds2: #數據源1
      jdbc-url: jdbc:mysql://127.0.0.1:3306/mytest02
      username: root
      password: root
      driver-class-name: com.mysql.jdbc.Driver

       第二步我們需要爲每個數據源配置對應的DataSource,我們把配置類放在config.datasource目錄中。

先實現ds1的配置類:

```

package com.example.multdatasource.config.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.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
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;

@Configuration
@MapperScan(basePackages = "com.example.multdatasource.mapper.ds1",sqlSessionTemplateRef = "sqlSessionTemplate1")
public class DatasourceConfig1 {

@Bean(name = "datasource1")
@Primary
@ConfigurationProperties(prefix = "spring.datasource.ds1")
public DataSource getDatasource(){
return DataSourceBuilder.create().build();
}

@Primary
@Bean(name = "sqlSessionFactory1")
public SqlSessionFactory getSqlSessionFactory1(@Qualifier("datasource1") DataSource dataSource) throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);

sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/ds1/*.xml"));
return sqlSessionFactoryBean.getObject();
}

@Bean("dataSourceTransactionManager1")
@Primary
public DataSourceTransactionManager getDataSourceTransactionManager1(@Qualifier("datasource1") DataSource dataSource){
return new DataSourceTransactionManager(dataSource);
}


@Bean("sqlSessionTemplate1")
@Primary
public SqlSessionTemplate getSqlSessionTemplate1(@Qualifier("sqlSessionFactory1") SqlSessionFactory sqlSessionFactory){
return new SqlSessionTemplate(sqlSessionFactory);
}

}

```

然後再實現ds2的DataSource配置:

package com.example.multdatasource.config.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.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
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;

@Configuration
@MapperScan(basePackages = "com.example.multdatasource.mapper.ds2",sqlSessionTemplateRef = "sqlSessionTemplate2")
public class DatasourceConfig2 {

    @Bean(name = "datasource2")
    @ConfigurationProperties(prefix = "spring.datasource.ds2")
    public DataSource getDatasource(){
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "sqlSessionFactory2")
    public SqlSessionFactory getSqlSessionFactory2(@Qualifier("datasource2") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/ds2/*.xml"));
        return sqlSessionFactoryBean.getObject();
    }

    @Bean("dataSourceTransactionManager2")
    public DataSourceTransactionManager getDataSourceTransactionManager2(@Qualifier("datasource2") DataSource dataSource){
        return new DataSourceTransactionManager(dataSource);
    }


    @Bean("sqlSessionTemplate2")
    public SqlSessionTemplate getSqlSessionTemplate2(@Qualifier("sqlSessionFactory2") SqlSessionFactory sqlSessionFactory){
        return new SqlSessionTemplate(sqlSessionFactory);
    }

}

        ds1與ds2的數據源配置大致一樣,但是稍有差別,ds1的配置類中我們加了@Primary註解,這些註解可以讓我們默認ds1爲主數據源。配置類中我們指定數據源的mapper.xml文件路徑。

第三步我們實現業務邏輯,這裏只實現增刪操作。在MariaDB中有數據庫testdb01庫user表,testdb02庫role表。

mapper/ds1/UserMapper.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">
<mapper namespace="com.example.multdatasource.mapper.ds1.UserMapper">

<resultMap id="UserResult" type="com.example.multdatasource.pojo.User">
<result property="id" column="id" javaType="Integer" ></result>
<result property="name" column="name" javaType="String" ></result>
<result property="gender" column="gender" javaType="String" ></result>
<result property="age" column="age" javaType="Integer" ></result>
</resultMap>

<select id="selectByName" resultMap="UserResult">
SELECT * FROM USER WHERE name=#{name}
</select>

<insert id="insertUser" parameterType="com.example.multdatasource.pojo.User" >
insert into
USER(name, gender, age)
values(#{name},#{gender},#{age})
</insert>

</mapper>

```

mapper/ds1/UserMapper.java實現

```

package com.example.multdatasource.mapper.ds1;

import com.example.multdatasource.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Component;

@Mapper
@Component("userMapper")
public interface UserMapper {

User selectByName(@Param("name") String name);

int insertUser(User user);

}

```

mapper/ds2/RoleMapper.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">
<mapper namespace="com.example.multdatasource.mapper.ds2.RoleMapper">

    <resultMap id="RoleResult" type="com.example.multdatasource.pojo.Role">
        <result property="id" column="id" javaType="Integer"  ></result>
        <result property="name" column="name" javaType="String" ></result>
        <result property="role" column="role" javaType="String" ></result>
    </resultMap>

    <select id="selectByName" resultMap="RoleResult">
        SELECT * FROM ROLE WHERE name=#{name}
    </select>

    <insert id="insertRole" parameterType="com.example.multdatasource.pojo.Role" >
        insert into
        ROLE(name, gender)
        values(#{name},#{role})
    </insert>

</mapper>

mapper/ds2/RoleMapper.java實現

```

package com.example.multdatasource.mapper.ds2;

import com.example.multdatasource.pojo.Role;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Component;

@Mapper
@Component("roleMapper")
public interface RoleMapper {

Role selectByName(String name);

}

```

實現對應的service

UserService.java

```

package com.example.multdatasource.service;

import com.example.multdatasource.mapper.ds1.UserMapper;
import com.example.multdatasource.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {

@Autowired
private UserMapper userMapper;

public User selectOneUser(String name){
return userMapper.selectByName(name);
}

public int insertOne(User user){
return userMapper.insertUser(user);
}
}

```

RoleService.java

```

package com.example.multdatasource.service;

import com.example.multdatasource.mapper.ds2.RoleMapper;
import com.example.multdatasource.pojo.Role;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class RoleService {

@Autowired
private RoleMapper roleMapper;

public Role getOneByName(String name){
return roleMapper.selectByName(name);
}

}

```

實現對應的Controller

UserController.java

```

package com.example.multdatasource.controller;

import com.example.multdatasource.pojo.User;
import com.example.multdatasource.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;


@RestController
@RequestMapping("/user")
public class UserController {

@Autowired
private UserService userService;

@RequestMapping("/getOne")
@ResponseBody
public User getOne(@RequestBody Map<String,Object> requestBody){
String name = requestBody.get("name").toString();
System.out.println("getOne");
return userService.selectOneUser(name);
}

@RequestMapping("/addOne")
@ResponseBody
public Map<String,Object> insertOnt(@RequestBody User user){
Map<String,Object> response = new HashMap<>();
int insertCount = userService.insertOne(user);
String result = insertCount == 1 ? "success" : "failed";
response.put("result",result);
return response;
}
}

```
RoleController.java

```

package com.example.multdatasource.controller;

import com.example.multdatasource.pojo.Role;
import com.example.multdatasource.service.RoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/role")
public class RoleController {

@Autowired
private RoleService roleService;

@RequestMapping("/getOne")
@ResponseBody
public Map<String,Object> getOne(@RequestBody Map<String,Object> request){
Map<String,Object> result = new HashMap<>();
String name = request.get("name").toString();
Role role = roleService.getOneByName(name);
result.put("role",role);
return result;
}
}

```

應用啓動我們就可以訪問localhost:8080/role/getOne去數據源ds2查詢role數據,訪問localhost:8080/user/addOn去數據源ds1新增一個user記錄。

項目地址:https://gitee.com/charberming/demos.git ,多數據源使用案例在 multdatasource目錄

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章