springboot系列之多数据源配置

springboot系列之多数据源

网上很多文章都有多数据源和动态数据源的介绍,只能只介绍多数据源的配置方式,废话不多说了,直接上代码

以下内容仅供参考,有不对的地方请广大客官批评指正。

应用场景

一般用于主从模式或者业务比较复杂需要连接不同的分库来支持业务。

application.properties

mybatis.type-aliases-package=com.husy.springboot.multisource.entity

spring.datasource.test1.jdbc-url=jdbc:mysql://localhost:3306/test-db1?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
spring.datasource.test1.username=root
spring.datasource.test1.password=123456
spring.datasource.test1.driver-class-name=com.mysql.cj.jdbc.Driver

spring.datasource.test2.jdbc-url=jdbc:mysql://localhost:3306/test-db2?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
spring.datasource.test2.username=root
spring.datasource.test2.password=123456
spring.datasource.test2.driver-class-name=com.mysql.cj.jdbc.Driver

数据源配置

最关键的一块,首先创建 DataSource,然后创建 SqlSessionFactory 再创建事务,最后包装到 SqlSessionTemplate 中。其中需要指定分库的 mapper 文件地址,以及分库dao层代码。

具体如下::

第一个数据源配置

DataSource1Config.java

/**
 * @description: 主数据源配置,@Primary这个注解必须要加,因为不加的话spring将分不清楚那个为主数据源(默认数据源)
 * @author: hsy
 * @date; 2019/9/22
 */
//表示这个类为一个配置类
@Configuration
// 配置mybatis的接口类放的地方
@MapperScan(basePackages="com.husy.springboot.multisource.mapper.test1",sqlSessionFactoryRef = "test1SqlSessionFactory")
public class DataSource1Config {

	// 将这个对象放入Spring容器中
	@Bean(name = "test1DataSource")
	//application.properteis中对应属性的前缀
	@ConfigurationProperties(prefix = "spring.datasource.test1")
	// 表示这个数据源是默认数据源
	@Primary
	public DataSource testDataSource() {
		return DataSourceBuilder.create().build();
	}


	@Bean(name = "test1SqlSessionFactory")
	// 表示这个数据源是默认数据源
	@Primary
	// @Qualifier表示查找Spring容器中名字为test1DataSource的对象
	public SqlSessionFactory test1SqlSessionFactory(@Qualifier("test1DataSource") DataSource datasource) throws Exception {
		MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
		bean.setDataSource(datasource);
		// 设置mybatis的xml所在位置
		bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/test1/*.xml"));
		return bean.getObject();
	}

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

	@Bean(name = "test1TransactionManager")
	@Primary// 表示这个数据源是默认数据源
	public DataSourceTransactionManager testTransactionManager(@Qualifier("test1DataSource") DataSource dataSource) {
		return new DataSourceTransactionManager(dataSource);
	}

}

第二个数据源配置

DataSource2Config.java


/**
 * @description: 数据源配置
 * @author: hsy
 * @date; 2019/9/22
 */
//表示这个类为一个配置类
@Configuration
// 配置mybatis的接口类放的地方
@MapperScan(basePackages="com.husy.springboot.multisource.mapper.test2",sqlSessionFactoryRef = "test2SqlSessionFactory")
public class DataSource2Config {

	// 将这个对象放入Spring容器中
	@Bean(name = "test2DataSource")
	//application.properteis中对应属性的前缀
	@ConfigurationProperties(prefix = "spring.datasource.test2")
	public DataSource testDataSource() {
		return DataSourceBuilder.create().build();
	}


	@Bean(name = "test2SqlSessionFactory")
	// 表示这个数据源是默认数据源
	public SqlSessionFactory test1SqlSessionFactory(@Qualifier("test2DataSource") DataSource datasource) throws Exception {
		MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
		bean.setDataSource(datasource);
		// 设置mybatis的xml所在位置
		bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/test2/*.xml"));
		return bean.getObject();
	}

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

	@Bean(name = "test2TransactionManager")
	public DataSourceTransactionManager testTransactionManager(@Qualifier("test2DataSource") DataSource dataSource) {
		return new DataSourceTransactionManager(dataSource);
	}

}

注意了:

1、@Primary这个注解必须要加,因为不加的话spring将分不清楚那个为主数据源(默认数据源)

2、mapper的接口、xml形式以及dao层都需要两个分开

3、由于我使用了 mybatis-plus 插件。所有这里必须用MybatisSqlSessionFactoryBean,如果是使用SqlSessionFactoryBean会报出现 Invalid bound statement (not found) 异常

entity

@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class Users implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 主键id
     */
    @TableId(value = "user_id", type = IdType.AUTO )
    private Long userId;

    /**
     * 用户名
     */
    @TableField("user_name")
    private String userName;

    /**
     * 密码
     */
    @TableField("password")
    private String password;

    /**
     * 0:男,1:女
     */
    @TableField("user_sex")
    private Integer userSex;

    @TableField("nick_name")
    private String nickName;

}

Mapper 和xml

public interface Users1Mapper extends BaseMapper<Users> {
}
public interface Users2Mapper extends BaseMapper<Users> {
}
<?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.husy.springboot.multisource.mapper.test1.Users1Mapper">
</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">
<mapper namespace="com.husy.springboot.multisource.mapper.test2.Users1Mapper">
</mapper>

service

public interface IUsersService{
	List<Users> getAll();
	Users getOne(Long id);
	void insert(Users user);
	void update(Users user);
	void delete(Long id);
}

@Service
public class UsersServiceImpl implements IUsersService {
	@Resource
	Users1Mapper users1Mapper;
	@Resource
	Users2Mapper users2Mapper;

	@Override
	public List<Users> getAll() {
		return users2Mapper.selectList(new QueryWrapper<>());
	}

	@Override
	public Users getOne(Long id) {
		return users2Mapper.selectById(id);
	}

	@Override
	public void insert(Users user) {
		users1Mapper.insert(user);
	}

	@Override
	public void update(Users user) {
		users1Mapper.update(user,null);
	}

	@Override
	public void delete(Long id) {
		users1Mapper.deleteById(id);
	}
}

controller

@RestController
@RequestMapping("users")
public class UsersController {
	@Autowired
	IUsersService usersService;

	@RequestMapping("/getUsers")
	public List<Users> getUsers() {
		List<Users> users=usersService.getAll();
		return users;
	}

	@RequestMapping("/getUser")
	public Users getUser(Long id) {
		Users user=usersService.getOne(id);
		return user;
	}

	@RequestMapping("/add")
	public void save(@RequestBody  Users user) {
		usersService.insert(user);
	}

	@RequestMapping(value="update")
	public void update(@RequestBody Users user) {
		usersService.update(user);
	}

	@RequestMapping(value="/delete/{id}")
	public void delete(@PathVariable("id") Long id) {
		usersService.delete(id);
	}
}

项目目录结构如下

在这里插入图片描述

GitHub项目地址:https://github.com/HusyCoding/springboot-demo/tree/master/springboot-multi-source

SQL脚本:

CREATE TABLE `users` (
	`user_id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键id',
	`user_name` VARCHAR(32) NOT NULL COMMENT '用户名' COLLATE 'utf8_general_ci',
	`password` VARCHAR(32) NOT NULL COMMENT '密码' COLLATE 'utf8_general_ci',
	`user_sex` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '0:男,1:女',
	`nick_name` VARCHAR(32) NULL DEFAULT NULL COLLATE 'utf8_general_ci',
	PRIMARY KEY (`user_id`)
)
COLLATE='utf8mb4_unicode_ci'
ENGINE=InnoDB
AUTO_INCREMENT=1
;

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