2012-07-14 13 views
17

Podczas używania doktryny zauważyłem, że aby usunąć encję, muszę pobrać tę encję przez podany parametr (name, id itp), a następnie wywołać metodę remove. Z drugiej strony, w zapytaniu mogę po prostu wykonać kwerendę usuwania.Jednostka doktryny usuń a usuń zapytanie, porównanie wydajności

Wygląda na to, że użycie stylu ORM wymaga dwóch operacji, a ogólna obsługa sql wymaga jednej operacji. Dlatego jestem nieco zagmatwany, czy powinniśmy używać operacji usuwania (lub aktualizacji) w ORM? Czy to nie gorsze w wykonaniu? Czy jest coś jeszcze, czego mi brakuje? Czy można to zrobić w jakikolwiek inny sposób w stylu ORM?

Odpowiedz

38

W Doctrine2 można wywołać usuwanie na obiekcie proxy, który nie jest ładowany z bazy danych. Wystarczy stworzyć „atrapę” obiekt, coś takiego:

$user = $em->getPartialReference('model\User', array('id' => $id)); 
$em->remove($user); 

Nie wymaga wstępnego zapytania, ale nie jestem pewien, czy nadal to robi Doktryna wewnętrznie na fush. Nie widzę tego w SqlLogu.

Trzeba dodać, że jest to oczekiwane zachowanie każdej przyzwoitej ORM. Zajmuje się obiektami i relacjami. Musi wiedzieć, że coś istnieje przed usunięciem. ORM to nie tylko generator zapytań . Ogólnie rzecz biorąc, zapytanie natywne zawsze będzie szybsze w dowolnej ORM. Każda ORM dodaje warstwę abstrakcji i jej wykonanie zajmuje trochę czasu. Jest to typowy kompromis, masz kilka ciekawych funkcji i czysty kod, ale tracisz trochę na wydajności.

EDIT:

cieszę się, że pracował dla ciebie. Właściwie natknąłem się na inny problem, który uświadomił mi, że proxy i częściowe obiekty nie są właściwie tym samym. Częściowa instancja obiektów to prawdziwa klasa modelu i wypełnij ją wybranymi wartościami. Po zainicjowaniu częściowego obiektu leniwe ładowanie nie działa już na nim. Na przykład, jeśli tworzysz częściowy obiekt z tylko identyfikatorem i chcesz usunąć tylko wtedy, gdy inne pole obiektu spełnia pewne warunki, to nie zadziała, ponieważ to inne pole zawsze będzie miało wartość null.

Z drugiej strony, serwery proxy działają z obciążaniem i nie dzielą się problemami, które mają częściowe obiekty. Więc zdecydowanie sugerujemy, aby nie używać getPartialReference sposób, zamiast tego można zrobić coś takiego:

$user = $em->getReference('model\User', $id); 
$em->remove($user); 

Sposób getReference zwraca obiekt, jeśli jest już załadowany lub pełnomocnika, jeżeli tak nie jest. Serwer proxy może leniwej załadować wszystkie inne wartości, jeśli/kiedy są potrzebne. Jeśli chodzi o twój przykład, będą zachowywać się dokładnie tak samo, ale z pewnością lepszym rozwiązaniem będą serwery proxy.

+1

dzięki za informacje i clarificaiton – Rana

4

Gotowe! dla mnie to działało jak ten dodatek Wiersz 3:

$user = $em->getReference('model\User', $id); 
$em->remove($user); 
$em->flush();