웹사이트 검색

Hibernate 캐싱 - 첫 번째 수준 캐시


Hibernate Caching - First Level Cache 예제 자습서에 오신 것을 환영합니다. 최근에 우리는 객체 지향 방식으로 SQL 쿼리를 실행하기 위한 HQL을 조사했습니다. 오늘 우리는 Hibernate의 중요한 측면 중 하나인 Hibernate Cache를 살펴볼 것입니다.

최대 절전 모드 캐싱

  1. 첫 번째 수준 캐시: Hibernate 첫 번째 수준 캐시는 세션 개체와 연결됩니다. Hibernate 첫 번째 수준 캐시는 기본적으로 활성화되어 있으며 비활성화할 방법이 없습니다. 그러나 최대 절전 모드는 캐시에서 선택한 객체를 삭제하거나 캐시를 완전히 지울 수 있는 방법을 제공합니다. 세션에 캐시된 개체는 다른 세션에서 볼 수 없으며 세션이 닫히면 캐시된 개체도 모두 손실됩니다.
  2. 2차 캐시: Hibernate 2차 캐시는 기본적으로 비활성화되어 있지만 구성을 통해 활성화할 수 있습니다. 현재 EHCache와 Infinispan은 Hibernate Second level cache에 대한 구현을 제공하고 있으며 우리는 이를 사용할 수 있습니다. 최대 절전 모드 캐싱에 대한 다음 자습서에서 이에 대해 살펴보겠습니다.
  3. 쿼리 캐시: Hibernate는 또한 쿼리 결과 집합을 캐시할 수 있습니다. Hibernate Query Cache는 캐시의 실제 엔터티 상태를 캐시하지 않습니다. 식별자 값과 값 유형의 결과만 캐시합니다. 따라서 항상 두 번째 수준 캐시와 함께 사용해야 합니다.

Hibernate 캐싱 - 첫 번째 수준 캐시 예제

내 하이버네이트 첫 번째 레벨 캐시 예제 프로그램의 경우 HQL 예제와 동일한 구성을 사용하고 있습니다. 이를 확인하고 테이블을 구성하고 더미 데이터로 채울 수 있습니다. 먼저 프로그램과 출력을 살펴보고 Hibernate First Level Cache와 관련된 몇 가지 중요한 사항을 살펴보겠습니다. HibernateCacheExample.java

package com.journaldev.hibernate.main;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;

import com.journaldev.hibernate.model.Employee;
import com.journaldev.hibernate.util.HibernateUtil;

public class HibernateCacheExample {

	public static void main(String[] args) throws InterruptedException {
		
		SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
		Session session = sessionFactory.getCurrentSession();
		Transaction tx = session.beginTransaction();
		
		//Get employee with id=1
		Employee emp = (Employee) session.load(Employee.class, new Long(1));
		printData(emp,1);
		
		//waiting for sometime to change the data in backend
		Thread.sleep(10000);
		
		//Fetch same data again, check logs that no query fired
		Employee emp1 = (Employee) session.load(Employee.class, new Long(1));
		printData(emp1,2);
		
		//Create new session
		Session newSession = sessionFactory.openSession();
		//Get employee with id=1, notice the logs for query
		Employee emp2 = (Employee) newSession.load(Employee.class, new Long(1));
		printData(emp2,3);
		
		//START: evict example to remove specific object from hibernate first level cache
		//Get employee with id=2, first time hence query in logs
		Employee emp3 = (Employee) session.load(Employee.class, new Long(2));
		printData(emp3,4);
		
		//evict the employee object with id=1
		session.evict(emp);
		System.out.println("Session Contains Employee with id=1?"+session.contains(emp));

		//since object is removed from first level cache, you will see query in logs
		Employee emp4 = (Employee) session.load(Employee.class, new Long(1));
		printData(emp4,5);
		
		//this object is still present, so you won't see query in logs
		Employee emp5 = (Employee) session.load(Employee.class, new Long(2));
		printData(emp5,6);
		//END: evict example
		
		//START: clear example to remove everything from first level cache
		session.clear();
		Employee emp6 = (Employee) session.load(Employee.class, new Long(1));
		printData(emp6,7);
		Employee emp7 = (Employee) session.load(Employee.class, new Long(2));
		printData(emp7,8);
		
		System.out.println("Session Contains Employee with id=2?"+session.contains(emp7));
		
		tx.commit();
		sessionFactory.close();
	}

