Bakit kailangan mo ng query cache

Isulat muli natin ang ating halimbawa sa pagkuha ng mga empleyado sa HQL:

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

assertTrue(director1 != director2);

Ang mga resulta ng naturang mga query ay hindi iniimbak ng alinman sa una o pangalawang antas ng cache.

Ito ay eksakto kung saan magagamit ang query cache . Ito rin ay hindi pinagana bilang default. Upang paganahin ito, idagdag ang sumusunod na linya sa configuration file:

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

Ngunit ito ay kalahati lamang ng solusyon. Pinagana namin ang cache ng query, ngunit kailangan din naming tukuyin kung aling mga resulta ng query ang gusto naming i-cache. Dapat itong isulat sa Query:

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

Ang cache ng query ay katulad ng cache ng pangalawang antas. Ngunit, hindi katulad nito, narito ang susi sa data ng cache ay hindi ang object identifier, ngunit ang hanay ng mga parameter ng query. At ang data mismo ay ang mga identifier ng mga bagay na tumutugma sa pamantayan ng query. Kaya, makatuwirang gamitin ang cache na ito sa pangalawang antas ng cache.

Pag-clear ng cache

Ang isa sa mga mahahalagang gawain kapag nagtatrabaho sa isang cache ay upang matiyak na ang mga naka-cache na bagay ay nagbabago at alisin ang mga ito mula sa cache (o i-update ang mga ito). Napakahusay na ginagawa ito ng hibernate. Minsan tila ginagabayan siya ng panuntunang "i-clear ang cache sa anumang hindi maintindihan na sitwasyon."

Sabihin nating gusto mong i-update ang data ng user sa pamamagitan ng HQL:

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

Hindi alam ng hibernate kung ano ang eksaktong nagbago sa database, ngunit alam nitong nagpapalit ka ng object ng Empleyado. Samakatuwid, pagkatapos isagawa ang query na ito, tatanggalin ng Hibernate ang lahat ng mga object ng uri ng Empleyado mula sa cache nito.

Ngunit ang NativeQuery ay gumagana nang mas kawili-wili:

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

Ang isang katutubong SQL query sa database ay naisakatuparan. Nangangahulugan ito na may nagbago sa database - tinawag ang kahilingan sa paraan ng executeUpdate() . Samakatuwid, sa kasong ito, gaganapin itong ligtas ng Hibernate at aalisin ang lahat ng bagay sa lahat ng uri mula sa cache nito .

Paano mo gusto iyan? Tumawag ka ng isang hindi nakakapinsalang kahilingan, at ang Hibernate bilang tugon ay binubura ang lahat ng data mula sa cache! Ito ay tiyak na mas mahusay kaysa sa kung siya ay nag-iingat ng mga bagay na naiiba sa base, ngunit iyon na!

Samakatuwid, mabilis na naisip ng mga tagalikha ng Hibernate kung paano tutulungan ang Hibernate sa kasong ito. Masasabi mo dito kung aling uri ng entity ang aalisin sa cache:

Query nativeQuery = session.createNativeQuery("update employee set name=’Alex’ where id = 4");
nativeQuery.unwrap(org.hibernate.SQLQuery.class).addSynchronizedEntityClass(Employee.class);
nativeQuery.executeUpdate();
Puna . Hindi pini-flush ng mga query ng native na pili ang cache , ipinapasok lang, i-update, tanggalin, procedure call, atbp.

Manu-manong pag-clear ng cache

Para sa ilang mga kadahilanan, maaaring gusto mong magtanggal ng isang bagay mula sa cache nang mag-isa. Ito ay maaaring gawin sa iba't ibang paraan.

Tandaan . Ang mga bagay sa cache ay nakaimbak sa mga pangkat na tinatawag na mga rehiyon . Bilang default, ang pangalan ng rehiyon ay kapareho ng pangalan ng klase. Samakatuwid, kung mayroon kang mga bagay na may uri na com.codegym.Employee , lahat ng mga ito ay maiimbak sa isang pangkat (rehiyon) na may pangalang " com.codegym.employee ".

Kung gusto mong ma-access ang cache at gumawa ng isang bagay dito, magagawa mo ito gamit ang SessionFactory object at ang getCache() method :

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

Kung gusto mong tanggalin ang data mula sa lahat ng pangkat (rehiyon), kailangan mong patakbuhin ang sumusunod na query:

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

Upang alisin ang isang bagay mula sa cache, kailangan mong ipasa ang pangalan nito (uri) at id. Magagawa mo ito sa dalawang paraan:

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

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

Maaari mo ring suriin kung ang isang partikular na bagay ay nasa cache:

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