* maven依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 整合freemarker -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!-- log4j -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
</dependency>
<!-- aop -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- fastJson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.32</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
一,多数据源配置
同一个项目有时候可能会涉及多个数据源,从不同的数据源分别进行CRUD操作;在同一个容器中进行不同的数据库操作,需要考虑多数据源配置;
本篇基于拆包方式进行多数据源配置,不同的数据源独享mapper下某一分包进行数据库操作,DataSource配置会自动扫描调用包路径进行数据源配置;
多数据库源配置只是个人尝试,不做企业开发参考;相对于下一篇AOP注解切换数据源,更倾向于通过拆包进行控制,有助于规范化管理,虽然AOP相对更加灵活!
二,项目配置
1,整体构成
* java代码
* 配置文件
2,application.properties
### mapper.xml存储路径
mybatis.mapper-locations=classpath:com.gupao.springboot.*.mapper.*/*.xml
### MYSQL_First数据源配置
spring.datasource.first.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.first.jdbc-url=jdbc:mysql://localhost:3306/first?characterEncoding=utf-8&serverTimezone=GMT%2B8
spring.datasource.first.username=root
spring.datasource.first.password=123456
### MYSQL_First数据源配置
spring.datasource.second.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.second.jdbc-url=jdbc:mysql://localhost:3306/second?characterEncoding=utf-8&serverTimezone=GMT%2B8
spring.datasource.second.username=root
spring.datasource.second.password=123456
3,数据源注册
* MYSQL_FIRST数据源注册
package com.gupao.springboot.datasourceprop.config;
import org.apache.ibatis.annotations.Mapper;
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;
/**
* FirstDataSource数据源
*
* @author pj_zhang
* @create 2018-12-28 10:06
**/
// 注册到SpringBoot容器中
@Configuration
// MYSQL_FIRST扫描mapper.first包下数据层
@MapperScan(basePackages = "com.gupao.springboot.*.mapper.first", sqlSessionFactoryRef = "firstSqlSessionFactory")
public class FirstDataSourceConfig {
/**
* 配置FirstDataSource数据源
*
* @return
*/
@Bean(name = "firstDataSource")
@ConfigurationProperties(prefix = "spring.datasource.first")
public DataSource firstDataSource() {
return DataSourceBuilder.create().build();
}
/**
* 配置SqlSessionFactory
*
* @param dataSource
* @return
* @throws Exception
*/
@Bean(name = "firstSqlSessionFactory")
public SqlSessionFactory firstSqlSessionFactory(@Qualifier("firstDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
return sqlSessionFactoryBean.getObject();
}
/**
* 数据库事务
*
* @param dataSource
* @return
*/
@Bean(name = "firstTransactionManager")
public DataSourceTransactionManager firstTransactionManager(@Qualifier("firstDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
/**
* 配置SqlSessionTemplate
*
* @param sqlSessionFactory
* @return
*/
@Bean(name = "firstSqlSessionTemplate")
public SqlSessionTemplate firstSqlSessionTemplate(@Qualifier("firstSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
* MYSQL_SECOND数据源注册
package com.gupao.springboot.datasourceprop.config;
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;
/**
* secondDataSource数据源
*
* @author pj_zhang
* @create 2018-12-28 10:06
**/
// 注册到SpringBoot容器中
@Configuration
// MYSQL_SECOND扫描mepper.second包下数据层
@MapperScan(basePackages = "com.gupao.springboot.*.mapper.second", sqlSessionFactoryRef = "secondSqlSessionFactory")
public class SecondDataSourceConfig {
/**
* 配置secondDataSource数据源
*
* @return
*/
@Bean(name = "secondDataSource")
@ConfigurationProperties(prefix = "spring.datasource.second")
public DataSource secondDataSource() {
return DataSourceBuilder.create().build();
}
/**
* 配置SqlSessionFactory
*
* @param dataSource
* @return
* @throws Exception
*/
@Bean(name = "secondSqlSessionFactory")
public SqlSessionFactory secondSqlSessionFactory(@Qualifier("secondDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
return sqlSessionFactoryBean.getObject();
}
/**
* 数据库事务
*
* @param dataSource
* @return
*/
@Bean(name = "secondTransactionManager")
public DataSourceTransactionManager secondTransactionManager(@Qualifier("secondDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
/**
* 配置SqlSessionTemplate
*
* @param sqlSessionFactory
* @return
*/
@Bean(name = "secondSqlSessionTemplate")
public SqlSessionTemplate secondSqlSessionTemplate(@Qualifier("secondSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
4,Controller层
package com.gupao.springboot.datasourceprop.controller;
import com.gupao.springboot.datasourceprop.service.IDataSourcePropService;
import com.gupao.springboot.entitys.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @author pj_zhang
* @create 2018-12-28 10:42
**/
@Slf4j
@RestController
public class DataSourcePropController {
@Autowired
private IDataSourcePropService dataSourcePropService;
/**
* 向MYSQL_FIRST插入数据
*
* @param userName
* @param password
* @return
*/
@RequestMapping("/firstInsert")
public Integer firstInsert(String userName, String password) {
UserVO userVO = new UserVO();
userVO.setUserName(userName);
userVO.setPassword(password);
return dataSourcePropService.insertFirstUserLst(userVO);
}
/**
* 向MYSQL_SECOND插入数据
*
* @param userName
* @param password
* @return
*/
@RequestMapping("/secondInsert")
public Integer secondInsert(String userName, String password) {
UserVO userVO = new UserVO();
userVO.setUserName(userName);
userVO.setPassword(password);
return dataSourcePropService.insertSecondUserLst(userVO);
}
/**
* 查询MYSQL_FIRST数据
*
* @return
*/
@RequestMapping("/firstPropSelect")
public List<UserVO> findFirstData() {
return dataSourcePropService.findFirstData();
}
/**
* 查询MYSQL_SECOND数据
*
* @return
*/
@RequestMapping("/secondPropSelect")
public List<UserVO> findSecondData() {
return dataSourcePropService.findSecondData();
}
}
5,Service层
* Service层接口
package com.gupao.springboot.datasourceprop.service;
import com.gupao.springboot.entitys.UserVO;
import java.util.List;
/**
* @author pj_zhang
* @create 2018-12-28 10:50
**/
public interface IDataSourcePropService {
/**
* 保存数据-MYSQL_FIRST
*
* @param userVO
* @return
*/
Integer insertFirstUserLst(UserVO userVO);
/**
* 保存数据-MYSQL_SECOND
*
* @param userVO
* @return
*/
Integer insertSecondUserLst(UserVO userVO);
/**
* 查询数据-MYSQL_FIRST
*
* @return
*/
List<UserVO> findFirstData();
/**
* 查询数据-MYSQL_SECOND
*
* @return
*/
List<UserVO> findSecondData();
}
* Service.Impl
package com.gupao.springboot.datasourceprop.service.impl;
import com.gupao.springboot.datasourceprop.mapper.first.FirstDataSourceMapper;
import com.gupao.springboot.datasourceprop.mapper.second.SecondDataSourceMapper;
import com.gupao.springboot.datasourceprop.service.IDataSourcePropService;
import com.gupao.springboot.entitys.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author pj_zhang
* @create 2018-12-28 10:43
**/
@Slf4j
@Service
public class DataSourcePropService implements IDataSourcePropService {
/**
* 注入first mapper层, 连接MYSQL_FIRST数据库操作
*/
@Autowired
private FirstDataSourceMapper firstDataSourceMapper;
/**
* 注入second mapper层, 连接MYSQL_SECOND数据库操作
*/
@Autowired
private SecondDataSourceMapper secondDataSourceMapper;
@Override
public Integer insertFirstUserLst(UserVO userVO) {
return firstDataSourceMapper.insertFirstUser(userVO);
}
@Override
public Integer insertSecondUserLst(UserVO userVO) {
return secondDataSourceMapper.insertSecondUser(userVO);
}
@Override
public List<UserVO> findFirstData() {
return firstDataSourceMapper.findFirstData();
}
@Override
public List<UserVO> findSecondData() {
return secondDataSourceMapper.findSecondData();
}
}
6,Mapper层
* Mapper层结构;其中first包对应MYSQL_FIRST数据源,second包对应MYSQL_SECOND数据源;xml文件对应结构一致,在application,properties已经指定,注意包结构用"."隔开,尝试过"/"没成功。
* MYSQL_FIRST对应数据层
package com.gupao.springboot.datasourceprop.mapper.first;
import com.gupao.springboot.entitys.UserVO;
import java.util.List;
/**
* @author pj_zhang
* @create 2018-12-28 10:43
**/
public interface FirstDataSourceMapper {
Integer insertFirstUser(UserVO userVO);
List<UserVO> findFirstData();
}
<?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.gupao.springboot.datasourceprop.mapper.first.FirstDataSourceMapper">
<insert id="insertFirstUser" parameterType="com.gupao.springboot.entitys.UserVO">
INSERT INTO
USER_T(USER, PASSWORD)
VALUES (
#{userName, jdbcType=VARCHAR},
#{password, jdbcType=VARCHAR}
)
</insert>
<select id="findFirstData" resultType="com.gupao.springboot.entitys.UserVO">
SELECT
user as userName,
password as password
from
USER_T
</select>
</mapper>
* MYSQL_SECOND对应数据层
package com.gupao.springboot.datasourceprop.mapper.second;
import com.gupao.springboot.entitys.UserVO;
import java.util.List;
/**
* @author pj_zhang
* @create 2018-12-28 10:43
**/
public interface SecondDataSourceMapper {
Integer insertSecondUser(UserVO userVO);
List<UserVO> findSecondData();
}
<?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.gupao.springboot.datasourceprop.mapper.second.SecondDataSourceMapper">
<insert id="insertSecondUser" parameterType="com.gupao.springboot.entitys.UserVO">
INSERT INTO
USER_T(USER, PASSWORD)
VALUES (
#{userName, jdbcType=VARCHAR},
#{password, jdbcType=VARCHAR}
)
</insert>
<select id="findSecondData" resultType="com.gupao.springboot.entitys.UserVO">
SELECT
user as userName,
password as password
from
USER_T
</select>
</mapper>
7,SpringBoot启动文件
package com.gupao.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class GupaoSpringbootApplication {
public static void main(String[] args) {
SpringApplication.run(GupaoSpringbootApplication.class, args);
}
}
8,测试
* MYSQL_FIRST入库
* MYSQL_SECOND入库
* MYSQL_FIRST查询
* MYSQL_SECOND查询
* MYSQL_FIRST数据库
* MYSQL_SECOND数据库