Java架构师方案—多数据源开发详解及原理(二)(附完整项目代码)
1. mybatis下数据源开发工作
在properties文件中配置两个数据库连接参数demo项目使用的是hikari数据源,配置 数据库地址,用户名,密码,数据库驱动等参数,在DataSource1Config类中通过@ConfigurationProperties(prefix = "spring.datasource.hikari.db1")的方式将参数注入到DataSource对象中。DataSource1Config类和DataSource2Config类分别创建了两个数据源对象。
server.port=8080
# 数据库myutilproject0
spring.datasource.hikari.db1.jdbc-url=jdbc:mysql://ip:port/myutilproject0?characterEncoding=GBK&useSSL=false
spring.datasource.hikari.db1.username=root
spring.datasource.hikari.db1.password=
spring.datasource.hikari.db1.driver-class-name=com.mysql.cj.jdbc.Driver
# 数据库myutilproject1
spring.datasource.hikari.db2.jdbc-url=jdbc:mysql://ip:port/myutilproject1?characterEncoding=GBK&useSSL=false
spring.datasource.hikari.db2.username=root
spring.datasource.hikari.db2.password=
spring.datasource.hikari.db2.driver-class-name=com.mysql.cj.jdbc.Driver
配置Dao层需要的工具对象:DataSource,SqlSessionFactory,SqlSessionTemplate(SqlSession),DataSourceTransactionManager
DataSource: 数据源对象,封装与数据库交互的connection对象,通过spring的@ConfigurationProperties注解方式获取配置参数并创建该对象。
SqlSessionFactory:SqlSession对象的创建工厂,关联Dao层的代理对象,代理对象需要的SqlSession从这里获取。
SqlSession:负责与数据库进行数据传输和交互并维护会话状态,这里使用了SqlSessionTemplate代理mybatis默认的SqlSession实现类,其实动态切换多数据源的方案也可以通过覆盖SqlSession来实现。
DataSourceTransactionManager:开启并配置数据源对象的事务管理器,开启事务机制。
@MapperScan工作目标:创建mapper接口的代理对象,关联配置的SqlSessionFactory对象,使用了该注解就不需要在mapper接口上使用@Mapper了。
@Mapper:告诉spring及mybatis,这个是mapper接口,需要创建代理对象。
注意:@MapperScan(basePackages = "jackdking.dao.db2", sqlSessionTemplateRef = "db2SqlSessionTemplate")这个地方有个关键点:这里生成的mapper接口代理对象与数据交互使用的sqlsession指定为db2SqlSessionTemplate,因此你选择db2中的对象就相当于选择了对应的数据库。
package jackdking.config;
import javax.sql.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.jdbc.datasource.DataSourceTransactionManager;
/**
* 数据源1配置
* @author YI
* @date 2018-12-6 09:35:36
*/
@Configuration
@MapperScan(basePackages = "jackdking.dao.db1", sqlSessionTemplateRef = "db1SqlSessionTemplate")
public class DataSource1Config {
/**
* 生成数据源. @Primary 注解声明为默认数据源
*/
@Bean(name = "db1DataSource")
@ConfigurationProperties(prefix = "spring.datasource.hikari.db1")
@Primary
public DataSource testDataSource() {
return DataSourceBuilder.create().build();
}
/**
* 创建 SqlSessionFactory
*/
@Bean(name = "db1SqlSessionFactory")
@Primary
public SqlSessionFactory testSqlSessionFactory(@Qualifier("db1DataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
// 如果使用xml请放开下面配置
// bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/db1/*.xml"));
return bean.getObject();
}
/**
* 配置事务管理
*/
@Bean(name = "db1TransactionManager")
@Primary
public DataSourceTransactionManager testTransactionManager(@Qualifier("db1DataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
/**
* 配置数据库操作模板
* @param sqlSessionFactory
* @return
* @throws Exception
*/
@Bean(name = "db1SqlSessionTemplate")
@Primary
public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("db1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
Mapper接口
import org.springframework.beans.factory.annotation.Qualifier;
import jackdking.bean.User;
@Qualifier("db1SqlSessionTemplate")
public interface User1Mapper {
User selectByPrimaryKey(Integer id);
}
2. 数据源与DAO的关系原理模型
从Dao层到DataSource的上下层级依赖关系
而我们对这些模型对象的依赖配置是由DataSource往Dao层方向进行的,从上图来看,DAO与数据源的关系模型非常明了。
3. 为什么要配置SqlSessionTemplate类的bean
我们Dao层直接打交道的是SQLSession,mybatis默认的是DefaultSqlSession,这里使用了SqlSessionTemplate来替代它。
以下是使用SqlSessionTemplate的好处
- SqlSessionTemplate是MyBatis-Spring的核心。这个类负责管理MyBatis的SqlSession,调用MyBatis的SQL方法。SqlSessionTemplate是线程安全的,可以被多个DAO所共享使用。
- 当调用SQL方法时,包含从映射器getMapper()方法返回的方法,SqlSessionTemplate将会保证使用的SqlSession是和当前Spring的事务相关的。此外,它管理session的生命周期,包含必要的关闭,提交或回滚操作。
- SqlSessionTemplate实现了SqlSession,这就是说要对MyBatis的SqlSession进行简易替换。
- SqlSessionTemplate通常是被用来替代默认的MyBatis实现的DefaultSqlSession,因为它不能参与到Spring的事务中也不能被注入,因为它是线程不安全的。相同应用程序中两个类之间的转换可能会引起数据一致性的问题。
4. 多数据源应用测试
多数据源应用和原理的分析,我之前的一篇文章也剖析过,是需要通过注解的形式来选择数据源:Java架构师方案—多数据源原理及应用(一)(附完整项目代码)
而这篇文章介绍的应用是不需要使用注解方式的,因为DAO层的dao对象是绑定了数据源的,你选择不同的dao就选择了不同的数据源。
测试类MyApplicationRunner
@Component
public class MyApplicationRunner implements ApplicationRunner{
@Autowired
User1Mapper user1Mapper;
@Autowired
User2Mapper user2Mapper;
@Override
public void run(ApplicationArguments args) throws Exception {
// TODO Auto-generated method stub
System.out.println("从db1数据库中查询数据");
//从db1中查出数据
User user1 = user1Mapper.selectByPrimaryKey(11);
System.out.println(user1.toString());
System.out.println("从db2数据库中查询数据");
//从db2中查出数据
User user2 = user2Mapper.selectByPrimaryKey(11);
System.out.println(user2.toString());
}
}
db1:myutilproject0 的user表数据
db2:myutilproject1 的user表数据
启动项目,测试数据如下
从db1数据库中查询数据
2020-09-16 11:13:22.679 INFO 20064 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2020-09-16 11:13:23.230 INFO 20064 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
User [id=11, name=jackdking-master, gender=male]
从db2数据库中查询数据
2020-09-16 11:13:23.305 INFO 20064 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-2 - Starting...
2020-09-16 11:13:23.746 INFO 20064 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-2 - Start completed.
User [id=11, name=jackdking-slave, gender=male]
从测试数据可以得出结论,不同的dao从不同的库中查询出数据,因此这个项目通过将不同dao绑定到不同的数据源来实现多数据源场景。
关注共图社,有更多惊喜。
欢迎加入技术群:获得更多java,springboot,redis,kafka圈的好友,共图技术未来
点击获取技术群二维码
还要配置状态转移信息以及事件处理器逻辑的开发。完整的demo项目,请关注公众号“前沿科技bot“并发送"多数据源"获取。
- 本文标签: Java Spring Spring Boot
- 版权声明: 本站原创文章,于2020年07月22日由空白发布,转载请注明出处