使用API调用发送的参数配置bean



我有一个配置类来配置sqlite数据库连接。在这里,我确实手动配置它。

@Configuration
@EnableJpaRepositories(basePackages = "fr.company.dashboard.io.repository")
public class DBConfiguration {
private final ApplicationProperties applicationProperties;
@Autowired
public DBConfiguration(ApplicationProperties applicationProperties) {
this.applicationProperties = applicationProperties;
}
@Bean
public DataSource dataSource() {
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(applicationProperties.getProperty("hibernate.connection.driverClassName"));
dataSource.setUrl(applicationProperties.getProperty("url"));
dataSource.setUsername(applicationProperties.getProperty("user"));
dataSource.setPassword(applicationProperties.getProperty("password"));
return dataSource;
}
}

我想通过使用API get方法来设置数据库,该方法包括URL 中的数据库名称

首先需要将bean的作用域更改为"请求";,然后传递你想要的参数如下:

@Scope("request")
@bean
public DataSource dataSource(String dbName){
......
......
return dataSource;
}

在你的控制器上,你应该做这样的事情,

@Controller
public class YourController{
@Autowired
private BeanFactory beanFactory;
@RequestMapping("/")
public String exFunc(){
String dbName = "....."
DataSource dataSource = 
beanFactory.getBean(DataSource.class, dbName);
}
}

在我的例子中,我在同一个文件夹中有多个sqlite数据库。我更改了控制器,以便从入口点检索数据库名称:

@RestController
@RequestMapping("/dbfiles")
public class AppController {
private final AppService appService;
private final DataSourceContextHolder dataSourceContextHolder;
@Autowired
public DatabaseListController(AppService AppService,
DataSourceContextHolder dataSourceContextHolder) {
this.appService= appService;
this.dataSourceContextHolder = dataSourceContextHolder;
}

@GetMapping("/{dbName}")
public List<AppResponse> getAll(@PathVariable("dbName") String dbName) throws IOException {
Set<String> databases = Utils.getDatabaseList();
if(databases.contains(dbName) || databases.contains(dbName + ".db")) {
dataSourceContextHolder.setBranchContext(dbName);
}
List<AppResponse> returnValue = new ArrayList<>();
ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
List<AppResponse> appResponses = appService.getAll();
returnValue = modelMapper.map(
appResponses ,
new TypeToken<List<AppDto>>() {}.getType()
);
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String json = gson.toJson(returnValue);
System.out.println(json);
return returnValue;
}
}

我使用了一个组件类来传递数据库名称:

@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
public class DataSourceContextHolder {
private static ThreadLocal<String> threadLocal;
public DataSourceContextHolder() {
threadLocal = new ThreadLocal<>();
}
public void setBranchContext(String dbName) {
threadLocal.set(dbName);
}
public String getBranchContext() {
return threadLocal.get();
}
public static void clearBranchContext() {
threadLocal.remove();
}
}

我还创建了一个DataSourceRouting类,用于在启动时处理数据库:

@Component
public class DataSourceRouting extends AbstractRoutingDataSource {
private DataSourceContextHolder dataSourceContextHolder;
private DataSourceConfig dataSourceConfig;
public DataSourceRouting(DataSourceContextHolder dataSourceContextHolder,
DataSourceConfig dataSourceConfig) throws IOException {
this.dataSourceContextHolder = dataSourceContextHolder;
this.dataSourceConfig = dataSourceConfig;
Map<Object, Object> dataSourceMap = new HashMap<>();
Set<String> databases = Utils.getDatabaseList();
databases.forEach(database -> {
DataSource dataSource = dataSourceBuilder(database);
dataSourceMap.put(database, dataSource);
this.setDefaultTargetDataSource(dataSource);
});
this.setTargetDataSources(dataSourceMap);
}
private DataSource dataSourceBuilder(String database) {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(dataSourceConfig.getDriverClassName());
dataSource.setUrl(dataSourceConfig.getUrl() + database);
dataSource.setUsername(dataSourceConfig.getUsername());
dataSource.setPassword(dataSourceConfig.getPassword());
return dataSource;
}
@Override
protected Object determineCurrentLookupKey() {
//System.out.println(dataSourceContextHolder.getBranchContext().toString());
return dataSourceContextHolder.getBranchContext();
}
}

我创建了一个在application.properties:中读取的POJO

@Component
@ConfigurationProperties(prefix="datasource")
@Getter @Setter
public class DataSourceConfig {
private String url;
private String password;
private String username;
private String driverClassName;
}

此代码允许传递数据库名称并对正确的数据库名称进行查询。由于数据库具有相同的结构,因此我会按预期输出正确的值。

最新更新