Veritabanı Gezgini
Explorer, veritabanınızla çalışmak için sezgisel ve verimli bir yol sunar. Tablolar arasındaki ilişkileri otomatik olarak ele alır, optimize edilmiş sorgular oluşturur ve uygulama mantığınıza odaklanmanızı sağlar. Yapılandırma gerekmez. Tam kontrol için SQL yöntemine geçebilirsiniz.
- Verilerle çalışmak doğaldır ve anlaşılması kolaydır
- Yalnızca gerekli verileri getiren optimize edilmiş SQL sorguları oluşturur
- JOIN sorguları yazmaya gerek kalmadan ilgili verilere kolay erişim sağlar
- Herhangi bir yapılandırma veya varlık oluşturma olmadan hemen çalışır
Explorer ile çalışmak, Nette\Database\Explorer
nesnesinde table()
yöntemini çağırarak başlar (veritabanı bağlantısı kurulumu hakkında ayrıntılar için
Bağlantı ve Yapılandırma bölümüne bakın):
Yöntem, bir SQL sorgusunu temsil eden bir Selection nesnesi döndürür. Sonuçları
filtrelemek ve sıralamak için bu nesneye ek yöntemler zincirlenebilir. Sorgu yalnızca veriler istendiğinde, örneğin
foreach
ile yinelenerek bir araya getirilir ve yürütülür. Her satır bir ActiveRow nesnesi ile temsil edilir:
Explorer, tablo ilişkileriyle çalışmayı büyük ölçüde kolaylaştırır. Aşağıdaki örnek, ilgili tablolardan (kitaplar ve yazarları) ne kadar kolay veri çıktısı alabileceğimizi göstermektedir. JOIN sorgularının yazılmasına gerek olmadığına dikkat edin; Nette bunları bizim için oluşturuyor:
Nette Database Explorer sorguları maksimum verimlilik için optimize eder. Yukarıdaki örnek, 10 veya 10.000 kitap işlememizden bağımsız olarak yalnızca iki SELECT sorgusu gerçekleştirir.
Ayrıca Explorer, kodda hangi sütunların kullanıldığını izler ve veritabanından yalnızca bunları getirerek daha fazla performans tasarrufu sağlar. Bu davranış tamamen otomatik ve uyarlanabilirdir. Daha sonra kodu ek sütunlar kullanacak şekilde değiştirirseniz, Explorer sorguları otomatik olarak ayarlar. Hiçbir şeyi yapılandırmanıza veya hangi sütunlara ihtiyaç duyulacağını düşünmenize gerek yok – bunu Nette'e bırakın.
Filtreleme ve Sıralama
Selection
sınıfı, verileri filtrelemek ve sıralamak için yöntemler sağlar.
where($condition, ...$params) |
Bir WHERE koşulu ekler. Birden fazla koşul AND kullanılarak birleştirilir |
whereOr(array $conditions) |
OR kullanılarak birleştirilmiş bir grup WHERE koşulu ekler |
wherePrimary($value) |
Birincil anahtarı temel alan bir WHERE koşulu ekler |
order($columns, ...$params) |
ORDER BY ile sıralamayı ayarlar |
select($columns, ...$params) |
Hangi sütunların getirileceğini belirtir |
limit($limit, $offset = null) |
Satır sayısını sınırlar (LIMIT) ve isteğe bağlı olarak OFFSET ayarlar |
page($page, $itemsPerPage, &$total = null) |
Sayfalandırmayı ayarlar |
group($columns, ...$params) |
Satırları gruplar (GROUP BY) |
having($condition, ...$params) |
Gruplanmış satırları filtrelemek için bir HAVING koşulu ekler |
Yöntemler zincirlenebilir ( akıcı arayüz olarak
adlandırılır): $table->where(...)->order(...)->limit(...)
.
Bu yöntemler ayrıca ilgili tablolardan verilere erişmek için özel gösterimlerin kullanılmasına izin verir.
Kaçış ve Tanımlayıcılar
Yöntemler parametreleri ve alıntı tanımlayıcılarını (tablo ve sütun adları) otomatik olarak kaçarak SQL enjeksiyonunu önler. Düzgün çalışmayı sağlamak için birkaç kurala uyulmalıdır:
- Anahtar sözcükleri, işlev adlarını, yordamları vb. büyük harfle yazın.
- Sütun ve tablo adlarını küçük harfle yazın.
- Dizeleri her zaman parameters kullanarak geçirin.
where(string|array $condition, …$parameters): static
WHERE koşullarını kullanarak sonuçları filtreler. Gücü, çeşitli değer türlerini akıllıca ele almasında ve SQL operatörlerini otomatik olarak seçmesinde yatmaktadır.
Temel kullanım:
Uygun operatörlerin otomatik olarak algılanması sayesinde, özel durumlarla uğraşmanıza gerek kalmaz – Nette bunları sizin için halleder:
Yöntem ayrıca negatif koşulları ve boş dizileri de doğru şekilde işler:
Ayrıca, bir alt sorgu oluşturarak başka bir tablo sorgusunun sonucunu parametre olarak aktarabilirsiniz:
Koşullar, AND kullanılarak birleştirilen öğelerle birlikte bir dizi olarak da geçirilebilir:
Dizide, anahtar-değer çiftleri kullanılabilir ve Nette yine otomatik olarak doğru operatörleri seçecektir:
SQL ifadelerini yer tutucular ve çoklu parametrelerle de karıştırabiliriz. Bu, kesin olarak tanımlanmış operatörlere sahip karmaşık koşullar için kullanışlıdır:
where()
adresine yapılan birden fazla çağrı, AND kullanarak koşulları otomatik olarak birleştirir.
whereOr(array $parameters): static
where()
adresine benzer, ancak OR kullanarak koşulları birleştirir:
Daha karmaşık ifadeler de kullanılabilir:
wherePrimary(mixed $key): static
Tablonun birincil anahtarı için bir koşul ekler:
Tablonun bileşik bir birincil anahtarı varsa (örneğin, foo_id
, bar_id
), bunu bir dizi olarak
iletiriz:
order(string $columns, …$parameters): static
Satırların döndürüleceği sırayı belirtir. Bir veya daha fazla sütuna göre, artan veya azalan sırada veya özel bir ifadeye göre sıralayabilirsiniz:
select(string $columns, …$parameters): static
Veritabanından döndürülecek sütunları belirtir. Varsayılan olarak, Nette Database Explorer yalnızca kodda gerçekten
kullanılan sütunları döndürür. Belirli ifadeleri almanız gerektiğinde select()
yöntemini kullanın:
AS
kullanılarak tanımlanan takma adlara daha sonra ActiveRow
nesnesinin özellikleri olarak
erişilebilir:
limit(?int $limit, ?int $offset = null): static
Döndürülen satır sayısını sınırlar (LIMIT) ve isteğe bağlı olarak bir ofset ayarlar:
Sayfalandırma için page()
yöntemini kullanmak daha uygundur.
page(int $page, int $itemsPerPage, &$numOfPages = null): static
Sonuçların sayfalandırılmasını basitleştirir. Sayfa numarasını (1'den başlayarak) ve sayfa başına öğe sayısını kabul eder. İsteğe bağlı olarak, toplam sayfa sayısının saklanacağı bir değişkene referans geçebilirsiniz:
group(string $columns, …$parameters): static
Satırları belirtilen sütunlara göre gruplar (GROUP BY). Tipik olarak toplama fonksiyonları ile birlikte kullanılır:
having(string $having, …$parameters): static
Gruplandırılmış satırları filtrelemek için bir koşul belirler (HAVING). group()
yöntemi ve toplama
işlevleri ile birlikte kullanılabilir:
Veri Okuma
Veritabanından veri okumak için birkaç kullanışlı yöntem mevcuttur:
foreach ($table as $key => $row) |
Tüm satırlar arasında yineleme yapar, $key birincil anahtar değeridir, $row bir ActiveRow
nesnesidir |
$row = $table->get($key) |
Birincil anahtara göre tek bir satır döndürür |
$row = $table->fetch() |
Geçerli satırı döndürür ve işaretçiyi bir sonrakine ilerletir |
$array = $table->fetchPairs() |
Sonuçlardan ilişkisel bir dizi oluşturur |
$array = $table->fetchAll() |
Tüm satırları bir dizi olarak döndürür |
count($table) |
Seçim nesnesindeki satır sayısını döndürür |
ActiveRow nesnesi salt okunurdur. Bu, özelliklerinin değerlerini değiştiremeyeceğiniz anlamına gelir. Bu kısıtlama, veri tutarlılığını sağlar ve beklenmedik yan etkileri önler. Veriler veritabanından alınır ve herhangi bir değişiklik açıkça ve kontrollü bir şekilde yapılmalıdır.
foreach
– Tüm Satırlar Arasında Yineleme
Bir sorguyu çalıştırmanın ve satırları almanın en kolay yolu foreach
döngüsü ile yinelemektir. SQL
sorgusunu otomatik olarak yürütür.
get($key): ?ActiveRow
Bir SQL sorgusu çalıştırır ve bir satırı birincil anahtarına göre veya yoksa null
adresine
döndürür.
fetch(): ?ActiveRow
Bir satır döndürür ve dahili işaretçiyi bir sonrakine ilerletir. Başka satır yoksa null
döndürür.
fetchPairs(string|int|null $key = null, string|int|null $value = null): array
Sonuçları ilişkisel bir dizi olarak döndürür. İlk bağımsız değişken, dizi anahtarı olarak kullanılacak sütunun adını ve ikinci bağımsız değişken, değer olarak kullanılacak sütunun adını belirtir:
Yalnızca ilk parametre sağlanırsa, tüm satır değer olarak kullanılır ve ActiveRow
nesnesi olarak temsil
edilir:
Yinelenen anahtarlar olması durumunda, son satırdaki değer kullanılır. Anahtar olarak null
kullanıldığında, dizi sıfırdan itibaren sayısal olarak indekslenecektir (bu durumda herhangi bir çakışma meydana
gelmez):
fetchPairs(Closure $callback): array
Alternatif olarak, parametre olarak bir geri arama iletebilirsiniz. Geri arama, tek bir değer veya bir anahtar-değer çifti döndürmek için her satıra uygulanacaktır.
fetchAll(): array
Tüm satırları, anahtarların birincil anahtar değerleri olduğu ActiveRow
nesnelerinin ilişkisel bir dizisi
olarak döndürür.
count(): int
Parametreleri olmayan count()
yöntemi, Selection
nesnesindeki satır sayısını döndürür:
Not: count()
bir parametre ile birlikte, aşağıda açıklandığı gibi veritabanında COUNT toplama işlevini
gerçekleştirir.
ActiveRow::toArray(): array
ActiveRow
nesnesini, anahtarların sütun adları ve değerlerin karşılık gelen veriler olduğu bir ilişkisel
diziye dönüştürür.
Birleştirme
Selection
sınıfı, toplama işlevlerini (COUNT, SUM, MIN, MAX, AVG, vb.) kolayca gerçekleştirmek için
yöntemler sağlar.
count($expr) |
Satır sayısını sayar |
min($expr) |
Bir sütundaki minimum değeri döndürür |
max($expr) |
Bir sütundaki maksimum değeri döndürür |
sum($expr) |
Bir sütundaki değerlerin toplamını verir |
aggregation($function) |
AVG() veya GROUP_CONCAT() gibi herhangi bir toplama işlevine izin verir |
count(string $expr): int
COUNT işleviyle bir SQL sorgusu çalıştırır ve sonucu döndürür. Bu yöntem, kaç satırın belirli bir koşulla eşleştiğini belirlemek için kullanılır:
Not: count() parametresiz olarak sadece Selection
nesnesindeki satır sayısını
döndürür.
min(string $expr) and max(string $expr)
min()
ve max()
yöntemleri, belirtilen sütun veya ifadedeki minimum ve maksimum değerleri
döndürür:
sum(string $expr): int
Belirtilen sütundaki veya ifadedeki değerlerin toplamını döndürür:
aggregation(string $function, ?string $groupFunction = null): mixed
Herhangi bir toplama fonksiyonunun yürütülmesine izin verir.
Kendileri bir toplama ve gruplamadan kaynaklanan sonuçları toplamamız gerekiyorsa (örneğin, gruplanmış satırlar
üzerinden SUM(value)
), bu ara sonuçlara uygulanacak toplama işlevini ikinci bağımsız değişken olarak
belirtiriz:
Bu örnekte, önce her kategorideki ürünlerin toplam fiyatını hesaplıyoruz
(SUM(price * stock) AS category_total
) ve sonuçları category_id
'a göre gruplandırıyoruz. Daha sonra
bu alt toplamları toplamak için aggregation('SUM(category_total)', 'SUM')
adresini kullanıyoruz. İkinci
bağımsız değişken 'SUM'
ara sonuçlara uygulanacak toplama işlevini belirtir.
Ekle, Güncelle ve Sil
Nette Database Explorer veri eklemeyi, güncellemeyi ve silmeyi basitleştirir. Bahsedilen tüm yöntemler hata durumunda bir
Nette\Database\DriverException
fırlatır.
Selection::insert(iterable $data): static
Bir tabloya yeni kayıtlar ekler.
Tek bir kayıt ekleniyor:
Yeni kayıt, anahtarların tablodaki sütun adlarıyla eşleştiği bir ilişkisel dizi veya yinelenebilir nesne ( formlarda kullanılan ArrayHash
gibi) olarak aktarılır.
Tablonun tanımlanmış bir birincil anahtarı varsa, yöntem, veritabanı düzeyinde yapılan değişiklikleri (örn.
tetikleyiciler, varsayılan sütun değerleri veya otomatik artırma hesaplamaları) yansıtmak için veritabanından yeniden
yüklenen bir ActiveRow
nesnesi döndürür. Bu, veri tutarlılığını sağlar ve nesne her zaman geçerli
veritabanı verilerini içerir. Birincil anahtar açıkça tanımlanmamışsa, yöntem girdi verilerini bir dizi olarak
döndürür.
Tek seferde birden fazla kayıt ekleme:
insert()
yöntemi, tek bir SQL sorgusu ile birden fazla kayıt eklemenize olanak tanır. Bu durumda, eklenen
satırların sayısını döndürür.
Parametre olarak veri seçimi içeren bir Selection
nesnesi de aktarabilirsiniz.
Özel değerlerin eklenmesi:
Değerler dosyaları, DateTime
nesnelerini veya SQL değişmezlerini içerebilir:
Selection::update(iterable $data): int
Bir tablodaki satırları belirtilen filtreye göre günceller. Gerçekte değiştirilen satır sayısını döndürür.
Güncellenecek sütunlar, anahtarların tablodaki sütun adlarıyla eşleştiği bir ilişkisel dizi veya yinelenebilir nesne (
formlarda kullanılan ArrayHash
gibi) olarak geçirilir:
Sayısal değerleri değiştirmek için +=
ve -=
operatörlerini kullanabilirsiniz:
Selection::delete(): int
Belirtilen filtreye göre bir tablodan satırları siler. Silinen satırların sayısını döndürür.
update()
veya delete()
adreslerini çağırırken, güncellenecek veya silinecek
satırları belirtmek için where()
adresini kullandığınızdan emin olun. where()
kullanılmazsa,
işlem tüm tablo üzerinde gerçekleştirilecektir!
ActiveRow::update(iterable $data): bool
ActiveRow
nesnesi tarafından temsil edilen bir veritabanı satırındaki verileri günceller. Anahtarların
sütun adları olduğu yinelenebilir verileri parametre olarak kabul eder. Sayısal değerleri değiştirmek için +=
ve -=
operatörlerini kullanabilirsiniz:
Güncelleme gerçekleştirildikten sonra, ActiveRow
veritabanı düzeyinde yapılan değişiklikleri (örn.
tetikleyiciler) yansıtmak için veritabanından otomatik olarak yeniden yüklenir. Yöntem, yalnızca gerçek bir veri
değişikliği meydana gelmişse true
döndürür.
Bu yöntem, veritabanında yalnızca belirli bir satırı günceller. Birden fazla satırın toplu güncellemeleri için Selection::update() yöntemini kullanın.
ActiveRow::delete()
Veritabanından ActiveRow
nesnesi tarafından temsil edilen bir satırı siler.
Bu yöntem, veritabanındaki yalnızca belirli bir satırı siler. Birden fazla satırı toplu olarak silmek için Selection::delete() yöntemini kullanın.
Tablolar Arasındaki İlişkiler
İlişkisel veritabanlarında veriler birden fazla tabloya bölünür ve yabancı anahtarlar aracılığıyla birbirine bağlanır. Nette Database Explorer, JOIN sorguları yazmadan veya herhangi bir yapılandırma veya varlık oluşturma gerektirmeden bu ilişkilerle çalışmak için devrim niteliğinde bir yol sunar.
Gösterim için example veritabanını kullanacağız(GitHub'da mevcuttur). Veritabanı aşağıdaki tabloları içerir:
author
– yazarlar ve çevirmenler (id
,name
,web
,born
sütunları)book
– kitaplar (id
,author_id
,translator_id
,title
,sequel_id
sütunları)tag
– etiketler (id
,name
sütunları)book_tag
– kitaplar ve etiketler arasındaki bağlantı tablosu (book_id
,tag_id
sütunları)

Veritabanı yapısı
Bu kitap veritabanı örneğinde, çeşitli ilişki türleri buluyoruz (gerçeğe kıyasla basitleştirilmiş):
- Birden çoğa (1:N)** – Her kitabın bir yazarı vardır; bir yazar birden fazla kitap yazabilir.
- Sıfırdan çoğa (0:N)** – Bir kitabın bir çevirmeni olabilir; bir çevirmen birden fazla kitabı çevirebilir.
- Sıfırdan bire (0:1)** – Bir kitabın bir devam kitabı olabilir.
- Çoktan çoğa (M:N)** – Bir kitap birden fazla etikete sahip olabilir ve bir etiket birden fazla kitaba atanabilir.
Bu ilişkilerde her zaman bir ana tablo ve bir çocuk tablo vardır. Örneğin, yazarlar ve kitaplar arasındaki
ilişkide, author
tablosu üst tablodur ve book
tablosu alt tablodur – bunu her zaman bir yazara
„ait“ bir kitap olarak düşünebilirsiniz. Bu durum veritabanı yapısına da yansır: book
alt tablosu,
author
üst tablosuna referans veren author_id
yabancı anahtarını içerir.
Kitapları yazarlarının adlarıyla birlikte görüntülemek istiyorsak, iki seçeneğimiz vardır. Ya bir JOIN ile tek bir SQL sorgusu kullanarak verileri alırız:
Ya da verileri iki adımda alırız – önce kitapları, sonra yazarlarını – ve bunları PHP'de bir araya getiririz:
İkinci yaklaşım şaşırtıcı bir şekilde daha verimlidir. Veriler yalnızca bir kez getirilir ve önbellekte daha iyi kullanılabilir. Nette Database Explorer tam olarak bu şekilde çalışır – her şeyi kaputun altında halleder ve size temiz bir API sağlar:
Ana Tabloya Erişim
Ana tabloya erişim basittir. Bunlar bir kitabın bir yazarı vardır veya bir kitabın bir çevirmeni
olabilir gibi ilişkilerdir. İlgili kayda ActiveRow
nesne özelliği aracılığıyla erişilebilir –
özellik adı, id
son eki olmadan yabancı anahtarın sütun adıyla eşleşir:
Explorer, $book->author
özelliğine erişirken, book
tablosunda author
dizesini
(yani, author_id
) içeren bir sütun arar. Bu sütundaki değere bağlı olarak, author
tablosundan
ilgili kaydı alır ve bunu bir ActiveRow
nesnesi olarak döndürür. Benzer şekilde
$book->translator
, translator_id
sütununu kullanır. translator_id
sütunu
null
içerebileceğinden ?->
operatörü kullanılır.
Alternatif bir yaklaşım, iki bağımsız değişken (hedef tablonun adı ve bağlantı sütunu) kabul eden ve bir
ActiveRow
örneği veya null
döndüren ref()
yöntemi tarafından sağlanır:
ref()
yöntemi, özellik tabanlı erişimin kullanılamadığı durumlarda, örneğin tabloda özellik ile aynı
ada sahip bir sütun varsa kullanışlıdır (author
). Diğer durumlarda, daha iyi okunabilirlik için özellik
tabanlı erişim kullanılması önerilir.
Explorer veritabanı sorgularını otomatik olarak optimize eder. Kitaplar arasında yineleme yaparken ve ilgili kayıtlarına (yazarlar, çevirmenler) erişirken, Explorer her kitap için ayrı ayrı bir sorgu oluşturmaz. Bunun yerine, her bir ilişki türü için yalnızca bir SELECT sorgusu çalıştırarak veritabanı yükünü önemli ölçüde azaltır. Örneğin:
Bu kod yalnızca üç optimize edilmiş veritabanı sorgusu yürütecektir:
Bağlantı sütununu tanımlama mantığı Conventions uygulaması tarafından tanımlanır. Yabancı anahtarları analiz eden ve mevcut tablo ilişkileriyle sorunsuz bir şekilde çalışmanıza olanak tanıyan DiscoveredConventions'ı kullanmanızı öneririz.
Çocuk Tablosuna Erişim
Alt tabloya erişim ters yönde çalışır. Şimdi bu yazar hangi kitapları yazdı veya bu çevirmen hangi
kitapları çevirdi diye soruyoruz. Bu tür bir sorgu için, ilgili kayıtları içeren bir Selection
nesnesi
döndüren related()
yöntemini kullanırız. İşte bir örnek:
related()
yöntemi, ilişki açıklamasını nokta gösterimini kullanarak tek bir bağımsız değişken olarak
veya iki ayrı bağımsız değişken olarak kabul eder:
Explorer, üst tablonun adına göre doğru bağlantı sütununu otomatik olarak algılayabilir. Bu durumda, kaynak tablonun
adı author
olduğu için book.author_id
sütunu üzerinden bağlantı verir:
Birden fazla olası bağlantı varsa, Explorer bir AmbiguousReferenceKeyException istisnası atacaktır.
Elbette, bir döngü içinde birden fazla kayıt arasında yineleme yaparken related()
yöntemini de
kullanabiliriz ve Explorer bu durumda da sorguları otomatik olarak optimize edecektir:
Bu kod yalnızca iki verimli SQL sorgusu oluşturur:
Çoktan Çoka İlişki
Çoktan çoka (M:N) ilişki için bir birleşim tablosu (bizim durumumuzda book_tag
) gereklidir. Bu tablo
iki yabancı anahtar sütunu içerir (book_id
, tag_id
). Her sütun, bağlı tablolardan birinin birincil
anahtarına referans verir. İlgili verileri almak için, önce related('book_tag')
adresini kullanarak bağlantı
tablosundan kayıtları getiriyoruz ve ardından hedef verilere devam ediyoruz:
Explorer SQL sorgularını tekrar verimli bir forma optimize eder:
İlgili Tablolar Üzerinden Sorgulama
where()
, select()
, order()
ve group()
yöntemlerinde, diğer tablolardan
sütunlara erişmek için özel gösterimler kullanabilirsiniz. Explorer gerekli JOIN'leri otomatik olarak oluşturur.
Ana tablonun perspektifinden bakıldığında 1:N ilişkiler için Nokta gösterimi (parent_table.column
)
kullanılır:
Üst tablo açısından 1:N ilişkiler için Kolon gösterimi kullanılır:
Yukarıdaki iki nokta üst üste gösterimli örnekte (:book.title
), yabancı anahtar sütunu açıkça
belirtilmemiştir. Explorer, üst tablo adına göre doğru sütunu otomatik olarak algılar. Bu durumda, kaynak tablonun adı
author
olduğu için book.author_id
sütunu üzerinden birleşir. Birden fazla olası bağlantı varsa,
Explorer AmbiguousReferenceKeyException
istisnasını atar.
Bağlantı sütunu parantez içinde açıkça belirtilebilir:
Birden fazla tablodaki verilere erişmek için gösterimler zincirlenebilir:
JOIN için Genişletme Koşulları
joinWhere()
yöntemi, SQL'deki tablo birleştirmelerine ON
anahtar sözcüğünden sonra ek
koşullar ekler.
Örneğin, belirli bir çevirmen tarafından çevrilmiş kitapları bulmak istediğimizi varsayalım:
joinWhere()
koşulunda, where()
yönteminde olduğu gibi aynı yapıları kullanabilirsiniz –
operatörler, yer tutucular, değer dizileri veya SQL ifadeleri.
Birden fazla JOIN içeren daha karmaşık sorgular için tablo takma adları tanımlanabilir:
where()
yöntemi WHERE
cümlesine koşullar eklerken, joinWhere()
yönteminin tablo
birleştirmeleri sırasında ON
cümlesindeki koşulları genişlettiğini unutmayın.