微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

通过springboot+mybatis+druid配置动态数据源

这篇文章主要介绍了通过springboot+mybatis+druid配置动态数据源,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,,需要的朋友可以参考下

一、建数据库和表

1.数据库demo1放一张user表

SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for user -- ---------------------------- DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` int(11) NOT NULL, `name` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of user -- ---------------------------- INSERT INTO `user` VALUES ('1', 'aa'); INSERT INTO `user` VALUES ('2', 'bb');

2.数据库demo2放一张role表

SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for role -- ---------------------------- DROP TABLE IF EXISTS `role`; CREATE TABLE `role` ( `id` int(11) NOT NULL, `name` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of role -- ---------------------------- INSERT INTO `role` VALUES ('1', 'CC'); INSERT INTO `role` VALUES ('2', 'DD');

二、pom.xml引入包

org.springframework.bootspring-boot-starter-weborg.springframework.bootspring-boot-starter-testtestorg.springframework.bootspring-boot-starter-thymeleafMysqLmysql-connector-javaruntimeMysqLmysql-connector-javaorg.springframework.bootspring-boot-starter-jdbcorg.mybatis.spring.bootmybatis-spring-boot-starter2.0.1org.aspectjaspectjweavercom.alibabadruid-spring-boot-starter1.1.10com.typesafe.dynamicdatasourcedynamic-data-source_2.11

三、用generator插件生成user、role两张表的实体类、mapper.java、mapper.xml

User.java Role.java UserMapper.java RoleMapper.java UserMapper.xml RoleMapper.xml

四、配置application.yml

server: port: 8088 mybatis: mapper-locations: classpath:mapper/*.xml spring: datasource: db1: url: jdbc:MysqL://localhost:3306/demo1?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT username: root password: root type: com.alibaba.druid.pool.DruidDataSource #驱动包 driver-class-name: com.MysqL.cj.jdbc.Driver #初始连接数 initial-size: 5 #最小空闲数 min-idle: 5 #最大活动数 max-active: 20 #等待超时时间 max-wait: 60000 #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 time-between-eviction-runs-millis: 60000 # 配置一个连接在池中最小生存的时间,单位是毫秒 min-evictable-idle-time-millis: 300000 #验证数据库连接的查询语句,MysqL是select 1 validation-query: SELECT 1 FROM DUAL #空闲时测试,testOnBorrow和testOnReturn在生产环境一般是不开启的,主要是性能考虑。失效连接主要通过testWhileIdle保证 test-while-idle: true test-on-borrow: false test-on-return: false #打开PSCache,并指定每个链接上的PSCache大小 pool-prepared-statements: true max-pool-prepared-statement-per-connection-size: 20 #配置监控统计拦截的filters,去掉后监控界面sql无法统计,‘wall'用于防火墙,此处是filter修改的地方 filters: stat,wall #通过connectproperties属性来打开mergesql功能:慢sql记录 connection-properties: druid.stat.mergesql=true;druid.stat.slowsqlMillis=5000 #合并多个DruidDataSource useglobalDataSourceStat: true db2: url: jdbc:MysqL://localhost:3306/demo2?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT username: root password: root type: com.alibaba.druid.pool.DruidDataSource #驱动包 driver-class-name: com.MysqL.cj.jdbc.Driver #初始连接数 initial-size: 5 #最小空闲数 min-idle: 5 #最大活动数 max-active: 20 #等待超时时间 max-wait: 60000 #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 time-between-eviction-runs-millis: 60000 # 配置一个连接在池中最小生存的时间,单位是毫秒 min-evictable-idle-time-millis: 300000 #验证数据库连接的查询语句,MysqL是select 1 validation-query: SELECT 1 FROM DUAL #空闲时测试,testOnBorrow和testOnReturn在生产环境一般是不开启的,主要是性能考虑。失效连接主要通过testWhileIdle保证 test-while-idle: true test-on-borrow: false test-on-return: false #打开PSCache,并指定每个链接上的PSCache大小 pool-prepared-statements: true max-pool-prepared-statement-per-connection-size: 20 #配置监控统计拦截的filters,去掉后监控界面sql无法统计,‘wall'用于防火墙,此处是filter修改的地方 filters: stat,wall #通过connectproperties属性来打开mergesql功能:慢sql记录 connection-properties: druid.stat.mergesql=true;druid.stat.slowsqlMillis=5000 #合并多个DruidDataSource useglobalDataSourceStat: true

五、启动类扫描mapper.java文件

@SpringBootApplication @MapperScan("com.example.demo.dao") public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }

六、定义DataSourceConfig, 将application.yml中的配置导入DataSource中,并注入到bean

@Configuration public class DataSourceConfig { //从配置文件配置数据源 @Primary @Bean(name="datasource1") @ConfigurationProperties("spring.datasource.db1") public DataSource dataSource1(){ return new DruidDataSource(); } //从配置文件配置数据源 @Bean(name="datasource2") @ConfigurationProperties("spring.datasource.db2") public DataSource dataSource2(){ return new DruidDataSource(); } //动态数据源 进行数据源切换 @Bean(name="dynamicDataSource") public DataSource dynamicDataSource(){ DynamicDataSource dynamicDatasource=new DynamicDataSource(); //设置认数据源 dynamicDatasource.setDefaultTargetDataSource(dataSource1()); //配置多数据源 Map dsMap=new HashMap(); dsMap.put("datasource1",dataSource1()); dsMap.put("datasource2",dataSource2()); //将多数据源放到数据源池中 dynamicDatasource.setTargetDataSources(dsMap); return dynamicDatasource; } }

七、定义动态数据源切换类DynamicDataSourceContextHolder

public class DynamicDataSourceContextHolder { private static final ThreadLocal contextHolder=new ThreadLocal(); //设置数据源名称 public static void setDB(String dbType){ contextHolder.set(dbType); } //获取数据源名称 public static String getDB(){ return contextHolder.get(); } //清除数据源名 public static void clearDB(){ contextHolder.remove(); } }

八、定义获取动态数据源类DynamicDataSource

public class DynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return DynamicDataSourceContextHolder.getDB(); } }

九、定义mybatis配置类,将DynamicDataSource放入sqlSessionfactorybean

@EnableTransactionManagement @Configuration public class MyBatisConfig { @Resource(name = "dynamicDataSource") private DataSource dynamicDataSource; @Bean public sqlSessionFactory sqlSessionFactory() throws Exception { sqlSessionfactorybean sqlSessionfactorybean = new sqlSessionfactorybean(); sqlSessionfactorybean.setDataSource(dynamicDataSource);//将动态数据源bean配置到sqlsessionfactory sqlSessionfactorybean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml")); return sqlSessionfactorybean.getobject(); } @Bean public PlatformTransactionManager platformTransactionManager() { return new DataSourceTransactionManager(dynamicDataSource); } }十、定义用于切换数据源的注解TargetDataSource

@Target({ElementType.METHOD,ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface TargetDataSource { String value() default "datasource1"; }

十一、定义切面DynamicDataSourceAspect,用于拦截注解,并执行数据源切换功能

@Aspect @Component public class DynamicDataSourceAspect { @Before("@annotation(targetDataSource)") public void beforeSwitchDS(JoinPoint point,TargetDataSource targetDataSource){ DynamicDataSourceContextHolder.setDB(targetDataSource.value()); } @After("@annotation(targetDataSource)") public void afterSwitchDS(JoinPoint point,TargetDataSource targetDataSource){ DynamicDataSourceContextHolder.clearDB(); } }

十二、测试类Test

@RestController public class Test { @Autowired private RoleMapper roleMapper; @Autowired private UserMapper userMapper; //未使用TargetDataSource注解,则使用认数据源,即datasource1 @RequestMapping("/ds1") public String selectDataSource1(){ return userMapper.selectByPrimaryKey(1).toString(); } //使用了注解,则数据源为注解中指定的datasource2 @RequestMapping("/ds2") @TargetDataSource("datasource2") public String selectDataSource2(){ return roleMapper.selectByPrimaryKey(1).toString(); } }

测试

1.输入

http://localhost:8088/ds1

返回

2.输入

http://localhost:8088/ds2

返回

结论:两次请求分别从不同的数据库获取到了数据,多数据源配置成功!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