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

Alb*_*ger 1 java mysql multiple-schema jdbi dropwizard

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

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

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

有任何想法吗?

Man*_*dan 5

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

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

public class Schema {
    public static ThreadLocal<String> 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

environment.jersey().property(ResourceConfig.PROPERTY_CONTAINER_REQUEST_FILTERS, asList(new SchemaNameFilter()));
Run Code Online (Sandbox Code Playgroud)

现在我们需要编写第二部分,我们应该使用这个架构信息.包括此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;
    }
}
Run Code Online (Sandbox Code Playgroud)

让我们说我们想要访问所有模式中的表"users",写这样的查询.

@OverrideStatementLocatorWith(SchemaReWriter.class)
public interface UserDao {

  @SqlQuery("select * from :schema.users")
  public List<User> getAllUsers();

}
Run Code Online (Sandbox Code Playgroud)

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