Nette Database
**************
.[perex]
Nette Database, basitliğe ve akıllı özelliklere odaklanan güçlü ve şık bir PHP veritabanı katmanıdır. Veritabanınızla çalışmanın iki yolunu sunar: hızlı uygulama geliştirme için [Explorer |explorer] ya da sorguları doğrudan yönetmek için [SQL yolu |SQL way].
<div class="grid gap-3">
<div>
[SQL yolu|sql-way]
==================
- Güvenli, parametreli sorgular
- SQL sorgusunun yapısı üzerinde tam denetim
- Gelişmiş fonksiyonlarla karmaşık sorgular yazarken
- Belirli SQL fonksiyonlarıyla başarımı iyileştirme
</div>
<div>
[Explorer |explorer]
====================
- SQL yazmadan hızlı geliştirme
- Tablolar arası ilişkilerin sezgisel yönetimi
- Otomatik sorgu iyileştirmesinden yararlanma
- Hızlı ve rahat veritabanı çalışması için uygun
</div>
</div>
Kurulum
=======
Kütüphaneyi [Composer|best-practices:composer] ile indirip kurun:
```shell
composer require nette/database
```
Desteklenen Veritabanları
=========================
Nette Database şu veritabanlarını destekler:
|* Veritabanı sunucusu |* DSN adı |* Explorer desteği
|-----------------------|--------------|-----------------------|
| MySQL (>= 5.1) | mysql | EVET |
| PostgreSQL (>= 9.0) | pgsql | EVET |
| SQLite 3 (>= 3.8) | sqlite | EVET |
| Oracle | oci | HAYIR |
| MS SQL (PDO_SQLSRV) | sqlsrv | EVET |
| MS SQL (PDO_DBLIB) | mssql | HAYIR |
| ODBC | odbc | HAYIR |
Veritabanı Çalışmasına İki Yaklaşım
===================================
Nette Database size bir seçim sunar: SQL sorgularını ya doğrudan yazarsınız (SQL yolu) ya da otomatik üretilmelerini sağlarsınız (Explorer). İki yaklaşımın aynı işleri nasıl yaptığına bakalım:
[SQL yolu|sql-way] - SQL sorguları
```php
// Kayıt ekleme
$database->query('INSERT INTO books', [
'author_id' => $authorId,
'title' => $bookData->title,
'published_at' => new DateTime,
]);
// Kayıtları alma: kitap yazarları
$result = $database->query('
SELECT authors.*, COUNT(books.id) AS books_count
FROM authors
LEFT JOIN books ON authors.id = books.author_id
WHERE authors.active = 1
GROUP BY authors.id
');
// Gösterim (ideal değil, N ek sorgu üretir)
foreach ($result as $author) {
$books = $database->query('
SELECT * FROM books
WHERE author_id = ?
ORDER BY published_at DESC
', $author->id);
echo "$author->name adlı yazar $author->books_count kitap yazmış:\n";
foreach ($books as $book) {
echo "- $book->title\n";
}
}
```
[Explorer yolu|explorer] - otomatik SQL üretimi
```php
// Kayıt ekleme
$database->table('books')->insert([
'author_id' => $authorId,
'title' => $bookData->title,
'published_at' => new DateTime,
]);
// Kayıtları alma: kitap yazarları
$authors = $database->table('authors')
->where('active', 1);
// Gösterim (otomatik olarak yalnızca 2 iyileştirilmiş sorgu üretir)
foreach ($authors as $author) {
$books = $author->related('books')
->order('published_at DESC');
echo "$author->name adlı yazar {$books->count()} kitap yazmış:\n";
foreach ($books as $book) {
echo "- $book->title\n";
}
}
```
Explorer yaklaşımı SQL sorgularını otomatik üretir ve iyileştirir. Yukarıdaki örnekte SQL yolu N+1 sorgu üretir (biri yazarlar için, sonra her yazarın kitapları için birer tane), Explorer ise sorguları otomatik iyileştirip yalnızca iki sorgu çalıştırır: biri yazarlar, biri de onların tüm kitapları için.
İki yaklaşım uygulamanızda ihtiyaca göre serbestçe birleştirilebilir.
Bağlantı ve Yapılandırma
========================
Veritabanına bağlanmak için yalnızca [api:Nette\Database\Connection] sınıfından bir örnek oluşturun:
```php
$database = new Nette\Database\Connection($dsn, $user, $password);
```
`$dsn` (Data Source Name) parametresi, [PDO'nun kullandığıyla |https://www.php.net/manual/en/pdo.construct.php#refsect1-pdo.construct-parameters] aynıdır, örneğin `host=127.0.0.1;dbname=test`. Başarısızlık durumunda `Nette\Database\ConnectionException` fırlatır.
Ancak daha elverişli bir yöntemi, yalnızca bir `database` bölümü eklemeniz yeten [uygulama yapılandırması |configuration] sunar. Bu, gereken nesneleri ve ayrıca [Tracy |tracy:] çubuğunda bir veritabanı paneli oluşturur.
```neon
database:
dsn: 'mysql:host=127.0.0.1;dbname=test'
user: root
password: password
```
Bağlantı nesnesi sonra [DI container'dan servis olarak alınabilir |dependency-injection:passing-dependencies], örneğin:
```php
class Model
{
public function __construct(
// ya da Nette\Database\Explorer
private Nette\Database\Connection $database,
) {
}
}
```
[Veritabanı yapılandırması|configuration] hakkında daha fazla bilgi.
Explorer'ı Elle Oluşturma
-------------------------
Nette DI container kullanmıyorsanız, `Nette\Database\Explorer` örneğini elle oluşturabilirsiniz:
```php
// veritabanı bağlantısı
$connection = new Nette\Database\Connection('mysql:host=127.0.0.1;dbname=mydatabase', 'user', 'password');
// önbellek deposu, Nette\Caching\Storage arayüzünü uygular, örneğin:
$storage = new Nette\Caching\Storages\FileStorage('/path/to/temp/dir');
// veritabanı yapısının reflection'ını üstlenir
$structure = new Nette\Database\Structure($connection, $storage);
// tablo adlarının, sütunların ve yabancı anahtarların eşlenme kurallarını tanımlar
$conventions = new Nette\Database\Conventions\DiscoveredConventions($structure);
$explorer = new Nette\Database\Explorer($connection, $structure, $conventions, $storage);
```
Bağlantı Yönetimi
=================
Bir `Connection` nesnesi oluşturulduğunda bağlantı otomatik olarak kurulur. Bağlantıyı geciktirmek istiyorsanız tembel kipi kullanın; onu [yapılandırmada|configuration] `lazy` ayarıyla ya da şöyle açın:
```php
$database = new Nette\Database\Connection($dsn, $user, $password, ['lazy' => true]);
```
Bağlantıyı yönetmek için `connect()`, `disconnect()` ve `reconnect()` metotlarını kullanın.
- `connect()`, henüz yoksa bir bağlantı kurar ve `Nette\Database\ConnectionException` fırlatabilir.
- `disconnect()`, geçerli veritabanı bağlantısını keser.
- `reconnect()`, bağlantıyı kesip veritabanına yeniden bağlanır. Bu metot da `Nette\Database\ConnectionException` fırlatabilir.
Ayrıca bağlantıyla ilgili olayları, veritabanı bağlantısı kurulduktan sonra çağrılan callback'lerden oluşan bir dizi olan `onConnect` olayıyla izleyebilirsiniz.
```php
// veritabanına bağlandıktan sonra çalışır
$database->onConnect[] = function($database) {
echo "Connected to the database";
};
```
`onQuery` olayı da benzer biçimde çalışır; çalıştırılan her sorgudan sonra (ve bir sorgu başarısız olduğunda) çağrılan callback'lerden oluşan bir dizidir ve günlükleme ya da profilleme için yararlıdır.
Tracy Debug Bar
===============
[Tracy |tracy:] kullanıyorsanız, Debug Bar'daki Database paneli otomatik olarak etkinleşir. Çalıştırılan tüm sorguları, parametrelerini, çalışma sürelerini ve koddaki çağrıldıkları yeri gösterir.
[* db-panel.webp *]
Nette Database
Nette Database, basitliğe ve akıllı özelliklere odaklanan güçlü ve şık bir PHP veritabanı katmanıdır.
Veritabanınızla çalışmanın iki yolunu sunar: hızlı uygulama geliştirme için Explorer ya da sorguları doğrudan yönetmek için SQL yolu.
Nette Database size bir seçim sunar: SQL sorgularını ya doğrudan yazarsınız (SQL yolu) ya da otomatik üretilmelerini
sağlarsınız (Explorer). İki yaklaşımın aynı işleri nasıl yaptığına bakalım:
// Kayıt ekleme
$database->query('INSERT INTO books', [
'author_id' => $authorId,
'title' => $bookData->title,
'published_at' => new DateTime,
]);
// Kayıtları alma: kitap yazarları
$result = $database->query('
SELECT authors.*, COUNT(books.id) AS books_count
FROM authors
LEFT JOIN books ON authors.id = books.author_id
WHERE authors.active = 1
GROUP BY authors.id
');
// Gösterim (ideal değil, N ek sorgu üretir)
foreach ($result as $author) {
$books = $database->query('
SELECT * FROM books
WHERE author_id = ?
ORDER BY published_at DESC
', $author->id);
echo "$author->name adlı yazar $author->books_count kitap yazmış:\n";
foreach ($books as $book) {
echo "- $book->title\n";
}
}
// Kayıt ekleme
$database->table('books')->insert([
'author_id' => $authorId,
'title' => $bookData->title,
'published_at' => new DateTime,
]);
// Kayıtları alma: kitap yazarları
$authors = $database->table('authors')
->where('active', 1);
// Gösterim (otomatik olarak yalnızca 2 iyileştirilmiş sorgu üretir)
foreach ($authors as $author) {
$books = $author->related('books')
->order('published_at DESC');
echo "$author->name adlı yazar {$books->count()} kitap yazmış:\n";
foreach ($books as $book) {
echo "- $book->title\n";
}
}
Explorer yaklaşımı SQL sorgularını otomatik üretir ve iyileştirir. Yukarıdaki örnekte SQL yolu N+1 sorgu üretir
(biri yazarlar için, sonra her yazarın kitapları için birer tane), Explorer ise sorguları otomatik iyileştirip yalnızca iki
sorgu çalıştırır: biri yazarlar, biri de onların tüm kitapları için.
İki yaklaşım uygulamanızda ihtiyaca göre serbestçe birleştirilebilir.
$database = new Nette\Database\Connection($dsn, $user, $password);
$dsn (Data Source Name) parametresi, PDO'nun kullandığıyla aynıdır,
örneğin host=127.0.0.1;dbname=test. Başarısızlık durumunda Nette\Database\ConnectionException
fırlatır.
Ancak daha elverişli bir yöntemi, yalnızca bir database bölümü eklemeniz yeten uygulama yapılandırması sunar. Bu, gereken nesneleri ve ayrıca Tracy çubuğunda bir veritabanı paneli oluşturur.
Nette DI container kullanmıyorsanız, Nette\Database\Explorer örneğini elle oluşturabilirsiniz:
// veritabanı bağlantısı
$connection = new Nette\Database\Connection('mysql:host=127.0.0.1;dbname=mydatabase', 'user', 'password');
// önbellek deposu, Nette\Caching\Storage arayüzünü uygular, örneğin:
$storage = new Nette\Caching\Storages\FileStorage('/path/to/temp/dir');
// veritabanı yapısının reflection'ını üstlenir
$structure = new Nette\Database\Structure($connection, $storage);
// tablo adlarının, sütunların ve yabancı anahtarların eşlenme kurallarını tanımlar
$conventions = new Nette\Database\Conventions\DiscoveredConventions($structure);
$explorer = new Nette\Database\Explorer($connection, $structure, $conventions, $storage);
Bağlantı Yönetimi
Bir Connection nesnesi oluşturulduğunda bağlantı otomatik olarak kurulur. Bağlantıyı geciktirmek
istiyorsanız tembel kipi kullanın; onu yapılandırmadalazy ayarıyla ya da şöyle açın:
$database = new Nette\Database\Connection($dsn, $user, $password, ['lazy' => true]);
Bağlantıyı yönetmek için connect(), disconnect() ve reconnect() metotlarını
kullanın.
connect(), henüz yoksa bir bağlantı kurar ve Nette\Database\ConnectionException
fırlatabilir.
disconnect(), geçerli veritabanı bağlantısını keser.
reconnect(), bağlantıyı kesip veritabanına yeniden bağlanır. Bu metot da
Nette\Database\ConnectionException fırlatabilir.
Ayrıca bağlantıyla ilgili olayları, veritabanı bağlantısı kurulduktan sonra çağrılan callback'lerden oluşan bir
dizi olan onConnect olayıyla izleyebilirsiniz.
// veritabanına bağlandıktan sonra çalışır
$database->onConnect[] = function($database) {
echo "Connected to the database";
};
onQuery olayı da benzer biçimde çalışır; çalıştırılan her sorgudan sonra (ve bir sorgu başarısız
olduğunda) çağrılan callback'lerden oluşan bir dizidir ve günlükleme ya da profilleme için yararlıdır.
Tracy Debug Bar
Tracy kullanıyorsanız, Debug Bar'daki Database paneli otomatik olarak etkinleşir.
Çalıştırılan tüm sorguları, parametrelerini, çalışma sürelerini ve koddaki çağrıldıkları yeri gösterir.