Идеалният начин да направите това е да заснемете свързаната със схемата информация от заявка и да я запишете в ThreadLocal и да зададете схемата, когато се изисква връзката. За съжаление, когато опитах този подход, открих, че методът setSchema все още не е внедрен в драйверите. Но намерих друг начин (хак) да разреша това. JDBI предоставя локатор на изявления, който можем да използваме тук, за да решим този проблем.
Да кажем, че изпращаме името на схемата в параметъра на заявката, можем да използваме филтър за заявки на Jersey, за да получим името на схемата.
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;
}
}
Това ще получи името на схемата при всяка заявка. Регистрирайте този файл за стартиране на приложението си.
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;
}
}
Да кажем, че искаме да получим достъп до таблицата „потребители“, която е във всички схеми, напишете заявка по този начин.
@OverrideStatementLocatorWith(SchemaReWriter.class)
public interface UserDao {
@SqlQuery("select * from :schema.users")
public List<User> getAllUsers();
}
Не забравяйте да коментирате Dao с StatementRewriter. Това е всичко. Не е нужно да се притеснявате за множество схеми.