ऐसा करने का आदर्श तरीका है, अनुरोध से स्कीमा से संबंधित जानकारी को कैप्चर करें और इसे थ्रेडलोकल में सहेजें और जब भी कनेक्शन का अनुरोध किया जाए तो स्कीमा सेट करें। दुर्भाग्य से जब मैंने इस दृष्टिकोण की कोशिश की, तो मैंने पाया कि सेटशेमा विधि अभी तक ड्राइवरों में लागू नहीं हुई है। लेकिन मुझे इसे हल करने का एक और तरीका (हैक) मिला। जेडीबीआई स्टेटमेंट लोकेटर प्रदान करता है जिसका उपयोग हम इस समस्या को हल करने के लिए यहां कर सकते हैं।
मान लें कि हम क्वेरी पैरामीटर में स्कीमा नाम भेज रहे हैं, हम स्कीमा नाम प्राप्त करने के लिए जर्सी अनुरोध फ़िल्टर का उपयोग कर सकते हैं।
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()));
अब हमें दूसरा भाग लिखने की जरूरत है, जहां हमें इस स्कीमा जानकारी का उपयोग करना चाहिए। इस स्कीमा राइटर को शामिल करें,
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();
}
StatementRewriter के साथ Dao को एनोटेट करना न भूलें। बस इतना ही। आपको एकाधिक स्कीमा के बारे में चिंता करने की आवश्यकता नहीं है।