Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Verwenden Sie Dropwizard &JDBI, um eine Datenbank mit mehreren Schemas abzufragen?

Der ideale Weg, dies zu tun, besteht darin, die schemabezogenen Informationen aus der Anfrage zu erfassen und in ThreadLocal zu speichern und das Schema festzulegen, wenn die Verbindung angefordert wird. Als ich diesen Ansatz ausprobierte, stellte ich leider fest, dass die setSchema-Methode noch nicht in den Treibern implementiert ist. Aber ich habe einen anderen Weg (Hack) gefunden, um dies zu lösen. JDBI bietet einen Statement Locator, den wir hier verwenden können, um dieses Problem zu lösen.

Angenommen, wir senden den Schemanamen im Abfrageparameter. Wir können den Jersey-Anforderungsfilter verwenden, um den Schemanamen zu erhalten.

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;
    }
}

Dadurch wird der Schemaname bei jeder Anfrage abgerufen. Registrieren Sie diesen Filer im Bootstrap Ihrer Anwendung.

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

Jetzt müssen wir den zweiten Teil schreiben, wo wir diese Schemainformationen verwenden sollen. Fügen Sie diesen SchemaRewriter hinzu,

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;
    }
}

Nehmen wir an, wir möchten auf die Tabelle "Benutzer" zugreifen, die in allen Schemas enthalten ist. Schreiben Sie eine Abfrage wie diese.

@OverrideStatementLocatorWith(SchemaReWriter.class)
public interface UserDao {

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

}

Vergessen Sie nicht, Dao mit StatementRewriter zu kommentieren. Das ist alles. Sie müssen sich keine Gedanken über mehrere Schemata machen.