springboot mybatis druid配置多数据源教程
目录
- 1、项目代码结构
- 2、导入基本依赖
- 3、配置多数据源
- 4、配置类
- 5、启动类
- 6、测试使用的表
- 7、测试表对应的实体类
- 8、持久层:dao层接口
1、项目代码结构
2、导入基本依赖
记得需要导入mysql驱动mysql-connector-java
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.2</version> </dependency> <dependency> <!-- MySql驱动 --> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!--druid 依赖--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies>
3、配置多数据源
注意:Spring Boot 2.X 版本不再支持配置继承,多数据源的话每个数据源的所有配置都需要单独配置,否则配置不会生效。
spring: datasource: db1: url: jdbc:mysql://127.0.0.1:3306/db01?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false username: root password: driver-class-name: com.mysql.cj.jdbc.Driver # 初始化时建立物理连接的个数。初始化发生在显示调用 init 方法,或者第一次 getConnection 时 initialSize: 5 # 最小连接池数量 minIdle: 5 # 最大连接池数量 maxActive: 10 # 获取连接时最大等待时间,单位毫秒。配置了 maxWait 之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置 useUnfairLock 属性为 true 使用非公平锁。 maxWait: 60000 # Destroy 线程会检测连接的间隔时间,如果连接空闲时间大于等于 minEvictableIdleTimeMillis 则关闭物理连接。 timeBetweenEvictionRunsMillis: 60000 # 连接保持空闲而不被驱逐的最小时间 minEvictableIdleTimeMillis: 300000 # 用来检测连接是否有效的 sql 因数据库方言而异, 例如 oracle 应该写成 SELECT 1 FROM DUAL validationQuery: SELECT 1 # 建议配置为 true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于 timeBetweenEvictionRunsMillis,执行 validationQuery 检测连接是否有效。 testWhileIdle: true # 申请连接时执行 validationQuery 检测连接是否有效,做了这个配置会降低性能。 testOnBorrow: false # 归还连接时执行 validationQuery 检测连接是否有效,做了这个配置会降低性能。 testOnReturn: false # 是否自动回收超时连接 removeAbandoned: true # 超时时间 (以秒数为单位) remove-abandoned-timeout: 1800 db2: url: jdbc:mysql://127.0.0.1:3306/db02?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false username: root password: driver-class-name: com.mysql.cj.jdbc.Driver # 初始化时建立物理连接的个数。初始化发生在显示调用 init 方法,或者第一次 getConnection 时 initialSize: 6 # 最小连接池数量 minIdle: 6 # 最大连接池数量 maxActive: 10 # 获取连接时最大等待时间,单位毫秒。配置了 maxWait 之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置 useUnfairLock 属性为 true 使用非公平锁。 maxWait: 60000 # Destroy 线程会检测连接的间隔时间,如果连接空闲时间大于等于 minEvictableIdleTimeMillis 则关闭物理连接。 timeBetweenEvictionRunsMillis: 60000 # 连接保持空闲而不被驱逐的最小时间 minEvictableIdleTimeMillis: 300000 # 用来检测连接是否有效的 sql 因数据库方言而异, 例如 oracle 应该写成 SELECT 1 FROM DUAL validationQuery: SELECT 1 # 建议配置为 true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于 timeBetweenEvictionRunsMillis,执行 validationQuery 检测连接是否有效。 testWhileIdle: true # 申请连接时执行 validationQuery 检测连接是否有效,做了这个配置会降低性能。 testOnBorrow: false # 归还连接时执行 validationQuery 检测连接是否有效,做了这个配置会降低性能。 testOnReturn: false # 是否自动回收超时连接 removeAbandoned: true # 超时时间 (以秒数为单位) remove-abandoned-timeout: 1800 # WebStatFilter 用于采集 web-jdbc 关联监控的数据。 web-stat-filter: # 是否开启 WebStatFilter 默认是 true enabled: true # 需要拦截的 url url-pattern: /* # 排除静态资源的请求 exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*" # Druid 内置提供了一个 StatViewServlet 用于展示 Druid 的统计信息。 stat-view-servlet: #是否启用 StatViewServlet 默认值 true enabled: true # 需要拦截的 url url-pattern: /druid/* # 允许清空统计数据 reset-enable: true login-username: druid login-password: druid
4、配置类
主数据源配置类:
package com.study.multisource.config; import com.alibaba.druid.pool.DruidDataSource; 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 javax.sql.DataSource; /** * @author liuhui * @date 2020/5/14 16:56 */ @Configuration @MapperScan(basePackages = "com.study.multisource.mybatis.oneDao",sqlSessionFactoryRef = "oneSqlSessionFactory") public class DataSourceConfig1 { // 将这个对象放入Spring容器中 @Bean(name = "oneDataSource") // 表示这个数据源是默认数据源 @Primary // 读取application.properties中的配置参数映射成为一个对象 // prefix表示参数的前缀 @ConfigurationProperties(prefix = "spring.datasource.db1") public DataSource getDateSource1() { return DataSourceBuilder.create().type(DruidDataSource.class).build(); } @Bean(name = "oneSqlSessionFactory") // 表示这个数据源是默认数据源 @Primary // @Qualifier表示查找Spring容器中名字为oneDataSource的对象 public SqlSessionFactory oneSqlSessionFactory(@Qualifier("oneDataSource") DataSource datasource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(datasource); bean.setMapperLocations( // 设置mybatis的xml所在位置 new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/one/*.xml")); return bean.getObject(); } @Bean("oneSqlSessionTemplate") // 表示这个数据源是默认数据源 @Primary public SqlSessionTemplate oneSqlSessionTemplate( @Qualifier("oneSqlSessionFactory") SqlSessionFactory sessionFactory) { return new SqlSessionTemplate(sessionFactory); } }
次数据源配置类:
package com.study.multisource.config; import com.alibaba.druid.pool.DruidDataSource; 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 javax.sql.DataSource; /** * @author liuhui * @date 2020/5/14 17:07 */ @Configuration @MapperScan(basePackages = "com.study.multisource.mybatis.twoDao",sqlSessionFactoryRef = "twoSqlSessionFactory") public class DataSourceConfig2 { // 将这个对象放入Spring容器中 @Bean(name = "twoDataSource") // 读取application.properties中的配置参数映射成为一个对象 // prefix表示参数的前缀 @ConfigurationProperties(prefix = "spring.datasource.db2") public DataSource getDateSource1() { return DataSourceBuilder.create().type(DruidDataSource.class).build(); } @Bean(name = "twoSqlSessionFactory") // 表示这个数据源是默认数据源 @Primary // @Qualifier表示查找Spring容器中名字为oneDataSource的对象 public SqlSessionFactory oneSqlSessionFactory(@Qualifier("twoDataSource") DataSource datasource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(datasource); bean.setMapperLocations( // 设置mybatis的xml所在位置 new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/two/*.xml")); return bean.getObject(); } @Bean("twoSqlSessionTemplate") // 表示这个数据源是默认数据源 @Primary public SqlSessionTemplate oneSqlSessionTemplate( @Qualifier("twoSqlSessionFactory") SqlSessionFactory sessionFactory) { return new SqlSessionTemplate(sessionFactory); } }
5、启动类
注意:不需要使用自动配置,那么需要取消加载对应的自动配置类。
在启动类关闭 Spring Boot 对数据源的自动化配置,由我们手动进行多数据源的配置:
package com.study.multisource; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) public class MultisourceApplication { public static void main(String[] args) { SpringApplication.run(MultisourceApplication.class, args); } }
6、测试使用的表
#建在db01库下 CREATE TABLE `user` ( `id` bigint(20) NOT NULL, `name` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; #建在db02库下 CREATE TABLE `t_item_order` ( `id` int(9) NOT NULL AUTO_INCREMENT COMMENT '自增id', `item_id` int(4) NOT NULL COMMENT '商品id', `item_name` varchar(50) NOT NULL DEFAULT '' COMMENT '商品名称', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COMMENT='商品表';
7、测试表对应的实体类
package com.study.multisource.entity; import lombok.Data; import lombok.ToString; /** * @author liuhui * @date 2020/5/14 17:32 */ @Data @ToString public class ItemOrder { private Integer id; private Integer itemId; private String itemName; }
package com.study.multisource.entity; import lombok.Data; import lombok.ToString; /** * @author liuhui * @date 2020/5/14 17:29 */ @Data @ToString public class User { private Long id; private String name; }
8、持久层:dao层接口
(注意:我将其放在不同目录下方便区分管理):
package com.study.multisource.mybatis.oneDao; import com.study.multisource.entity.User; import java.util.List; public interface UserMapper { List<User> getAllUser(); }
package com.study.multisource.mybatis.twoDao; import com.study.multisource.entity.ItemOrder; import java.util.List; public interface ItemOrderMapper { List<ItemOrder> getAllItemOrder(); }
dao层对应的xml配置文件:
UserMapper.xml
<?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.study.multisource.mybatis.oneDao.UserMapper"> <select id="getAllUser" resultType="com.study.multisource.entity.User"> select * from `user` </select> </mapper>
ItemOrderMapper.xml
<?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.study.multisource.mybatis.twoDao.ItemOrderMapper"> <resultMap id="BaseResultMap" type="com.study.multisource.entity.ItemOrder"> <id column="id" jdbcType="BIGINT" property="id" /> <result column="item_id" jdbcType="INTEGER" property="itemId" /> <result column="item_name" jdbcType="VARCHAR" property="itemName" /> </resultMap> <select id="getAllItemOrder" resultMap="BaseResultMap"> select * from t_item_order </select> </mapper>
service层:
接口:
package com.study.multisource.service; import com.study.multisource.entity.ItemOrder; import com.study.multisource.entity.User; import java.util.List; /** * @author liuhui * @date 2020/5/14 17:24 */ public interface TestService { public List<User> getAllUser(); public List<ItemOrder> getAllItemOrder(); }
实现类:
package com.study.multisource.service.impl; import com.study.multisource.entity.ItemOrder; import com.study.multisource.entity.User; import com.study.multisource.mybatis.oneDao.UserMapper; import com.study.multisource.mybatis.twoDao.ItemOrderMapper; import com.study.multisource.service.TestService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; /** * @author liuhui * @date 2020/5/14 17:25 */ @Service public class TestServiceImpl implements TestService { @Autowired UserMapper userMapper; @Autowired ItemOrderMapper itemOrderMapper; @Override public List<User> getAllUser() { return userMapper.getAllUser(); } @Override public List<ItemOrder> getAllItemOrder() { return itemOrderMapper.getAllItemOrder(); } }
下面进行测试:
package com.study.multisource.multisource; import com.study.multisource.service.TestService; import lombok.ToString; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest class MultisourceApplicationTests { @Autowired TestService testService; @Test void contextLoads() { } @Test void testS(){ System.out.println(testService.getAllItemOrder()); System.out.println(testService.getAllUser()); } }
结果:
2020-05-16 08:54:17.566 INFO 12556 --- [ main] com.alibaba.druid.pool.DruidDataSource : {dataSource-1} inited
[ItemOrder(id=1, itemId=101, itemName=泡泡糖)]
--------------------------
2020-05-16 08:54:17.752 INFO 12556 --- [ main] com.alibaba.druid.pool.DruidDataSource : {dataSource-2} inited
[User(id=2, name=Lucy), User(id=4, name=Lina)]
当然也可以不用向上面分的那么细,也可以把多个数据源下面的XxxMapper.xml放在同一个目录下,同时就可以把多个数据源的配置类解析的xml路径写成同一个了
new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/*.xml"));
以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。