	private static void printData(Employee emp, int count) {
		System.out.println(count+":: Name="+emp.getName()+", Zipcode="+emp.getAddress().getZipcode());
	}

}

위의 예제를 실행하면 출력에 많은 최대 절전 모드 관련 정보가 포함됩니다. 그러나 우리는 대부분 코드별 출력과 데이터를 로드하기 위해 최대 절전 모드에서 실행되는 쿼리에 관심이 있습니다. 출력 스니펫은 아래와 같습니다.

Hibernate Configuration loaded
Hibernate serviceRegistry created
Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_, employee0_.emp_salary as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as address_2_0_1_, address1_.city as city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE employee0_ left outer join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id where employee0_.emp_id=?
1:: Name=Pankaj, Zipcode=95129
2:: Name=Pankaj, Zipcode=95129
Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_, employee0_.emp_salary as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as address_2_0_1_, address1_.city as city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE employee0_ left outer join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id where employee0_.emp_id=?
3:: Name=PankajK, Zipcode=95129
Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_, employee0_.emp_salary as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as address_2_0_1_, address1_.city as city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE employee0_ left outer join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id where employee0_.emp_id=?
4:: Name=David, Zipcode=95051
Session Contains Employee with id=1?false
Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_, employee0_.emp_salary as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as address_2_0_1_, address1_.city as city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE employee0_ left outer join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id where employee0_.emp_id=?
5:: Name=Pankaj, Zipcode=95129
6:: Name=David, Zipcode=95051
Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_, employee0_.emp_salary as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as address_2_0_1_, address1_.city as city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE employee0_ left outer join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id where employee0_.emp_id=?
7:: Name=Pankaj, Zipcode=95129
Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_, employee0_.emp_salary as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as address_2_0_1_, address1_.city as city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE employee0_ left outer join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id where employee0_.emp_id=?
8:: Name=David, Zipcode=95051
Session Contains Employee with id=2?true

Hibernate 중요 포인트의 첫 번째 수준 캐시

위의 프로그램에서 파생될 수 있는 Hibernate의 첫 번째 수준 캐시에 대한 중요한 사항은 다음과 같습니다.

  1. Hibernate First Level 캐시는 기본적으로 활성화되어 있으며 이에 대한 구성이 필요하지 않습니다.
  2. Hibernate 첫 번째 수준 캐시는 세션에 따라 다르므로 동일한 세션에서 동일한 데이터를 가져올 때 쿼리가 실행되지 않는 반면 다른 세션에서는 데이터를 로드하기 위해 쿼리가 실행됩니다.
  3. Hibernate 첫 번째 수준 캐시는 이전 값을 가질 수 있습니다. 위에서 볼 수 있듯이 프로그램을 10초 동안 절전 모드로 전환했고 그 시간 동안 데이터베이스에서 값(Pankaj에서 PankajK로 이름)을 업데이트했지만 업데이트되지 않았습니다. 동일한 세션에 반영됩니다. 그러나 다른 세션에서는 업데이트된 값을 얻었습니다.
  4. 세션 evict() 메서드를 사용하여 최대 절전 모드 첫 번째 수준 캐시에서 단일 개체를 제거할 수 있습니다.
  5. 세션 clear() 메서드를 사용하여 캐시를 지울 수 있습니다. 즉, 캐시에서 모든 객체를 삭제할 수 있습니다.
  6. 세션 contains() 메서드를 사용하여 개체가 최대 절전 모드 캐시에 있는지 여부를 확인할 수 있습니다. 개체가 캐시에서 발견되면 true를 반환하고 그렇지 않으면 false를 반환합니다.< /리>
  7. hibernate는 모든 개체를 세션 첫 번째 수준 캐시에 캐시하기 때문에 대량 쿼리 또는 일괄 업데이트를 실행하는 동안 메모리 문제를 방지하기 위해 특정 간격으로 캐시를 지워야 합니다.

이것이 최대 절전 모드 캐싱 및 첫 번째 수준 캐시 예제의 전부입니다. 향후 게시물에서는 Hibernate 두 번째 수준 캐시 - EHCache 구현을 살펴볼 것입니다.