三、tienchin健身系统下的技术点复现--动态数据源

发布时间 2023-06-04 23:07:39作者: 山沉

三、网页手动实现动态数据源切换

手动切换 数据源,采用HttpSession 保存数据源名称,在全局的切面定义service下所有方法,都会切换数据源。

1、定义一个html页面

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>切换数据源</title>
  <script src="jquery-3.6.0.js"></script>
</head>
<body>
<div>
  请选择数据源:
  <select name="" id="" onchange="dsChange(this.options[this.options.selectedIndex].value)">
    <option value="请选择">请选择</option>
    <option value="master">master</option>
    <option value="slave">slave</option>
  </select>
</div>
<div id="result"></div>
<button onclick="loadData()">加载数据</button>
<script>
  function dsChange(value) {
    $.post("/dataType",{dataType:value});
  }
  function loadData() {
    $.get("/users",function (data) {
      $("#result").html(JSON.stringify(data));
    })
  }
</script>
</body>
</html>

2、定义一个全局切换数据源切面

@Aspect
@Component
@Order(11)
public class GlobalDynamicDataSourceAspect {
    private static final Logger LOGGER = LoggerFactory.getLogger(GlobalDynamicDataSourceAspect.class);
    @Autowired
    private HttpSession httpSession;

    @Pointcut("execution(* com.example.datasource_tienchin.service.*.*(..))")
    public void pc(){}

    @Around("pc()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        // 设置数据源
        DynamicDataSourceContextHolder.setDatasourceType(
                ((String) httpSession.getAttribute(DataSourceType.SESSION_KEY_TYPE)));
        try {
            return pjp.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            throw throwable;
        }
    }

}

由于DynamicAspec 的@Order(10) ,所以它先执行,最后生效的是全局切面。

3、请求接口

@RestController
public class DynamicDataSourceController {
    private static final Logger LOGGER = LoggerFactory.getLogger(DynamicDataSourceController.class);
    @Autowired
    LoginUserService loginUserService;

    @PostMapping("/dataType")
    public void changeDataSource(String dataType, HttpSession session) {

        // session 中存储数据源名称
        session.setAttribute(DataSourceType.SESSION_KEY_TYPE, dataType);
        LOGGER.info("前端切换数据源 {} 了", dataType);
    }

    @GetMapping("/users")
    public List<LoginUser> queryUsers(){
        return loginUserService.getAllLoginUsers();
    }
}

当然,HttpSession可以存,其他方式也可以。