Mybatis 您所在的位置:网站首页 mybatis的数据源 Mybatis

Mybatis

#Mybatis | 来源: 网络整理| 查看: 265

文章目录 前言业务逻辑使用Mybatis实现使用Mybatis-plus实现

前言

​ 工作的时候,遇到了需要将一个数据库的一些数据插入或更新到另一个数据库。一开始使用insert into TABLE (col1,col2) VALUES (val1,val2) ON DUPLICATE KEY update col1 = "val1"; (这句sql语句的意思是:将val1,val2值插入到TABLE表的col1和col2字段中,如果出现主键或唯一冲突,就进行更新,只将col1值更新为val1)进行数据的插入和更新。但是每次都要对着这一条sql语句进行修改,十分麻烦,就想着能否同时连接两个数据库进行业务处理。

业务逻辑

在这里插入图片描述

使用Mybatis实现

首先,如果你的项目用的是Mybatis,那么以下配置可以实现配置多数据源,连接多数据库的作用。但是,如果你使用的是Mybatis-plus,本人建议使用Mybatis-plus实现更加简单易操作。

1、在yml配置文件中配置多数据库,例如:

spring: application: name: CONNECTION datasource: db1: driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://localhost:3306/test?serverTimezone=UTC username: root password: 123456 type: com.alibaba.druid.pool.DruidDataSource db2: driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://11.11.11.11:3306/test?serverTimezone=UTC username: root password: 654321 type: com.alibaba.druid.pool.DruidDataSource

注意,将数据库配置中的url改为jdbc-url,否则无法配置多数据源。

2、创建不同的mapper,用于不同的数据库。 请添加图片描述 3、编写数据源的配置类,例如:

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 org.springframework.jdbc.datasource.DataSourceTransactionManager; import javax.sql.DataSource; @Configuration @MapperScan(basePackages = "com.czf.connect.mapper.db1", sqlSessionTemplateRef = "db1SqlSessionTemplate") //此处的basePackages指向的是你存放数据库db1的mapper的包 public class DataSource1Config { @Bean(name = "db1DataSource") @ConfigurationProperties(prefix = "spring.datasource.db1")//指向yml配置文件中的数据库配置 @Primary //主库加这个注解,修改优先权,表示发现相同类型bean,优先使用该方法。 public DataSource dbDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "db1SqlSessionFactory") @Primary public SqlSessionFactory dbSqlSessionFactory(@Qualifier("db1DataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*xml")); //这个的getResources指向的是你的mapper.xml文件,相当于在yml中配置的mapper-locations,此处配置了yml中就不用配置,或者说不会读取yml中的该配置。 return bean.getObject(); } @Bean(name = "db1TransactionManager") @Primary public DataSourceTransactionManager dbTransactionManager(@Qualifier("db1DataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } @Bean(name = "db1SqlSessionTemplate") @Primary public SqlSessionTemplate dbSqlSessionTemplate(@Qualifier("db1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } }

数据库db2的配置类:

@Configuration @MapperScan(basePackages = "com.czf.connect.mapper.db2", sqlSessionTemplateRef = "db2SqlSessionTemplate") public class DataSource2Config { @Bean(name = "db2DataSource") @ConfigurationProperties(prefix = "spring.datasource.db2") public DataSource dbDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "db2SqlSessionFactory") public SqlSessionFactory dbSqlSessionFactory(@Qualifier("db2DataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*xml")); return bean.getObject(); } @Bean(name = "db2TransactionManager") public DataSourceTransactionManager dbTransactionManager(@Qualifier("db2DataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } @Bean(name = "db2SqlSessionTemplate") public SqlSessionTemplate dbSqlSessionTemplate(@Qualifier("db2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } }

整体结构: 在这里插入图片描述

至此,需要修改或查询哪个数据库,只需要在对应的com///mapper/db包中创建对应的mapper类或者编写特定的sql语句即可。

使用Mybatis-plus实现

多数据源 | MyBatis-Plus (baomidou.com)

Mybatis-plus官网很清楚的告诉了我们如何配置多数据源。

1、引入dynamic-datasource-spring-boot-starter。

com.baomidou dynamic-datasource-spring-boot-starter ${version}

2、配置数据源。

spring: datasource: dynamic: primary: mysql1 #设置默认的数据源或者数据源组,默认值即为mysql1 strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源 datasource: mysql1: url: jdbc:mysql://xx.xx.xx.xx:3306/dynamic username: root password: 123456 driver-class-name: com.mysql.jdbc.Driver # 3.2.0开始支持SPI可省略此配置 mysql2: url: jdbc:mysql://xx.xx.xx.xx:3307/dynamic username: root password: 123456 driver-class-name: com.mysql.jdbc.Driver mysql2: url: ENC(xxxxx) # 内置加密,使用请查看详细文档 username: ENC(xxxxx) password: ENC(xxxxx) driver-class-name: com.mysql.jdbc.Driver #......省略

3、使用 @DS 切换数据源。

@DS 可以注解在方法上或类上,同时存在就近原则 方法上注解 优先于 类上注解。

注解结果没有@DS默认数据源@DS(“dsName”)dsName可以为组名也可以为具体某个库的名称 @Service @DS("mysql1") public class UserServiceImpl implements UserService { @Autowired private JdbcTemplate jdbcTemplate; public List selectAll() { return jdbcTemplate.queryForList("select * from user"); } @Override @DS("mysql2") public List selectByCondition() { return jdbcTemplate.queryForList("select * from user where age >10"); } }

在这里会有个小问题,假如我编写了两个方法,方法A使用的是 @DS(“mysql1”) ,功能是查询mysql1中的数据;方法B调用的是@DS(“mysql2”),是将数据插入到mysql2数据库中,那么我想在方法B中调用方法A,实现mysql1中查询的数据插入到mysql2中,能够成功吗?

答案是:不可以。

要想实现这个功能,我们可以使用多数据源的一个类,简单来说是一个队列,将需要使用到的数据源push进行,不用时再poll掉。就不用使用@DS注解了。

比如:

@RequestMapping("/Bmetohd") public int Bmethod(){ DynamicDataSourceContextHolder.push("mysql1"); List users = Amethod(); DynamicDataSourceContextHolder.poll(); DynamicDataSourceContextHolder.push("mysql2"); int num = 0; for(User user: users){ int i = User2Mapper.insert(user); num += i; } DynamicDataSourceContextHolder.poll(); return num; }

重点:

DynamicDataSourceContextHolder.push("mysql1"); //业务代码 DynamicDataSourceContextHolder.poll();


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有