최대 절전 모드에서 지연 로딩이란 무엇입니까?


178

Java에서 지연 로딩이란 무엇입니까? 과정을 이해하지 못합니다. 아무도 게으른 로딩 과정을 이해하도록 도와 줄 수 있습니까?

답변:


268

부모님이 있고 그 부모에게 자녀 모음이 있다고 가정하십시오. 최대 절전 모드는 이제 자식을 "지연로드"할 수 있습니다. 즉, 부모를로드 할 때 실제로 모든 자식을로드하지는 않습니다. 대신 요청이있을 때로드합니다. 이것을 명시 적으로 요청하거나 훨씬 더 일반적으로 요청할 수 있으며, 최대 절전 모드는 자식에 액세스하려고 할 때 자동으로로드됩니다.

지연 로딩은 종종 자식이 필요하지 않으므로로드되지 않기 때문에 성능을 크게 향상시키는 데 도움이됩니다.

n + 1 문제도주의하십시오. 최대 절전 모드는 컬렉션에 액세스 할 때 실제로 모든 자식을로드하지 않습니다. 대신 각 자식을 개별적으로로드합니다. 컬렉션을 반복 할 때 모든 자식에 대한 쿼리가 발생합니다. 이를 피하기 위해, 예를 들어 parent.getChildren (). size ()를 호출하여 모든 자식을 동시에로드하도록 최대 절전 모드를 속일 수 있습니다.


5
다른 방법들 Hibernate.initialize (parent.getChildren는 ())를 사용한다
HakunaMatata

18
"컬렉션에 액세스 할 때 ... 각 자식을 개별적으로로드 할 것"이라는 문장은 실제로 완전히 부정확합니다. 실제로는 정반대입니다. parent.getChildren ()을 역 참조하면 Hibernate는 컬렉션에있는 모든 자식들을 하나의 db 쿼리로로드하게된다. 매우 특별한 "추가 게으른"게으른 로딩 힌트를 사용하지 않는 한. 또는 콜렉션을 2 차 레벨 캐시에 캐시하지 않으면 연관된 하위도 캐시되지 않습니다.
Steve Ebersole 17

오, 스택 오버플로-가장 좋은 답변은 페이지 하단에 있습니다 ;-)
Piotrek Hryciuk

76

"게으른로드"는 실제로 첫 번째 엔티티에 액세스 할 때만 엔티티가로드됨을 의미합니다. .

패턴은 다음과 같이이다 :

public Entity getEntity() {
    if (entity == null) {
        entity = loadEntity();
    }
    return entity;
}

이 / 미리로드 미리 입력의 비용을 절약 할 수 있는 모든에게 모든 사실 필요가 없습니다 후 동안 미리 큰 데이터 세트에서 엔티티를 모두 그들 중입니다.

최대 절전 모드에서 하위 엔터티 컬렉션을 느리게로드하도록 구성 할 수 있습니다. 실제 지연로드는 다음의 방법 안에 완료 PersistentSet"후드 아래"하는 최대 절전 모드 사용 등 개체의 컬렉션을 지정합니다 Set.

예 :

public class Parent {
    private Set<Child> children;

    public Set<Child> getChildren() {
        return children;
    }
}

.

public void doSomething() {
    Set<Child> children = parent.getChildren(); // Still contains nothing.

    // Whenever you call one of the following (indirectly), 
    // Hibernate will start to actually load and fill the set.
    children.size();
    children.iterator();
}

25

Martin Fowler는 다음 과 같이 엔터프라이즈 애플리케이션 아키텍처 패턴에서 지연로드 패턴을 정의합니다 .

필요한 모든 데이터를 포함하지는 않지만 가져 오는 방법을 알고있는 객체입니다.

따라서 주어진 객체를로드 할 때 관련 성능 비용을 절약하기 위해 즉시 사용할 수없는 관련 객체를 열망 하지 않는 것이 좋습니다 . 대신 관련 개체가 사용될 때만로드됩니다.

이것은 데이터 액세스 및 최대 절전 모드에 특정한 패턴은 아니지만 이러한 필드에서 특히 유용하며 최대 절전 모드는 일대 다 연결 및 단일 지점 연결 (일대일 및 다 대일)의 지연로드를 지원합니다. 특정 조건에서. 게으른 상호 작용에 대해서는 Hibernate 3.0 Reference Documentation의 19 장 에서 더 자세히 설명 합니다.


