杭州盘石做网站专业吗,域名估价网站,忻州做网站,竣工验收备案表查询网站作者简介#xff1a;大家好#xff0c;我是撸代码的羊驼#xff0c;前阿里巴巴架构师#xff0c;现某互联网公司CTO 联系v#xff1a;sulny_ann#xff08;17362204968#xff09;#xff0c;加我进群#xff0c;大家一起学习#xff0c;一起进步#xff0c;一起对抗…作者简介大家好我是撸代码的羊驼前阿里巴巴架构师现某互联网公司CTO 联系vsulny_ann17362204968加我进群大家一起学习一起进步一起对抗互联网寒冬 在《Spring Boot中JdbcTemplate源码分析》中讲到了自动配置相关的源代码实现。基于Spring Boot自动配置默认配置的组件我们可以来自定义JdbcTemplate的实例化。而多数据源的配置就是在此基础上实例化多个数据源和JdbcTemplate。
下面我们来看具体的源代码实现。
依赖类库
关于依赖类库与集成JdbcTemplate时的一样Spring Boot版本2.2.2.RELEASE。
相关pom依赖如下
dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency!--数据库连接相关-- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-jdbc/artifactId /dependency dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId /dependencydependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId optionaltrue/optional /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-test/artifactId scopetest/scope exclusions exclusion groupIdorg.junit.vintage/groupId artifactIdjunit-vintage-engine/artifactId /exclusion /exclusions /dependency/dependencies
spring-boot-starter-jdbc是集成jdbc的依赖mysql-connector-java是基于mysql的依赖类库。lombok是简化代码的工具类如果不需要可去掉并去掉类中相关的注解。
spring-boot-starter-test为单元测试依赖的类库这里单元测试使用的是junit5注意使用方法与junit4差别比较大。
配置application
application.properties配置如下
spring.datasource.primary.jdbc-urljdbc:mysql://localhost:3306/spring?serverTimezoneUTCuseUnicodetruecharacterEncodingutf-8useSSLtruespring.datasource.primary.usernamerootspring.datasource.primary.passwordroot_123spring.datasource.primary.driver-class-namecom.mysql.cj.jdbc.Driver
spring.datasource.secondary.jdbc-urljdbc:mysql://localhost:3306/spring1?serverTimezoneUTCuseUnicodetrue\ characterEncodingutf-8useSSLtruespring.datasource.secondary.usernamerootspring.datasource.secondary.passwordroot_123spring.datasource.secondary.driver-class-namecom.mysql.cj.jdbc.Driver
既然是多数据源肯定要配置多个数据源的配置。与单数据源配置基本形式差不多。
需要注意的是第一个配置项的key为spring.datasource.primary.jdbc-url。与单数据源时使用的spring.datasource.url有所区别。不然启动时会抛出异常。
多数据源对应的Java配置
下面就需要我们自己来实例化DataSource和JdbcTemplate。相关的实例化也可参看源码解析文章中Spring Boot的实例化方式。
这里我们的实现如下
Configurationpublic class DataSourceConfig {Primary Bean(name primaryDataSource) ConfigurationProperties(prefixspring.datasource.primary) public DataSource primaryDataSource() { return DataSourceBuilder.create().build(); }Bean(name secondaryDataSource) ConfigurationProperties(prefixspring.datasource.secondary) public DataSource secondaryDataSource() { return DataSourceBuilder.create().build(); }Bean(nameprimaryJdbcTemplate) public JdbcTemplate primaryJdbcTemplate (Qualifier(primaryDataSource) DataSource dataSource ) { return new JdbcTemplate(dataSource); }Bean(namesecondaryJdbcTemplate) public JdbcTemplate secondaryJdbcTemplate(Qualifier(secondaryDataSource) DataSource dataSource) { return new JdbcTemplate(dataSource); }
}
Configuration声明该类为配置类。
Primary指定当出现多个相同类型的实例化对象时以该注解标注的为默认的。
Bean实例化Bean并将其注入到容器当中。这里分别实例化了primaryDataSource和secondaryDataSource两个DataSource以Bean的名称来区分。
ConfigurationProperties将前缀为spring.datasource.primary和前缀为spring.datasource.secondary的配置属性设置到对应的DataSource中。
随后实例化了两个JdbcTemplate直接通过new关键字创建并且把对应的DataSource作为构造参数传入。
经过该配置文件的配置便有了两个JdbcTemplate。
实体类
实体类如下
Datapublic class Order {private int id;private String orderNo;private int amount;}
Data为Lombok的注解自动生成一些默认的方法比如属性的getter/setter方法。
数据库
关于数据库的DDL如下
CREATE TABLE tb_order ( id int(11) NOT NULL AUTO_INCREMENT, amount int(11) NOT NULL DEFAULT 1, order_no varchar(64) NOT NULL DEFAULT , PRIMARY KEY (id)) ENGINEInnoDB AUTO_INCREMENT2 DEFAULT CHARSETutf8
同样的表在两个数据库中进行创建。
接口定义
定义OrderService接口
public interface OrderService {/** * 创建订单 * param order 订单信息 * return 记录数 */ int save(Order order);/** * 保存到指定库 * param order 订单信息 * param jdbcTemplate jdbc * return */ int save(Order order, JdbcTemplate jdbcTemplate);}
接口实现
Service(orderService)public class OrderServiceImpl implements OrderService {Resource Qualifier(primaryJdbcTemplate) private JdbcTemplate jdbcTemplate;Override public int save(Order order) { return jdbcTemplate.update(insert into tb_order(order_no, amount) values(?, ?), order.getOrderNo(), order.getAmount()); }Override public int save(Order order, JdbcTemplate secJdbcTemplate) { if (secJdbcTemplate ! null) { return secJdbcTemplate.update(insert into tb_order(order_no, amount) values(?, ?), order.getOrderNo(), order.getAmount()); } else { return jdbcTemplate.update(insert into tb_order(order_no, amount) values(?, ?), order.getOrderNo(), order.getAmount()); } }}
在实现方法中默认注入了主库的JdbcTemplate同时在原来的save方法中新增了一个JdbcTemplate参数可以根据是否传递该新的JdbcTemplate来决定使用哪个JdbcTemplate。
当然在此方法内也可以使用一个JdbcTemplate然后根据参数动态的修改该JdbcTemplate指向的具体实现类。可以根据具体情况进行灵活运用。
单元测试
单元测试类如下
Slf4jSpringBootTestclass OrderServiceTest {Resource private OrderService orderService;Resource Qualifier(primaryJdbcTemplate) private JdbcTemplate primaryJdbcTemplate;Resource Qualifier(secondaryJdbcTemplate) private JdbcTemplate secondaryJdbcTemplate;Test void save() { Order order new Order(); order.setOrderNo(N003); order.setAmount(10000); orderService.save(order, primaryJdbcTemplate); orderService.save(order, secondaryJdbcTemplate); }}
执行以上单元测试两个库中的tb_order表分别插入了一条数据。关于其他增删改查操作可参考保存方法进行扩展。