आपको क्वेरी कैश की आवश्यकता क्यों है

आइए एचक्यूएल में कर्मचारी प्राप्त करने के साथ अपना उदाहरण दोबारा लिखें:

Employee director1 = session.createQuery("from Employee where id = 4").uniqueResult();
Employee director2 = session.createQuery("from Employee where id = 4").uniqueResult();

assertTrue(director1 != director2);

ऐसे प्रश्नों के परिणाम पहले या दूसरे स्तर के कैश द्वारा संग्रहीत नहीं होते हैं ।

यहीं पर क्वेरी कैश का उपयोग किया जा सकता है । यह डिफ़ॉल्ट रूप से अक्षम भी है। इसे सक्षम करने के लिए, कॉन्फ़िगरेशन फ़ाइल में निम्न पंक्ति जोड़ें:

<property name="hibernate.cache.use_query_cache" value="true"/>

लेकिन यह केवल आधा समाधान है। हमने क्वेरी कैश को सक्षम कर दिया है, लेकिन हमें यह भी निर्दिष्ट करना होगा कि हम किस क्वेरी परिणाम को कैश करना चाहते हैं। यह प्रश्न में लिखा जाना चाहिए:

Query query = session.createQuery("from Employee where id = 4");
query.setCacheable(true);
Employee director1 = query.uniqueResult();

क्वेरी कैश दूसरे स्तर के कैश के समान है। लेकिन, इसके विपरीत, यहाँ कैश डेटा की कुंजी ऑब्जेक्ट आइडेंटिफ़ायर नहीं है, बल्कि क्वेरी पैरामीटर का सेट है। और डेटा ही उन वस्तुओं का पहचानकर्ता है जो क्वेरी मानदंड से मेल खाते हैं। इस प्रकार, इस कैश को दूसरे स्तर के कैश के साथ उपयोग करना तर्कसंगत है।

कैश साफ़ करना

कैश के साथ काम करते समय महत्वपूर्ण कार्यों में से एक यह सुनिश्चित करना है कि कैश की गई वस्तुएं बदल जाती हैं और उन्हें कैश से हटा दें (या उन्हें अपडेट करें)। हाइबरनेट यह बहुत अच्छा करता है। कभी-कभी ऐसा भी लगता है कि वह "किसी भी समझ से बाहर की स्थिति में कैश को साफ़ करने" के नियम द्वारा निर्देशित होता है।

मान लीजिए कि आप एचक्यूएल के माध्यम से उपयोगकर्ता डेटा अपडेट करना चाहते हैं:

Query query = session.createQuery("update Employee set name=’Alex’ where id = 4")
query. executeUpdate();

हाइबरनेट को पता नहीं चल सकता है कि डेटाबेस में क्या बदल गया है, लेकिन यह जानता है कि आप एक कर्मचारी वस्तु बदल रहे हैं। इसलिए, इस क्वेरी को निष्पादित करने के बाद, हाइबरनेट अपने कैश से कर्मचारी प्रकार की सभी वस्तुओं को हटा देगा ।

लेकिन NativeQuery और भी दिलचस्प काम करता है:

Query nativeQuery = session.createNativeQuery("update employee set name=’Alex’ where id = 4")
nativeQuery.executeUpdate();

डेटाबेस के लिए मूल SQL क्वेरी निष्पादित की गई है। इसका मतलब है कि डेटाबेस में कुछ बदल गया है - अनुरोध को एक्सीक्यूटअपडेट () विधि में कहा गया था । इसलिए, इस मामले में, हाइबरनेट इसे सुरक्षित रखेगा और सभी प्रकार की सभी वस्तुओं को अपने कैश से हटा देगा ।

आपको वह कैसा लगा? आप एक हानिरहित अनुरोध कहते हैं, और प्रतिक्रिया में हाइबरनेट कैश से सभी डेटा मिटा देता है! यह निश्चित रूप से बेहतर है अगर वह उन वस्तुओं को रखता है जो आधार से भिन्न होती हैं, लेकिन यह बात है!

इसलिए, हाइबरनेट के रचनाकारों ने जल्दी से पता लगाया कि इस मामले में हाइबरनेट की मदद कैसे की जाए। आप उसे बता सकते हैं कि कैश से किस निकाय प्रकार को निकालना है:

Query nativeQuery = session.createNativeQuery("update employee set name=’Alex’ where id = 4");
nativeQuery.unwrap(org.hibernate.SQLQuery.class).addSynchronizedEntityClass(Employee.class);
nativeQuery.executeUpdate();
टिप्पणी । नेटिव सेलेक्ट क्वेश्चन कैश फ्लश नहीं करते हैं , केवल इंसर्ट, अपडेट, डिलीट, प्रोसेस कॉल आदि करते हैं।

मैनुअल कैश समाशोधन

कुछ कारणों से, हो सकता है कि आप स्वयं कैश से किसी वस्तु को हटाना चाहें। यह अलग-अलग तरीकों से किया जा सकता है।

ध्यान दें । कैश में वस्तुओं को क्षेत्रों नामक समूहों में संग्रहीत किया जाता है । डिफ़ॉल्ट रूप से, क्षेत्र का नाम वर्ग के नाम के समान होता है। इसलिए, यदि आपके पास com.codegym.कर्मचारी प्रकार की वस्तुएं हैं, तो उन सभी को एक समूह (क्षेत्र) में " com.codegym.employee " नाम से संग्रहीत किया जाएगा।

यदि आप कैश को एक्सेस करना चाहते हैं और इसके साथ कुछ करना चाहते हैं, तो आप इसे SessionFactory ऑब्जेक्ट और getCache () विधि से कर सकते हैं :

session.getSessionFactory().getCache().evictQueryRegion("com.codegym.employee”);

यदि आप सभी समूहों (क्षेत्रों) से डेटा हटाना चाहते हैं, तो आपको निम्न क्वेरी चलाने की आवश्यकता है:

session.getSessionFactory().getCache().evictAllRegions();

कैश से एक ऑब्जेक्ट को निकालने के लिए, आपको उसका नाम (प्रकार) और आईडी पास करना होगा। आप इसे दो तरीकों से कर सकते हैं:

session.getSessionFactory().getCache().evictEntityData("Employee, 4);

session.getSessionFactory().getCache().evictEntityData(com.codegym.Employee.class, 4);

आप यह भी देख सकते हैं कि कोई विशेष वस्तु कैश में है या नहीं:

session.getSessionFactory().getCache().containsEntity("Employee, 4);
session.getSessionFactory().getCache().containsEntity(com.codegym.Employee.class, 4);