15

지연 로딩은 기본적으로 true입니다. 지연 로딩은 선택 쿼리가 실행될 때 데이터베이스에 도달하지 않음을 의미합니다. getter 함수를 기다릴 것입니다. 즉, 필요할 때 datbase에서 가져옵니다. 예를 들어, 당신은 장난감이 많은 아이를 가진 부모입니다. 그러나 현재 문제는 당신이 그를 부를 때마다 (우리는 당신이 소년이 있다고 가정합니다), 그는 모든 장난감을 가지고 당신에게옵니다. 이제는 장난감을 항상 가지고 다니는 것을 원하지 않기 때문에 이것은 문제입니다. 따라서 합리적 인 부모이기 때문에 바로 어린이의 장난감을 LAZY로 정의하십시오. 지금 당신이 그를 부를 때마다, 그는 그의 장난감없이 당신에게 온다.


11

지연 가져 오기는 상위 오브젝트를로드하는 동안 하위 오브젝트를로드할지 여부를 결정합니다. 부모 클래스의 각 최대 절전 모드 매핑 파일에서이 설정을 수행해야합니다. Lazy = true(자식을로드하지 않음을 의미) 기본적으로 자식 오브젝트의 지연로드는 true입니다.

이렇게하면 응용 프로그램에서 하위 개체를 호출하여 명시 적으로 호출하지 않는 한 자식 개체가로드되지 않습니다. getChild() 메소드를getChild() 합니다.

그러나 경우에 따라 부모가로드 될 때 자식 개체를로드해야합니다. lazy = false로 설정하면 부모가 데이터베이스에서로드 될 때 최대 절전 모드에서 자식을로드합니다.

예 : TABLE이 있다면? EMPLOYEE는 Employee 개체에 매핑되었으며 Address 개체 집합을 포함합니다. 부모 클래스 : 직원 클래스, 자식 클래스 : 주소 클래스

public class Employee { 
private Set address = new HashSet(); // contains set of child Address objects 
public Set getAddress () { 
return address; 
} 
public void setAddresss(Set address) { 
this. address = address; 
} 
} 

Employee.hbm.xml 파일에서

<set name="address" inverse="true" cascade="delete" lazy="false"> 
<key column="a_id" /> 
<one-to-many class="beans Address"/> 
</set> 

위 구성에서. 만약lazy="false" :-해당 하위 개체 주소가 Employee 개체를로드 할 때 setAddresss () 메서드로 설정됩니다. employee.getAdress ()를 호출하면로드 된 데이터가 반환됩니다. 새 데이터베이스 호출이 없습니다.

If lazy="true":-기본 구성입니다. 언급하지 않으면 최대 절전 모드로 설정하면 lazy = true로 간주됩니다. 하위 오브젝트 Adress가로드되지 않은 시간에 Employee 오브젝트를로드 할 때 주소 개체를 얻으려면 데이터베이스를 추가로 호출해야합니다. 호출 employee.getAdress()하면 해당 시간 데이터베이스 쿼리가 실행되고 결과가 반환됩니다. 새로운 데이터베이스 호출.


이 시나리오에서 직원과 주소는 부모-자녀 관계가 없습니다. 그것은이다 '가-A'의 관계 !
Ram

이것은 상속이 아닌 집계입니다.
Rishi

11

평신도의 언어로는 케이크를 만드는 것과 같으며 냉장고에서 5-10 가지 재료가 필요합니다. 냉장고에서 모든 재료를 가져와 주방 플랫폼에 놓거나 필요할 때 원하는 물건을 가져 오는 두 가지 옵션이 있습니다.

비슷하게, 열망하는 로딩에서, 당신은 콩과 관련 클래스에 대한 모든 정보를 가져옵니다. 동일한 테이블에서 나오는 식별자와 값만 가져옵니다 (케이크의 경우 먼저 그릇에 필요한 재료). 다른 테이블에서 오는 모든 정보는 필요할 때 / 사용할 때 가져옵니다.


8

게으른 로딩? 즉, 하위 레코드는 즉시 가져 오지 않고 액세스하려는 즉시 자동으로 가져옵니다.


