program tip

교리 2의 대리 란 무엇입니까?

radiobox 2020. 7. 30. 10:17
반응형

교리 2의 대리 란 무엇입니까?


방금 모든 Doctrine 2 문서를 다 읽었고, 나는 자신의 샌드 박스를 시작했으며, 대부분의 원칙을 이해했지만 여전히 의문이 있으며 문서에서 완전한 설명을 찾을 수 없었습니다.

  1. Proxy수업 은 무엇입니까 ?
  2. 언제 엔티티에 사용해야합니까?

내가 이해하는 한 프록시 클래스는 레이어를 추가하여 엔티티에 다른 기능을 추가 할 수 있지만 엔티티 클래스에서 메소드 자체를 구현하는 대신 프록시를 사용하는 이유는 무엇입니까?


프록시 개체는 쿼리가 엔터티를 만드는 데 필요한 모든 데이터를 반환하지 않을 때마다 사용됩니다. 다음 시나리오를 상상해보십시오.

@Entity
class User {
     @Column protected $id;
     @Column protected $username;
     @Column protected $firstname;
     @Column protected $lastname;

     // bunch of setters/getters here
}

DQL query:

SELECT u.id, u.username FROM Entity\User u WHERE u.id = :id

당신이 볼 수 있듯이이 쿼리는 반환하지 않습니다 firstnamelastname특성, 따라서 당신은 만들 수 없습니다 User개체를. 불완전한 엔티티를 작성하면 예기치 않은 오류가 발생할 수 있습니다.

이것이 Doctrine이 UserProxy게으른 로딩을 지원하는 객체를 만드는 이유 입니다. firstname로드되지 않은 속성 에 액세스하려고 시도 하면 먼저 데이터베이스에서 해당 값을로드합니다.


왜 프록시를 사용해야합니까?

프록시 객체를 전혀 사용하지 않은 것처럼 항상 코드를 작성해야합니다. 그것들은 교리가 사용하는 내부 객체로 취급 될 수 있습니다.

Entitiy 자체에서 지연 로딩을 구현할 수없는 이유는 무엇입니까?

기술적으로는 임의의 프록시 객체 클래스를 살펴볼 수 있습니다. 더러운 코드로 가득합니다. 엔티티에 깨끗한 코드를 작성하는 것이 좋습니다.

유스 케이스를 제공해 주시겠습니까?

최신 25 개의 기사 목록을 표시하고 첫 번째 기사의 세부 사항을 표시하려고합니다. 각각에는 많은 양의 텍스트가 포함되어 있으므로 모든 데이터를 가져 오는 것은 메모리 낭비입니다. 이것이 불필요한 데이터를 가져 오지 않는 이유입니다.

SELECT a.title, a.createdAt
FROM Entity\Article a
ORDER BY a.createdAt DESC
LIMIT 25

$isFirst = true;
foreach ($articles as $article) {
    echo $article->getTitle();
    echo $article->getCreatedAt();

    if ($isFirst) {
        echo $article->getContent(); // Article::content is not loaded so it is transparently loaded 
                                     // for this single article.

        $isFirst = false;
    }
}

최신 정보

아래 주석 섹션에는 프록시 객체와 부분 객체의 차이점에 대한 잘못된 정보가 있습니다. 자세한 내용은 @Kontrollfreak 답변을 참조하십시오 : https : //.com/a/17787070/252591


프록시

Doctrine 프록시는 단지 Lazy Loading을 제공하기 위해 엔티티 클래스를 확장하는 래퍼입니다.

By default, when you ask the Entity Manager for an entity that is associated with another entity, the associated entity won't be loaded from the database, but wrapped into a proxy object. When your application then requests a property or calls a method of this proxied entity, Doctrine will load the entity from the database (except when you request the ID, which is always known to the proxy).

This happens fully transparent to your application due to the fact that the proxy extends your entity class.

Doctrine will by default hydrate associations as lazy load proxies if you don't JOIN them in your query or set the fetch mode to EAGER.


Now I must add this because I don't have enough reputation to comment everywhere:

Unfortunately, Crozin's answer contains misinformation.

If you execute a DQL query like

SELECT u.id, u.username FROM Entity\User u WHERE u.id = :id

you won't get a (proxied) entity object, but an associative array. So it's not possible to lazy load any additional properties.

With this in mind, one comes to the conclusion that the use case example won't work either. The DQL would have to be changed to something like this in order to access $article as object:

SELECT a FROM Entity\Article a ORDER BY a.createdAt DESC LIMIT 25

And the property returned by getContent() would have to be an association in order not to load the content properties of all 25 entities.


Partial Objects

If you want to partially load entity properties that are not associations, you have to tell this Doctrine explicitly:

SELECT partial u.{id, username} FROM Entity\User u WHERE u.id = :id

This gives you a partially loaded entity object.

But beware that partial objects are not proxies! Lazy Loading doesn't apply to them. Therefore, using partial objects is generally dangerous and should be avoided. Read more: Partial Objects — Doctrine 2 ORM 2 documentation

참고URL : https://stackoverflow.com/questions/4923817/what-is-a-proxy-in-doctrine-2

반응형