Idealnym sposobem na to jest przechwycenie informacji związanych ze schematem z żądania i zapisanie ich w ThreadLocal i ustawienie schematu za każdym razem, gdy wymagane jest połączenie. Niestety, gdy próbowałem tego podejścia, odkryłem, że metoda setSchema nie jest jeszcze zaimplementowana w sterownikach. Ale znalazłem inny sposób (hack), aby rozwiązać ten problem. JDBI zapewnia lokalizator instrukcji, którego możemy użyć tutaj, aby rozwiązać ten problem.
Powiedzmy, że wysyłamy nazwę schematu w parametrze zapytania, możemy użyć filtra żądań jersey, aby uzyskać nazwę schematu.
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;
}
}
Spowoduje to otrzymanie nazwy schematu przy każdym żądaniu. Zarejestruj ten plik w programie startowym aplikacji.
environment.jersey().property(ResourceConfig.PROPERTY_CONTAINER_REQUEST_FILTERS, asList(new SchemaNameFilter()));
Teraz musimy napisać drugą część, w której powinniśmy użyć tych informacji o schemacie. Dołącz ten 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;
}
}
Powiedzmy, że chcemy uzyskać dostęp do tabeli „users”, która znajduje się we wszystkich schematach, napisz zapytanie w ten sposób.
@OverrideStatementLocatorWith(SchemaReWriter.class)
public interface UserDao {
@SqlQuery("select * from :schema.users")
public List<User> getAllUsers();
}
Nie zapomnij dodać adnotacji do Dao za pomocą StatementRewriter. To wszystko. Nie musisz się martwić o wiele schematów.