09 - Hibenate 3.6.2 대량 처리

8663 단어 일괄 처리hibenate

앞에서 우 리 는 Hibernate 의 조회 조작 을 총 결 했 습 니 다. 오늘 우 리 는 Hibernate 의 대량 처 리 를 말 합 니 다.
         Hibernate 는 완전히 대상 을 대상 으로 데이터 베 이 스 를 조작 합 니 다. 프로그램 에서 대상 을 대상 으로 영구 화 대상 을 조작 할 때 자동 으로 데이터베이스 에 대한 작업 으로 전 환 됩 니 다. 예 를 들 어 Session 의 delete () 방법 을 호출 하여 영구 화 대상 을 삭제 하고 Hibernate 는 해당 하 는 데이터 기록 을 삭제 합 니 다.지구 화 대상 의 set 방법 을 실행 할 때, Hibernate 는 자동 으로 대응 하 는 update 방법 으로 변환 하여 데이터베이스 에 대응 하 는 기록 을 수정 합 니 다.문 제 는 100 건, 000 건 기록 을 동시에 업데이트 해 야 한다 면 100 건, 000 건 기록 을 하나씩 불 러 온 다음 에 set 방법 을 순서대로 호출 해 야 하 는 것 이 아니 냐 는 것 이다. 번 거 로 울 뿐만 아니 라 데이터 접근 성능 도 매우 나쁘다.이러한 일괄 처리 장면 에 대해 Hibernate 는 일괄 처리 솔 루 션 을 제공 합 니 다.
         일괄 처리 데이터 란 한 업무 에서 대량의 데 이 터 를 처리 하 는 것 을 말한다.
일반적으로 응용 층 에서 대량 작업 을 하 는 것 을 피하 고 데이터베이스 층 에서 직접 대량 작업 을 해 야 한다.예 를 들 어 데이터베이스 에서 대량 업데이트 나 삭제 에 사용 되 는 SQL 문 구 를 직접 실행 하고 대량 작업 의 논리 가 복잡 하면 데이터베이스 에서 직접 실행 되 는 저장 과정 을 통 해 대량 작업 을 완성 할 수 있다.모든 데이터베이스 시스템 이 저장 과정 을 지원 하 는 것 은 아니다.예 를 들 어 현재 MySQL 은 저장 프로 세 스 를 지원 하지 않 기 때문에 저장 프로 세 스 를 통 해 일괄 업데이트 하거나 일괄 삭제 할 수 없습니다.물론 응용 층 에서 도 대량 작업 을 할 수 있 는데 주로 다음 과 같은 방식 이 있다.
(1) 세 션 을 통 해 대량 작업 을 한다.
  (2) StatelessSession 을 통 해 대량 작업 을 한다.
  (3) HQL 을 통 해 대량 작업 을 한다.
  (4) JDBC API 를 통 해 직접 대량 작업 을 한다.
 
1. 세 션 을 통 해 대량 작업 진행
Session 의 save () 방법 과 update () 방법 은 처리 대상 을 자신의 캐 시 에 저장 합 니 다.하나의 Session 대상 을 통 해 대량의 지구 화 대상 을 처리 하려 면 캐 시 에서 처리 되 었 고 접근 하지 않 는 대상 을 제때에 비 워 야 합 니 다. 구체 적 인 방법 은 대상 이나 소량 대상 을 처리 한 후에 즉시 flush () 방법 으로 캐 시 를 정리 한 다음 에 clear () 방법 으로 캐 시 를 비 우 는 것 입 니 다.
세 션 을 통 해 일괄 처 리 를 하면 다음 과 같은 제약 을 받 습 니 다.
(1) Hibernate 의 설정 파일 에 JDBC 의 일괄 처리 수 를 설정 해 야 합 니 다. 합 리 적 인 수 치 는 보통 10 에서 50 사이 입 니 다. 예 를 들 어:
<hibernate-configuration>
    <session-factory>
        .........
        <property name="hibernate.jdbc.batch_size">50</property>
        .........
    <session-factory>
<hibernate-configuration>

    (2) 대상 이 "idenity" 식별 자 생 성 기 를 사용 하면 Hibernate 는 JDBC 층 에서 일괄 삽입 작업 을 할 수 없습니다.
(3) 일괄 작업 을 할 때 Hibernate 의 두 번 째 캐 시 를 닫 는 것 을 권장 합 니 다.Session 의 캐 시 는 Hibernate 의 1 급 캐 시 입 니 다. 보통 사무 범위 내의 캐 시 입 니 다. 즉, 모든 사무 에 1 급 캐 시가 따로 있 습 니 다.Session Factory 의 외 장 캐 시 는 Hibernate 의 2 급 캐 시 입 니 다. 응용 범위 내의 캐 시 입 니 다. 즉, 모든 사무 가 같은 2 급 캐 시 를 공유 합 니 다.어떤 경우 에 도 Hibernate 의 첫 번 째 캐 시 는 항상 사용 할 수 있 습 니 다.기본적으로 Hibernate 의 2 급 캐 시 는 닫 혀 있 으 며, Hibernate 설정 파일 에서 2 급 캐 시 를 다음 과 같이 명시 적 으로 닫 을 수 있 습 니 다: hibernate. cache. usesecond_level_cache=false
 
