Cách lý tưởng để làm điều này là nắm bắt thông tin liên quan đến lược đồ từ yêu cầu và lưu nó trong ThreadLocal và đặt lược đồ bất cứ khi nào kết nối được yêu cầu. Nhưng tôi đã tìm thấy một cách khác (hack) để giải quyết vấn đề này .JDBI cung cấp Bộ định vị câu lệnh mà chúng tôi có thể sử dụng ở đây để giải quyết vấn đề này.
Giả sử chúng tôi đang gửi tên giản đồ trong Tham số truy vấn, chúng tôi có thể sử dụng bộ lọc yêu cầu jersey để lấy tên giản đồ.
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;
}
}
Thao tác này sẽ nhận được tên lược đồ theo mọi yêu cầu. Đăng ký bộ lọc này trên bootstrap ứng dụng của bạn.
Thuộc tínhenvironment.jersey().property(ResourceConfig.PROPERTY_CONTAINER_REQUEST_FILTERS, asList(new SchemaNameFilter()));
Bây giờ chúng ta cần viết phần thứ hai, nơi chúng ta nên sử dụng thông tin lược đồ này. Bao gồm SchemaRewriter này,
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;
}
}
Giả sử chúng ta muốn truy cập bảng "người dùng" có trong tất cả các lược đồ, hãy viết truy vấn như thế này.
@OverrideStatementLocatorWith(SchemaReWriter.class)
public interface UserDao {
@SqlQuery("select * from :schema.users")
public List<User> getAllUsers();
}
Đừng quên chú thích Dao bằng StatementRewriter. Đó là tất cả. Bạn không cần phải lo lắng về nhiều lược đồ.