基于mybatis+spring的读写分离

本文介绍了一个针对MyBatis的自定义封装——RWSqlSessionTemplate,该类实现了根据不同的操作类型(如查询或更新)动态切换数据源(主从),但此方案不支持事务管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在SqlSessionTemplate上层进行了封装,根据调用的方法,切换master/slave,但是无法支持事务

package com.xjy.study.spring.mybatis;

import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

import javax.sql.DataSource;

import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.mybatis.spring.SqlSessionTemplate;

// 不支持事务
public class RWSqlSessionTemplate {
    private SqlSessionTemplate sqlSessionTemplate;
    private DataSource masterDataSource;
    private List<DataSource> slaveDataSources;
    private volatile boolean isMaster = true;

    public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
        this.sqlSessionTemplate = sqlSessionTemplate;
    }

    public void setMasterDataSource(DataSource masterDataSource) {
        this.masterDataSource = masterDataSource;
    }

    public void setSlaveDataSources(List<DataSource> slaveDataSources) {
        this.slaveDataSources = slaveDataSources;
    }

    public <T> T selectOne(String statement, Object parameter) {
        switchToSlave();
        return sqlSessionTemplate.selectOne(statement, parameter);
    }

    public int update(String statement, Object parameter) {
        switchToMaster();
        return this.sqlSessionTemplate.update(statement, parameter);
      }

    private void switchToSlave() {
        if(isMaster) {
            switchToSlaveDataSource();
            isMaster = false;
        }
    }

    private void switchToMaster() {
        if(!isMaster) {
            switchToMasterDataSource();
            isMaster = true;
        }
    }

    private void switchToSlaveDataSource() {
        Configuration configuration = this.sqlSessionTemplate.getSqlSessionFactory().getConfiguration();
        Environment oldEnvironment = this.sqlSessionTemplate.getSqlSessionFactory().getConfiguration().getEnvironment();
        int index = ThreadLocalRandom.current().nextInt(slaveDataSources.size());
        Environment newEnvironment = new Environment(oldEnvironment.getId(), oldEnvironment.getTransactionFactory(), slaveDataSources.get(index));
        configuration.setEnvironment(newEnvironment);
    }

    private void switchToMasterDataSource() {
        Configuration configuration = this.sqlSessionTemplate.getSqlSessionFactory().getConfiguration();
        Environment oldEnvironment = this.sqlSessionTemplate.getSqlSessionFactory().getConfiguration().getEnvironment();
        Environment newEnvironment = new Environment(oldEnvironment.getId(), oldEnvironment.getTransactionFactory(), this.masterDataSource);
        configuration.setEnvironment(newEnvironment);
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值