1、  일괄 삽입
Session session = sessionFactory.openSession();
	Transaction tx = session.beginTransaction();
	for ( int i=0; i<100000; i++ ) {
		Customer customer = new Customer(.....);
		session.save(customer);
		if ( i % 20 == 0 ) { //          20
			session.flush();//    ,      20    SQL insert  
			session.clear();//      Customer  
		}
	}
	tx.commit();
	session.close();

상기 프로그램 에서 session. flush () 방법 을 실행 할 때마다 데이터베이스 에 20 개의 기록 을 대량으로 삽입 합 니 다.다음 session. clear () 방법 은 저 장 된 Customer 대상 20 개 를 캐 시 에서 비 웁 니 다.
상기 절차 가 순조롭게 운행 되도록 다음 과 같은 제약 을 준수 해 야 한다.
  1. Hibernate 설정 파일 에서 hibernate. jdbc. batchsize 속성 도 20 으로 설정 합 니 다.
  2. 2 급 캐 시 를 닫 습 니 다.2 급 캐 시 를 사용 했다 면 1 급 캐 시 (즉 Session 캐 시) 에 만 든 모든 Customer 대상 은 2 급 캐 시 에 복사 한 다음 데이터베이스 에 저장 해 야 하기 때문에 불필요 한 비용 이 많이 들 수 있 습 니 다.
  3. Customer 대상 의 식별 자 생 성 기 는 'idenity' 가 될 수 없습니다.
 
1、  대량 업데이트
일괄 업 데 이 트 를 진행 할 때 세 션 캐 시 에 모든 대상 을 한꺼번에 불 러 온 다음 캐 시 에 일일이 업데이트 하 는 것 은 바람 직 하지 않 습 니 다.이 문 제 를 해결 하기 위해 서 는 스크롤 가능 한 결과 집합 org. hibenate. ScrollableResults, Query 의 scroll () 방법 으로 ScrollableResults 대상 을 되 돌려 줍 니 다.다음 코드 는 Customer 대상 을 대량으로 업데이트 하 는 것 을 보 여 줍 니 다. 이 코드 는 처음에 ScrollableResults 대상 을 이용 하여 모든 Customer 대상 을 불 러 옵 니 다.
Session session = sessionFactory.openSession();
	Transaction tx = session.beginTransaction();
	ScrollableResults customers = session.getNamedQuery("GetCustomers")
		.setCacheMode(CacheMode.IGNORE)
		.scroll(ScrollMode.FORWARD_ONLY);
	int count=0;
	while ( customers.next() ) {
		Customer customer = (Customer) customers.get(0);
		customer.updateStuff(...);//  Customer  
		if ( ++count % 20 == 0 ) {//          20
			session.flush();//    ,      20    SQL update  
			session.clear();//      Customer  
		}
	}
	tx.commit();
	session.close();

이 코드 에 서 는 Query 의 scroll () 방법 이 되 돌아 오 는 ScrollableResults 대상 에 실제 Customer 대상 이 포함 되 어 있 지 않 으 며, 온라인 포 지 셔 닝 데이터베이스 에 있 는 CUSTOMERS 기록 에 사용 할 커서 만 포함 되 어 있 습 니 다.프로그램 이 ScrollableResults 대상 의 특정 요 소 를 옮 겨 다 닐 때 만 데이터베이스 에 해당 하 는 Customer 대상 을 불 러 옵 니 다.
상기 절차 가 순조롭게 운행 되도록 다음 과 같은 제약 을 준수 해 야 한다.
        1. Hibernate 설정 파일 에서 hibernate. jdbc. batchsize 속성 도 20 으로 설정 합 니 다.
        2. 2 급 캐 시 를 닫 습 니 다.설정 파일 에 2 급 캐 시 를 사용 했다 면 다음 과 같은 방식 으로 프로그램 에서 2 급 캐 시 를 무시 할 수 있 습 니 다. setCacheMode (CacheMode. IGNORE). scroll (Scroll Mode. FORWARD ONLY);
 