4

지연로드를 사용하면 연관 검색을 지연 시키거나 페치 전략을보다 잘 제어 할 수 있습니다.

EAGER 로딩을 사용하는 경우 쿼리시 재정의 할 수없는 전역 페치 계획을 정의하므로 엔터티 모델을 디자인 할 때 결정한 사항으로 제한됩니다. EAGER 페치는 코드 냄새입니다 페치 전략은 질의 시간 정책과는 다른 비즈니스 유스 케이스 다를 수 있기 때문에.

가져 오는 전략은 너무 많은 EAGER 가져 오는 심각한 성능 관련 문제가 발생할 수 있으므로, 매우 중요한 측면이다.


3

게으른 설정은 부모 개체를로드하는 동안 자식 개체를로드 할 것인지 여부를 결정합니다.이 설정은 부모 클래스의 각 최대 절전 모드 매핑 파일을 설정해야합니다 .Lazy = true (자식을로드하지 않음) 기본적으로 자식 개체의 지연로드는 true입니다 . 이렇게하면 부모에서 getChild () 메서드를 호출하여 응용 프로그램에서 자식 개체를 명시 적으로 호출하지 않으면 자식 개체가로드되지 않습니다.이 경우에는 최대 절전 모드에서 getChild ()가 부모에서 호출 될 때 자식을로드하기 위해 새 데이터베이스 호출이 실행됩니다. 그러나 경우에 따라 부모가로드 될 때 자식 개체를로드해야합니다. lazy = false로 설정하면 부모가 데이터베이스에서로드 될 때 최대 절전 모드에서 자식을로드합니다. 예 : lazy = true (기본값) 사용자 클래스의 주소 자식은 자주 필요하지 않은 경우 게으르게 만들 수 있습니다.


2

지연 로딩은 필요한 시점까지 객체의 초기화를 연기하기 위해 컴퓨터 프로그래밍에서 일반적으로 사용되는 디자인 패턴입니다. 적절하고 적절하게 사용되면 프로그램 운영의 효율성에 기여할 수 있습니다

위키 백과

hibernate.org에서 게으른 로딩의 링크


1

그것은 단순히 지금 사용하지 않을 전체 데이터를 한 번에로드하는 대신 현재 필요한 데이터를로드하는 것을 의미합니다. 따라서 응용 프로그램로드 시간이 평소보다 빨라집니다.


0

Hiberante는 엔터티와 컬렉션 모두에 대해 지연 초기화 기능을 지원합니다. Hibernate 엔진은 우리가 쿼리하고있는 객체들만 다른 엔터 티나 컬렉션을로드하지 않는다.

lazy = "false"기본적으로 유일한 자식에 대한 로딩 초기화 언급은 lazy입니다. 부모 인 경우 자식이 지원되지 않는 경우 true


0

게으른 설정은 부모 개체를로드하는 동안 자식 개체를로드 할 것인지 여부를 결정합니다.이 설정은 부모 클래스의 각 최대 절전 모드 매핑 파일을 설정해야합니다 .Lazy = true (자식을로드하지 않음) 기본적으로 자식 개체의 지연로드는 true입니다 .


0

놀랍게도 화면 뒤에서 최대 절전 모드를 통해 어떻게 달성되는지에 대한 답변은 없습니다.

지연 로딩 은 다음 기술을 포함하는 성능상의 이유로 최대 절전 모드에서 효과적으로 사용되는 디자인 패턴입니다.


1. 바이트 코드 계측 :

해당 엔티티 객체에 대한 모든 호출을 가로 채기 위해 최대 절전 모드 후크 로 기본 클래스 정의를 향상시킵니다 .

컴파일 타임 또는 실행 시간에 완료

1.1 컴파일 시간

  • 컴파일 후 작업

  • 주로 maven / ant 플러그인에 의해

1.2 런타임

  • 컴파일 타임 인스 트루먼 테이션이 수행되지 않으면 런타임시 작성됩니다. javassist 와 같은 라이브러리 사용

2. 프록시

Hibernate가 리턴하는 엔티티 객체는 실제 타입의 프록시이다.

Javassist 도 참조하십시오 . 주요 아이디어는 무엇이며 어디에 실제로 사용됩니까?

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.