Det perfekta sättet att göra detta är att fånga schemarelaterade information från begäran och spara den i ThreadLocal och ställa in schemat när anslutningen begärs. Tyvärr när jag försökte detta tillvägagångssätt fann jag att setSchema-metoden ännu inte är implementerad i drivrutiner. Men jag hittade ett annat sätt (hack) att lösa detta. JDBI tillhandahåller en statement Locator som vi kan använda här för att lösa det här problemet.
Låt oss säga att vi skickar schemanamn i frågeparameter, vi kan använda jersey request filter för att få schemanamn.
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;
}
}
Detta kommer att få schemanamnet på varje begäran. Registrera denna fil på din applikationsbootstrap.
environment.jersey().property(ResourceConfig.PROPERTY_CONTAINER_REQUEST_FILTERS, asList(new SchemaNameFilter()));
Nu måste vi skriva den andra delen, där vi ska använda denna schemainformation. Inkludera denna 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;
}
}
Låt oss säga att vi vill komma åt tabellen "användare" som finns i alla scheman, skriv en fråga så här.
@OverrideStatementLocatorWith(SchemaReWriter.class)
public interface UserDao {
@SqlQuery("select * from :schema.users")
public List<User> getAllUsers();
}
Glöm inte att kommentera Dao med StatementRewriter. Det är allt. Du behöver inte oroa dig för flera scheman.