多数据源
日常开发,多数据源场景,避免不了,AutoTable内部支持多数据源,提供了自定义数据源的切换接口,使用者根据不同数据源框架自行切换。
spring boot应用
假设在Entity上通过
@DS(value:String)
注解来标注不同的数据源,其中value是数据源的名称。 DynamicDataSourceContextHolder类是动态数据源框架的全局数据源控制类
java
// spring boot应用,直接使用@Component注入即可
@Component
public class MyDataSourceHandler implements IDataSourceHandler {
/**
* 根据实体类获取对应的数据源名称
* @param clazz 实体类
*/
@Override
public String getDataSourceName(Class<?> clazz) {
// 假定自定义的多数据源,有一个注解Ds,通过在类上标注Ds注解来指定类的数据源。*其他方式大同小异,此处仅举例说明。
Ds ds = clazz.getAnnotation(Ds.class);
if (ds != null) {
return ds.value();
} else {
return DynamicDataSourceContextHolder.getContextKey();
}
}
/**
* 根据数据源名称,切换数据源
* @param dataSourceName 来自getDataSourceName的返回值
*/
@Override
public void useDataSource(String dataSourceName) {
DynamicDataSourceContextHolder.setContextKey(dataSourceName);
}
/**
* 根据数据源名称,清除数据源
* @param dataSourceName 来自getDataSourceName的返回值
*/
@Override
public void clearDataSource(String dataSourceName) {
DynamicDataSourceContextHolder.removeContextKey();
}
}
普通java应用
普通java应用的实现方式相较于有所不同,但是主要取决于如何实现,因为AutoTable内部是通过
SqlSessionFactory
来确定数据源的,所以,普通java应用需要手动切换SqlSessionFactory
java
public class DynamicDataSourceHandler implements IDataSourceHandler {
private static final Map<String, String> CONFIG_MAP = new HashMap<String, String>() {{
put("mysql", "mybatis-config.xml");
put("pgsql", "mybatis-config-pgsql.xml");
put("sqlite", "mybatis-config-sqlite.xml");
}};
private static final Map<String, SqlSessionFactory> STRING_SQL_SESSION_FACTORY_MAP = new HashMap<>();
@Override
public void useDataSource(String dataSourceName) {
SqlSessionFactory sqlSessionFactory = STRING_SQL_SESSION_FACTORY_MAP.computeIfAbsent(dataSourceName, $ -> {
String resource = CONFIG_MAP.get(dataSourceName);
try (InputStream inputStream = TestApplication.class.getClassLoader().getResourceAsStream(resource)) {
// 使用SqlSessionFactoryBuilder加载配置文件
return new SqlSessionFactoryBuilder().build(inputStream);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
// 设置新的SqlSessionFactory
SqlSessionFactoryManager.setSqlSessionFactory(sqlSessionFactory);
}
@Override
public void clearDataSource(String dataSourceName) {
SqlSessionFactoryManager.cleanSqlSessionFactory();
}
@Override
public @NonNull String getDataSourceName(Class<?> clazz) {
Ds annotation = clazz.getAnnotation(Ds.class);
if (annotation != null) {
return annotation.value();
}
// 默认mysql
return "mysql";
}
}
提示
spring boot中不需要手动调用SqlSessionFactoryManager.setSqlSessionFactory
,是因为spring boot保持了SqlSessionFactory
的单实例,通过切换内部的DataSource实现切换数据源,AutoTable的spring-boot-starter包,在初始化的时候就把spring管理的SqlSessionFactory
通过SqlSessionFactoryManager.setSqlSessionFactory
配置到了框架中
第三方集成
如果你使用的是Mybatis-plus、Mybatis-flex等三方的开源框架,他们都有成熟的多数据源方案,AutoTable可以进行良好的集成,可参考第三方框架集成,内部均实现了相关框架的多数据方案