基于MyBatis解锁多数据源

多数据源~其实就是实现在一个项目里面操作多个数据源,从而共同实现某项任务或者某个功能模块!

案例:我们将再创建一个数据库sb_technology作为从数据源,并在项目的请求方法中发起对主数据源、客数据源相关数据表的访问!

实现:将基于注解+Java Config显示注入的方式实现!

新建数据库sb_technology和数据表

create database sb_technology;
use sb_technology;
create table sys_config(
	id int(11) not null auto_increment,
    type varchar(100) character set utf8mb4 not null comment "字典类型",
    name varchar(100) character set utf8mb4 not null comment "字典名称",
    code varchar(100) character set utf8mb4 not null comment "选项编码",
    value varchar(100) character set utf8mb4 not null comment "选项取值",
    order_by int(11) default 1 comment "排序",
    is_active tinyint(4) default 1 comment "是否有效(1=是;0=否)",
    create_time datetime default current_timestamp comment "创建时间",
    primary key(id),
    unique key idx_type_Code (type, code) using btree
)engine=InnoDB auto_increment=5 default charset=utf8 comment="字典配置表";

配置数据源

datasource.one.url=jdbc:mysql://localhost:3306/sb_middleaware?characterEncoding=utf-8&useSSL=false&serverTimezone=Hongkong
datasource.one.username=root
datasource.one.password=
datasource.one.type=com.zaxxer.hikari.HikariDataSource
datasource.one.driver-class-name=com.mysql.cj.jdbc.Driver


datasource.two.url=jdbc:mysql://localhost:3306/sb_technology?characterEncoding=utf-8&useSSL=false&serverTimezone=Hongkong
datasource.two.username=root
datasource.two.password=
datasource.two.type=com.zaxxer.hikari.HikariDataSource
datasource.two.driver-class-name=com.mysql.cj.jdbc.Driver

利用注解的方式:需要先将下面的给注释掉

@ImportResource(value = {"classpath:spring/spring-jdbc.xml"})
@MapperScan(basePackages = "com.cuihua.boot.middleware.model.mapper")

创建两个配置类 Primary和Second

@Configuration
@MapperScan(basePackages = "com.cuihua.boot.middleware.model.mapper.primary", sqlSessionTemplateRef = "primarySqlSessionTemplate")
public class DataSourcePrimary {

    @Autowired
    private Environment env;

    @Primary
    @Bean(name = "primaryDataSource")
    public DataSource dataSource(){
        return DataSourceBuilder.create()
                .driverClassName(env.getProperty("datasource.one.driver-class-name"))
                .url(env.getProperty("datasource.one.url"))
                .username(env.getProperty("datasource.one.username"))
                .password(env.getProperty("datasource.one.password"))
                .build();
    }

    @Primary
    @Bean(name="primarySqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("primaryDataSource") DataSource dataSource) throws Exception{
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:/mappers/primary/*.xml"));

        //TODO:加载mybats全局的配置文件
        bean.setConfigLocation(new DefaultResourceLoader().getResource("classpath:mybatis-config.xml"));
        return bean.getObject();
    }

    @Primary
    @Bean(name = "primaryTransactionManager")
    public DataSourceTransactionManager transactionManager(@Qualifier("primaryDataSource") DataSource dataSource) throws Exception{
        return new DataSourceTransactionManager(dataSource);
    }

    @Primary
    @Bean(name = "primarySqlSessionTemplate")
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("primarySqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception{
        return new SqlSessionTemplate(sqlSessionFactory);
    }

    @Bean("primaryJdbcTemplate")
    public JdbcTemplate primaryJdbcTemplate(@Qualifier("primaryDataSource") DataSource dataSource){
        return new JdbcTemplate(dataSource);
    }
}
@Configuration
@MapperScan(basePackages = "com.cuihua.boot.middleware.model.mapper.second", sqlSessionTemplateRef = "secondSqlSessionTemplate")
public class DataSourceSecond {

    @Autowired
    private Environment env;


    @Bean(name = "secondDataSource")
    public DataSource dataSource(){
        return DataSourceBuilder.create()
                .driverClassName(env.getProperty("datasource.two.driver-class-name"))
                .url(env.getProperty("datasource.two.url"))
                .username(env.getProperty("datasource.two.username"))
                .password(env.getProperty("datasource.two.password"))
                .build();
    }


    @Bean(name="secondSqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("secondDataSource") DataSource dataSource) throws Exception{
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:/mappers/second/*.xml"));
        bean.setConfigLocation(new DefaultResourceLoader().getResource("classpath:mybatis-config.xml"));
        return bean.getObject();
    }


    @Bean(name = "secondTransactionManager")
    public DataSourceTransactionManager transactionManager(@Qualifier("secondDataSource") DataSource dataSource) throws Exception{
        return new DataSourceTransactionManager(dataSource);
    }


    @Bean(name = "secondSqlSessionTemplate")
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("secondSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception{
        return new SqlSessionTemplate(sqlSessionFactory);
    }

    @Bean("secondJdbcTemplate")
    public JdbcTemplate secondJdbcTemplate(@Qualifier("secondDataSource") DataSource dataSource){
        return new JdbcTemplate(dataSource);
    }
}

注意目录结构的调整 

从数据库SysConfig.java

@Data
public class SysConfig implements Serializable {
    private String variable;

    private String value;

    private Date setTime;

    private String setBy;

}

mapper.xml 

  <select id="selectActiveConfigs" resultType="com.cuihua.boot.middleware.model.entity.second.SysConfig">
    SELECT <include refid="Base_Column_List"/>
    FROM sys_config
    WHERE is_active = 1
    ORDER BY type, order_by ASC
  </select>

Controller

@RestController
@RequestMapping("multipart/source")
public class MultipartSourceController extends AbstractController{

    //TODO:从数据源
    @Autowired
    private SysConfigMapper sysConfigMapper;

    //TODO:主数据源
    @Autowired
    private UserMapper userMapper;

    //同时访问主数据源、从数据源的数据库表的信息
    @RequestMapping(value = "list",method = RequestMethod.GET)
    public BaseResponse list(){
        BaseResponse response = new BaseResponse(StatusCode.Success);
        Map<String, Object> resMap = Maps.newHashMap();

        try{
            resMap.put("主数据源的data", userMapper.selectByPrimaryKey(343587));
            List<SysConfig> res = sysConfigMapper.selectActiveConfigs();
            for(SysConfig sysConfig : res){
                System.out.println(sysConfig.getValue());
            }
            resMap.put("从数据源的data", sysConfigMapper.selectActiveConfigs());
        }catch (Exception e){
            response = new BaseResponse(StatusCode.Fail.getCode(), e.getMessage());
        }
        response.setData(resMap);
        return response;
    }

    @RequestMapping(value = "add", method = RequestMethod.POST)
    @Transactional(rollbackFor =  Exception.class)
    public BaseResponse add() throws Exception{
        BaseResponse response = new BaseResponse(StatusCode.Success);

        //TODO:新增用户数据-主数据源
        User user = new User();
        user.setName("cuihua2");
        user.setCode("10010");
        userMapper.insertSelective(user);

        //TODO:新增数据字典-从数据源
        SysConfig config = new SysConfig();
        config.setValue("颜色");
        sysConfigMapper.insertSelective(config);

        int i = 1 / 0;
        return  response;
    }

}

最终发现,几乎不用动原来的业务操作逻辑,而知识添加关乎数据源相关的自定义注解+包目录的扫描

猜你喜欢

转载自blog.csdn.net/weixin_37841366/article/details/109031941