2. StatelessSession (무 상태 Session) 을 통 해 대량 작업
Session 은 메모리 의 대상 과 데이터베이스 의 해당 데 이 터 를 동기 화 하 는 캐 시 를 가지 고 있 으 며, Session 캐 시 에 있 는 대상 은 지구 화 대상 입 니 다.그러나 대량 작업 을 할 때 대량의 대상 을 세 션 캐 시 에 저장 하면 대량의 메모리 공간 이 소모 된다.대체 방안 으로 무 상태의 StatelessSession 을 사용 하여 대량 작업 을 할 수 있 습 니 다.
StatelessSession:
무 상태 session 은 1 급 cache 를 실현 하지 않 고 2 급 캐 시 나 캐 시 와 상호작용 하지 않 습 니 다.그것 은 사무 화 를 실현 하지 도 않 고 더러 운 데이터 검사 도 실현 하지 않 는 다.stateless session 으로 진행 되 는 작업 은 관련 인 스 턴 스 와 연결 되 지 않 습 니 다.stateless session 은 집합 클래스 (Collections) 를 무시 합 니 다.stateless session 을 통 해 진행 되 는 동작 은 Hibernate 의 이벤트 모델 과 차단 기 를 터치 하지 않 습 니 다.첫 번 째 캐 시가 없 기 때문에 상태 세 션 이 데이터 의 혼동 현상 에 면역 이 됩 니 다.무 상태 세 션 은 저층 의 추상 으로 저층 JDBC 와 상당히 가깝다.
	StatelessSession session = sessionFactory.openStatelessSession();
	Transaction tx = session.beginTransaction();
	ScrollableResults customers = session.getNamedQuery("GetCustomers").scroll(ScrollMode.FORWARD_ONLY);
	while ( customers.next() ) {
		Customer customer = (Customer) customers.get(0);
		customer.updateStuff(...);
		session.update(customer);
	}
	tx.commit();
	session.close();

 
형식적 으로 는 스테이 트 리 스 세 션 과 세 션 의 용법 이 비슷 하 다.StatelessSession 은 Session 에 비해 다음 과 같은 차이 가 있 습 니 다.
 (1) StatelessSession 은 캐 시 되 지 않 고 StatelessSession 을 통 해 불 러 오 거나 저장 하거나 업 데 이 트 된 대상 이 모두 유리 상태 에 있 습 니 다.
 (2) StatelessSession 은 Hibernate 의 2 급 캐 시 와 상호작용 하지 않 습 니 다.
 (3) StatelessSession 의 save (), update () 또는 delete () 방법 을 호출 할 때 이 방법 들 은 SQL 문 구 를 실행 할 계획 이 아니 라 해당 하 는 SQL 문 구 를 즉시 실행 합 니 다.
 (4) StatelessSession 은 불 러 온 대상 에 대해 자동 으로 더러 운 검 사 를 하지 않 습 니 다.따라서 상기 프로그램 에서 메모리 에 있 는 Customer 대상 의 속성 을 수정 한 후 StatelessSession 의 update () 방법 을 통 해 데이터베이스 에 있 는 해당 데 이 터 를 업데이트 해 야 한다.
 (5) StatelessSession 은 관련 대상 에 대해 어떠한 직렬 연결 작업 도 하지 않 습 니 다.예 를 들 어 StatelessSession 을 통 해 Customer 대상 을 저장 할 때 이와 관련 된 Order 대상 을 직렬 로 저장 하지 않 습 니 다.
 (6) StatelessSession 에서 하 는 작업 은 Interceptor 차단기 에 의 해 포착 되 지만 Hibernate 의 이벤트 처리 시스템 에 의 해 무 시 됩 니 다.
 (7) 같은 StatelessSession 대상 을 통 해 OID 가 1 인 Customer 대상 을 두 번 불 러 올 때 서로 다른 메모리 주 소 를 가 진 Customer 대상 을 얻 을 수 있 습 니 다. 예 를 들 어:
StatelessSession session = sessionFactory.openStatelessSession();
Customer c1=(Customer)session.get(Customer.class,new Long(1));
Customer c2=(Customer)session.get(Customer.class,new Long(1));
System.out.println(c1==c2); //  false

 
3. HQL 을 통 해 대량 작업
 
1. 대량 업데이트
Session session = sessionFactory.openSession();
	Transaction tx = session.beginTransaction();
	 
	String hqlUpdate ="update Customer c set c.name = :newName where c.name = :oldName";
	int updatedEntities = session.createQuery( hqlUpdate )
	 	.setString( "newName", "Mike" )
	 	.setString( "oldName", "Tom" )
	 	.executeUpdate();
	 
	tx.commit();
	session.close();

 
2. 일괄 삭제
	 Session session = sessionFactory.openSession();
	 Transaction tx = session.beginTransaction();
	 
	 String hqlDelete = "delete Customer c where c.name = :oldName";
	 int deletedEntities = session.createQuery( hqlDelete )
	 	.setString( "oldName", "Tom" )
	 	.executeUpdate();
	 tx.commit();
	 session.close();

 
4. JDBC API 를 통 해 직접 대량 작업
 
대략.

좋은 웹페이지 즐겨찾기