三、tienchin健身系统下的技术点复现--动态数据源
三、网页手动实现动态数据源切换
手动切换 数据源,采用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可以存,其他方式也可以。
弯弯月亮,只为美好的自己。