MEMPERBARUI
Jawaban ini mengandung informasi yang salah tentang perbedaan antara objek proxy dan objek parsial. Lihat jawaban @ Kontrollfreak untuk lebih jelasnya: https://stackoverflow.com/a/17787070/252591
Objek proxy digunakan setiap kali kueri Anda tidak mengembalikan semua data yang diperlukan untuk membuat entitas. Bayangkan skenario berikut:
@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
Seperti yang Anda lihat, kueri ini tidak mengembalikan firstname
dan lastname
properti, oleh karena itu Anda tidak dapat membuat User
objek. Pembuatan entitas yang tidak lengkap dapat menyebabkan kesalahan yang tidak terduga.
Itu sebabnya Doctrine akan membuat UserProxy
objek yang mendukung lazy loading. Ketika Anda mencoba mengakses firstname
properti (yang tidak dimuat), pertama-tama akan memuat nilai itu dari database.
Maksud saya, mengapa saya harus menggunakan proxy?
Anda harus selalu menulis kode Anda seolah-olah Anda tidak menggunakan objek proxy sama sekali. Mereka dapat diperlakukan sebagai objek internal yang digunakan oleh Doktrin.
Mengapa pemuatan lambat tidak dapat diterapkan di Entitiy itu sendiri?
Secara teknis bisa jadi tapi lihatlah kelas beberapa objek proxy acak. Itu penuh dengan kode kotor, ugh. Sangat menyenangkan memiliki kode yang bersih di entitas Anda.
Bisakah Anda memberi saya kasus penggunaan?
Anda sedang menampilkan daftar 25 artikel terbaru dan Anda ingin menampilkan rincian artikel pertama. Masing-masing berisi teks dalam jumlah besar, jadi mengambil semua data itu akan membuang-buang memori. Itulah mengapa Anda tidak mengambil data yang tidak perlu.
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;
}
}
Proksi
Doctrine proxy hanyalah pembungkus yang memperluas kelas entitas untuk menyediakan Lazy Loading untuknya.
Secara default, saat Anda meminta Manajer Entitas untuk entitas yang terkait dengan entitas lain, entitas terkait tidak akan dimuat dari database, tetapi dibungkus ke dalam objek proxy. Ketika aplikasi Anda kemudian meminta properti atau memanggil metode entitas yang di-proxy ini, Doctrine akan memuat entitas dari database (kecuali jika Anda meminta ID, yang selalu dikenal oleh proxy).
Ini terjadi sepenuhnya transparan untuk aplikasi Anda karena fakta bahwa proxy memperluas kelas entitas Anda.
Doctrine secara default akan menghidrasi asosiasi sebagai proxy pemuatan lambat jika Anda tidak
JOIN
memasukkannya dalam kueri atau menyetel mode pengambilan keEAGER
.Sekarang saya harus menambahkan ini karena saya tidak memiliki reputasi yang cukup untuk berkomentar di mana-mana:
Sayangnya, jawaban Crozin mengandung informasi yang salah.
Jika Anda menjalankan kueri DQL seperti
Anda tidak akan mendapatkan objek entitas (yang diproksikan), tetapi array asosiatif. Jadi, tidak mungkin untuk memuat properti tambahan secara lambat.
Dengan pemikiran ini, seseorang sampai pada kesimpulan bahwa contoh use case juga tidak akan berfungsi. DQL harus diubah menjadi seperti ini untuk mengakses
$article
sebagai objek:Dan properti yang dikembalikan oleh
getContent()
harus berupa asosiasi agar tidak memuat properti konten dari semua 25 entitas.Objek Parsial
Jika Anda ingin memuat sebagian properti entitas yang bukan merupakan asosiasi, Anda harus memberi tahu Doktrin ini secara eksplisit:
Ini memberi Anda objek entitas yang dimuat sebagian.
Namun berhati-hatilah karena objek parsial bukanlah proxy! Lazy Loading tidak berlaku untuk mereka. Oleh karena itu, menggunakan objek parsial umumnya berbahaya dan harus dihindari. Baca lebih lanjut: Objek Parsial - Doktrin 2 ORM 2 dokumentasi
sumber