使用Dropwizard和JDBI查询具有多个模式的数据库?

我正在使用DropWizard(使用JDBI)构建Java Rest API,我的要求是我需要使用相同的应用程序查询多个MySQL模式。 它基本上是一个包含多个模式的AWS MySQL实例 – 每个客户端一个模式。

我需要的是一种机制,它根据请求知道要查询哪个“模式” – IE:请求属于哪个客户端。

我知道如何创建DataSource,DAO等(使用本教程: https : //dropwizard.github.io/dropwizard/manual/jdbi.html ),但不知道如何查询多个模式。

有任何想法吗?

执行此操作的理想方法是从请求中捕获与架构相关的信息,并将其保存在ThreadLocal中,并在请求连接时设置架构。 不幸的是,当我尝试这种方法时,我发现setSchema方法尚未在驱动程序中实现。 但我找到了解决这个问题的另一种方法(黑客)。 JDBI提供了语句Locator,我们可以在这里解决这个问题。

假设我们在查询参数中发送模式名称,我们可以使用泽西请求filter来获取模式名称。

public class Schema { public static ThreadLocal name = new ThreadLocal<>(); } public class SchemaNameFilter implements ContainerRequestFilter { @Override public ContainerRequest filter(ContainerRequest request) { if(request.getQueryParameters().containsKey("schema")) { Schema.name.set(request.getQueryParameters().get("schema").get(0)); } return request; } } 

这将获得每个请求的模式名称。 在您的应用程序引导程序中注册此文件管理器。

 environment.jersey().property(ResourceConfig.PROPERTY_CONTAINER_REQUEST_FILTERS, asList(new SchemaNameFilter())); 

现在我们需要编写第二部分,我们应该使用这个架构信息。 包括此SchemaRewriter,

 public class SchemaReWriter implements StatementLocator { @Override public String locate(String sql, StatementContext ctx) throws Exception { if (nonNull(Schema.name.get())) { sql = sql.replaceAll(":schema", Schema.name.get()); } return sql; } } 

让我们说我们想访问所有模式中的表“users”,写这样的查询。

 @OverrideStatementLocatorWith(SchemaReWriter.class) public interface UserDao { @SqlQuery("select * from :schema.users") public List getAllUsers(); } 

不要忘记用StatementRewriter注释Dao。 就这样。 您不必担心多个模式。

最简单的解决方案是使用多个:

  @JsonProperty("database") public DataSourceFactory getDataSourceFactory() { return database; } 

配置,例如:

 @JsonProperty("products") @JsonProperty("clients") 

然后配置文件:

 products: # products schema configuration... clients: # clients configuration