双数据源配置(多数据源以此类推)
先附上完整的层次结构
- 配置application.properties
注意填自己的数据库名,登录名和密码
spring.application.name=demo
server.port=8080
mybatis.mapper-locations=classpath:mappers/*xml
mybatis.type-aliases-package=com.example.demo.entity
spring.datasource.one.jdbc-url=jdbc:sqlserver://127.0.0.1:1433;DatabaseName=Test
spring.datasource.one.username=xxx
spring.datasource.one.password=xxx
spring.datasource.one.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.datasource.two.jdbc-url=jdbc:sqlserver://127.0.0.1:1433;DatabaseName=pcshop
spring.datasource.two.username=xxx
spring.datasource.two.password=xxx
spring.datasource.two.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
logging.level.com.example.demo.repository=debug
spring.jackson.serialization.indent-output=true
- 创建datasource包,在包中创建类DataSourceConfig_1和类DataSourceConfig_2
注意结构层次
DataSourceConfig_1
//DataSourceConfig_1
package com.example.demo.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;
/**
* 创建多数据源的过程就是:首先创建 DataSource,
* 注入到 SqlSessionFactory 中,再创建事务,
* 将 SqlSessionFactory 注入到创建的 SqlSessionTemplate 中,
* 最后将 SqlSessionTemplate 注入到对应的 Mapper 包路径下。
* 其中需要指定分库的 Mapper 包路径。
*/
@Configuration
@MapperScan(basePackages = "com.example.demo.repository.one", sqlSessionTemplateRef = "oneSqlSessionTemplate")
public class DataSourceConfig_1 {
/**
* 加载配置数据源
*
* @return
* @Primary 是指具有默认值
*/
@Bean(name = "oneDataSource")
@ConfigurationProperties(prefix = "spring.datasource.one")
@Primary
public DataSource testDataSource() {
return DataSourceBuilder.create().build();
}
/**
* 根据数据源创建 sqlsessionFactory
*
* @Qualifier("oneDataSource") 传参
* 指明需要加载的 Mapper xml 文件。
*/
@Bean(name = "oneSqlSessionFactory")
@Primary
public SqlSessionFactory testSqlSessionFactory(@Qualifier("oneDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mappers/one/*.xml"));
//Resource[] mapperLocations
return bean.getObject();
}
/**
* 添加事务
* transactionManager需要datasource
*/
@Bean(name = "oneTransactionManager")
@Primary
public DataSourceTransactionManager testTransactionManager(@Qualifier("oneDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
/**
* 需要 sqlSessionFactory 来创建
* sqlSessionTemplate 模板
*/
@Bean(name = "oneSqlSessionTemplate")
@Primary
public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("oneSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
/**
* sqlSessionTemplate 用来操作mapper接口中的crud
* 所以,把sqlSessionTemplate 传入mapper的包路径下
* 在 @MapperScan
*/
}
这里有两个地方需要改成自己的包路径
DataSourceConfig_2
package com.example.demo.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.demo.repository.two", sqlSessionTemplateRef = "twoSqlSessionTemplate")
public class DataSourceConfig_2 {
@Bean(name = "twoDataSource")
@ConfigurationProperties(prefix = "spring.datasource.two")
public DataSource testDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "twoSqlSessionFactory")
public SqlSessionFactory testSqlSessionFactory(@Qualifier("twoDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mappers/two/*.xml"));
return bean.getObject();
}
@Bean(name = "twoTransactionManager")
public DataSourceTransactionManager testTransactionManager(@Qualifier("twoDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "twoSqlSessionTemplate")
public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("twoSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
同理,与DataSourceConfig_1一样有两个地方需要改成自己包的路径。
- 数据库建表
pcshop库,printer表
Test库,My_user表
- 创建enetity包,在该包下创建子包one和two,实体类MyUser_1和MyUse_2,如下图所示
MyUser_1对应My_user表
package com.example.demo.entity.one;
import lombok.Data;
@Data
public class MyUser_1 {
private Integer uid;
private String uname;
private String usex;
}
MyUse_2对应printer表
package com.example.demo.entity.two;
import lombok.Data;
@Data
public class MyUser_2 {
private String model;
private String color;
private String type;
private String price;
}
- 创建repository包,在该包下创建子包one和two,接口MyUserRepository_1和MyUserRepository_2,如下图所示
MyUserRepository_1
package com.example.demo.repository.one;
import com.example.demo.entity.one.MyUser_1;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface MyUserRepository_1 {
public void insertData_1(@Param("uid")Integer uid,@Param("uname")String uname,@Param("usex")String usex);
public List<MyUser_1> findAll_1();
public void deleteData_1();
}
MyUserRepository_2
package com.example.demo.repository.two;
import com.example.demo.entity.two.MyUser_2;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface MyUserRepository_2 {
public List<MyUser_2> findAll_2();
public void insertData_2(@Param("model")String model, @Param("color") String color, @Param("type") String type, @Param("price") Float price);
public void deleteData_2();
}
- 创建service包,在该包下创建MyUserService接口和MyUserServiceImpl实现类,如下图所示
MyUserService接口
package com.example.demo.service;
import com.example.demo.entity.one.MyUser_1;
import com.example.demo.entity.two.MyUser_2;
import java.util.List;
public interface MyUserService {
public List<MyUser_1> findAll_1();
public void insertData_1(Integer uid, String uname, String usex);
public void deleteData_1();
public List<MyUser_2> findAll_2();
public void insertData_2(String model,String color,String type,Float price);
public void deleteData_2();
}
MyUserServiceImpl实现类
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class MyUserServiceImpl implements MyUserService{
@Autowired
private MyUserRepository_1 myUserRepository1;
@Autowired
private MyUserRepository_2 myUserRepository2;
@Override
public List<MyUser_1> findAll_1() {
return myUserRepository1.findAll_1();
}
@Override
public void insertData_1(Integer uid, String uname, String usex){
myUserRepository1.insertData_1(uid,uname,usex);
}
@Override
public void deleteData_1(){
myUserRepository1.deleteData_1();
}
@Override
public List<MyUser_2> findAll_2(){
return myUserRepository2.findAll_2();
}
@Override
public void insertData_2(String model,String color,String type,Float price){
myUserRepository2.insertData_2(model,color,type,price);
}
@Override
public void deleteData_2(){
myUserRepository2.deleteData_2();
}
}
- 启动类
basePackages路径要写全
package com.example.demo;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication()
@MapperScan(basePackages={"com.example.demo.repository.one","com.example.demo.repository.two"})
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
- 在resource包下创建mappers包,在mappers包下创建子包one和two,映射文件MyUserMapper_1和MyUserMapper_2,如下图所示
MyUserMapper_1
<?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.demo.repository.one.MyUserRepository_1">
<select id="findAll_1" resultType="com.example.demo.entity.one.MyUser_1">
select * from My_user
</select>
<delete id="deleteData_1">
truncate table My_user
</delete>
<insert id="insertData_1" >
insert into My_user(uid,uname,usex) values (#{uid},#{uname},#{usex})
</insert>
</mapper>
MyUserMapper_2
<?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.demo.repository.two.MyUserRepository_2">
<select id="findAll_2" resultType="com.example.demo.entity.two.MyUser_2">
select * from printer
</select>
<delete id="deleteData_2">
truncate table printer
</delete>
<insert id="insertData_2" >
insert into printer (model,color,type,price) values (#{model},#{color},#{type},#{price})
</insert>
</mapper>
mapper namespace 填自己接口的路径
resultType 填自己实体类的路径
路径一定要完整
- 创建controller包,该包下创建控制器类MyUserController
package com.example.demo.controller;
import com.example.demo.entity.one.MyUser_1;
import com.example.demo.entity.two.MyUser_2;
import com.example.demo.service.MyUserService;
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;
@RestController
public class MyUserController {
@Autowired
private MyUserService myUserService;
@RequestMapping("/findAll_1")
public List<MyUser_1> findAll_1(){
return myUserService.findAll_1();
}
@RequestMapping("/insert_1")
public String insertData_1(Integer uid, String uname, String usex){
myUserService.insertData_1(20,"test","女");
return "insert successfully";
}
@RequestMapping("/delete_1")
public String deleteData_1(){
myUserService.deleteData_1();
return "delete successfully";
}
@RequestMapping("/findAll_2")
public List<MyUser_2> findAll_2(){
return myUserService.findAll_2();
}
@RequestMapping("/insert_2")
public String insertData_2(String model,String color,String type,Float price){
myUserService.insertData_2("4000","TRUE","laser",300f);
return "insert successfully";
}
@RequestMapping("/delete_2")
public String deleteData_2(){
myUserService.deleteData_2();
return "delete successfully";
}
}
- 运行结果
源码下载
https://download.csdn.net/download/Oceansssss/77875256