Εξερεύνηση βάσης δεδομένων
Με τη βάση δεδομένων Nette, μπορείτε να εργαστείτε με δύο τρόπους: είτε να αφήσετε τα ερωτήματα SQL να δημιουργηθούν αυτόματα (προσέγγιση Explorer) είτε να τα γράψετε μόνοι σας(άμεση πρόσβαση). Ο Εξερευνητής απλοποιεί σημαντικά την πρόσβαση στα δεδομένα. Χειρίζεται τις σχέσεις μεταξύ των πινάκων, ώστε να μπορείτε να επικεντρωθείτε στη λογική της εφαρμογής σας.
- Η εργασία με τα δεδομένα είναι φυσική και εύκολα κατανοητή
- Δημιουργεί βελτιστοποιημένα ερωτήματα SQL που αντλούν μόνο τα απαραίτητα δεδομένα
- Παρέχει εύκολη πρόσβαση σε συναφή δεδομένα χωρίς την ανάγκη συγγραφής ερωτημάτων JOIN
- Λειτουργεί άμεσα χωρίς καμία διαμόρφωση ή δημιουργία οντοτήτων
Η εργασία με την Εξερεύνηση ξεκινά με την κλήση της μεθόδου table() στο αντικείμενο Nette\Database\Explorer (για πληροφορίες σχετικά με τη δημιουργία συνδέσεων και τη διαμόρφωση, ανατρέξτε στην ειδική σελίδα):
$books = $explorer->table('book'); // 'book' είναι το όνομα του πίνακα
Η μέθοδος επιστρέφει ένα αντικείμενο Selection, το οποίο
αναπαριστά ένα ερώτημα SQL. Πρόσθετες μέθοδοι μπορούν να συνδεθούν
αλυσιδωτά με αυτό το αντικείμενο για το φιλτράρισμα και την ταξινόμηση
των αποτελεσμάτων. Το ερώτημα συναρμολογείται και εκτελείται μόνο
όταν ζητούνται τα δεδομένα, για παράδειγμα, με επανάληψη με το
foreach
. Κάθε γραμμή αντιπροσωπεύεται από ένα αντικείμενο ActiveRow:
foreach ($books as $book) {
echo $book->title; // εξάγει τη στήλη 'title'
echo $book->author_id; // εξάγει τη στήλη 'author_id
}
Η Εξερεύνηση απλοποιεί σημαντικά την εργασία με τις σχέσεις πινάκων. Το ακόλουθο παράδειγμα δείχνει πόσο εύκολα μπορούμε να εξάγουμε δεδομένα από σχετικούς πίνακες (βιβλία και οι συγγραφείς τους). Παρατηρήστε ότι δεν χρειάζεται να γράψετε κανένα ερώτημα JOIN- η Nette τα παράγει για εμάς:
$books = $explorer->table('book');
foreach ($books as $book) {
echo 'Book: ' . $book->title;
echo 'Author: ' . $book->author->name; // δημιουργεί ένα JOIN στον πίνακα 'author'
}
Η Nette Database Explorer βελτιστοποιεί τα ερωτήματα για μέγιστη αποδοτικότητα. Το παραπάνω παράδειγμα εκτελεί μόνο δύο ερωτήματα SELECT, ανεξάρτητα από το αν επεξεργαζόμαστε 10 ή 10.000 βιβλία.
Επιπλέον, ο Explorer παρακολουθεί ποιες στήλες χρησιμοποιούνται στον κώδικα και αντλεί μόνο αυτές από τη βάση δεδομένων, εξοικονομώντας περαιτέρω απόδοση. Αυτή η συμπεριφορά είναι πλήρως αυτόματη και προσαρμοστική. Αν αργότερα τροποποιήσετε τον κώδικα για να χρησιμοποιήσετε επιπλέον στήλες, ο Explorer προσαρμόζει αυτόματα τα ερωτήματα. Δεν χρειάζεται να ρυθμίσετε τίποτα ή να σκεφτείτε ποιες στήλες θα χρειαστούν – αφήστε το στη Nette.
Φιλτράρισμα και ταξινόμηση
Η κλάση Selection
παρέχει μεθόδους φιλτραρίσματος και ταξινόμησης
δεδομένων.
where($condition, ...$params) |
Προσθέτει μια συνθήκη WHERE. Οι πολλαπλές συνθήκες συνδυάζονται με τη χρήση AND |
whereOr(array $conditions) |
Προσθέτει μια ομάδα συνθηκών WHERE που συνδυάζονται με τη χρήση OR |
wherePrimary($value) |
Προσθέτει μια συνθήκη WHERE με βάση το πρωτεύον κλειδί |
order($columns, ...$params) |
Ορίζει ταξινόμηση με ORDER BY |
select($columns, ...$params) |
Καθορίζει ποιες στήλες θα αντληθούν |
limit($limit, $offset = null) |
Περιορίζει τον αριθμό των γραμμών (LIMIT) και προαιρετικά ορίζει OFFSET |
page($page, $itemsPerPage, &$total = null) |
Ορίζει σελιδοποίηση |
group($columns, ...$params) |
Ομαδοποιεί σειρές (GROUP BY) |
having($condition, ...$params) |
Προσθέτει μια συνθήκη HAVING για το φιλτράρισμα των ομαδοποιημένων γραμμών |
Οι μέθοδοι μπορούν να αλυσιδωθούν (η λεγόμενη ρευστή
διεπαφή): $table->where(...)->order(...)->limit(...)
.
Αυτές οι μέθοδοι επιτρέπουν επίσης τη χρήση ειδικών συμβολισμών για την πρόσβαση σε δεδομένα από σχετικούς πίνακες.
Διαφυγή και αναγνωριστικά
Οι μέθοδοι αποφεύγουν αυτόματα τις παραμέτρους και τα αναγνωριστικά παραθέματος (ονόματα πινάκων και στηλών), αποτρέποντας την έγχυση SQL. Για να διασφαλιστεί η σωστή λειτουργία, πρέπει να τηρούνται μερικοί κανόνες:
- Γράψτε λέξεις-κλειδιά, ονόματα συναρτήσεων, διαδικασίες, κ.λπ., σε uppercase.
- Γράψτε τα ονόματα στηλών και πινάκων με μικρά γράμματα.
- Πάντα να περνάτε συμβολοσειρές χρησιμοποιώντας παραμέτρους.
where('name = ' . $name); // **DISASTER**: ευάλωτο σε έγχυση SQL
where('name LIKE "%search%"'); // **WRONG**: περιπλέκει την αυτόματη αναγραφή εισαγωγικών
where('name LIKE ?', '%search%'); // **ΣΩΣΤΟ**: τιμή που περνάει ως παράμετρος
where('name like ?', $name); // **WRONG**: παράγει: `name` `like` ?
where('name LIKE ?', $name); // **ΣΩΣΤΟ**: παράγει: `name` LIKE ?
where('LOWER(name) = ?', $value);// **ΣΩΣΤΟ**: LOWER(`όνομα`) = ?
where (string|array $condition, …$parameters): static
Φιλτράρει τα αποτελέσματα χρησιμοποιώντας συνθήκες WHERE. Η δύναμή του έγκειται στον έξυπνο χειρισμό διαφόρων τύπων τιμών και στην αυτόματη επιλογή τελεστών SQL.
Βασική χρήση:
$table->where('id', $value); // WHERE `id` = 123
$table->where('id > ?', $value); // WHERE `id` > 123
$table->where('id = ? OR name = ?', $id, $name); // WHERE `id` = 1 OR `name` = 'Jon Snow'
Χάρη στην αυτόματη ανίχνευση των κατάλληλων χειριστών, δεν χρειάζεται να χειρίζεστε ειδικές περιπτώσεις – η Nette τις χειρίζεται για εσάς:
$table->where('id', 1); // WHERE `id` = 1
$table->where('id', null); // WHERE `id` IS NULL
$table->where('id', [1, 2, 3]); // WHERE `id` IN (1, 2, 3)
// Το σύμβολο θέσης ? μπορεί να χρησιμοποιηθεί χωρίς τελεστή:
$table->where('id ?', 1); // WHERE `id` = 1
Η μέθοδος χειρίζεται επίσης σωστά τις αρνητικές συνθήκες και τους άδειους πίνακες:
$table->where('id', []); // WHERE `id` IS NULL AND FALSE -- δεν βρίσκει τίποτα
$table->where('id NOT', []); // WHERE `id` IS NULL OR TRUE -- βρίσκει τα πάντα
$table->where('NOT (id ?)', []); // WHERE NOT (`id` IS NULL AND FALSE) -- βρίσκει τα πάντα
// $table->where('NOT id ?', $ids); // ΠΡΟΕΙΔΟΠΟΙΗΣΗ: Αυτή η σύνταξη δεν υποστηρίζεται
Μπορείτε επίσης να περάσετε το αποτέλεσμα ενός άλλου ερωτήματος πίνακα ως παράμετρο, δημιουργώντας ένα υποερώτημα:
// WHERE `id` IN (SELECT `id` FROM `tableName`)
$table->where('id', $explorer->table($tableName));
// WHERE `id` IN (SELECT `col` FROM `tableName`)
$table->where('id', $explorer->table($tableName)->select('col'));
Οι συνθήκες μπορούν επίσης να περάσουν ως πίνακας, με τα στοιχεία να συνδυάζονται με τη χρήση AND:
// WHERE (`price_final` < `price_original`) AND (`stock_count` > `min_stock`)
$table->where([
'price_final < price_original',
'stock_count > min_stock',
]);
Στον πίνακα μπορούν να χρησιμοποιηθούν ζεύγη κλειδιών-τιμών και η Nette θα επιλέξει και πάλι αυτόματα τους σωστούς τελεστές:
// WHERE (`status` = 'active') AND (`id` IN (1, 2, 3))
$table->where([
'status' => 'active',
'id' => [1, 2, 3],
]);
Μπορούμε επίσης να αναμειγνύουμε εκφράσεις SQL με placeholders και πολλαπλές παραμέτρους. Αυτό είναι χρήσιμο για σύνθετες συνθήκες με επακριβώς καθορισμένους τελεστές:
// WHERE (`ηλικία` > 18) AND (ROUND(`score`, 2) > 75.5)
$table->where([
'age > ?' => 18,
'ROUND(score, ?) > ?' => [2, 75.5], // Δύο παράμετροι περνούν ως πίνακας
]);
Πολλαπλές κλήσεις στο where()
συνδυάζουν αυτόματα τις συνθήκες
με τη χρήση AND.
whereOr (array $parameters): static
Παρόμοιο με το where()
, αλλά συνδυάζει τις συνθήκες
χρησιμοποιώντας OR:
// WHERE (`status` = 'active') OR (`deleted` = 1)
$table->whereOr([
'status' => 'active',
'deleted' => true,
]);
Μπορούν επίσης να χρησιμοποιηθούν πιο σύνθετες εκφράσεις:
// WHERE (`price` > 1000) OR (`price_with_tax` > 1500)
$table->whereOr([
'price > ?' => 1000,
'price_with_tax > ?' => 1500,
]);
wherePrimary (mixed $key): static
Προσθέτει μια συνθήκη για το πρωτεύον κλειδί του πίνακα:
// WHERE `id` = 123
$table->wherePrimary(123);
// WHERE `id` IN (1, 2, 3)
$table->wherePrimary([1, 2, 3]);
(π.χ. foo_id
, bar_id
), το περνάμε ως πίνακα:
// WHERE `foo_id` = 1 AND `bar_id` = 5
$table->wherePrimary(['foo_id' => 1, 'bar_id' => 5])->fetch();
// WHERE (`foo_id`, `bar_id`) IN ((1, 5), (2, 3))
$table->wherePrimary([
['foo_id' => 1, 'bar_id' => 5],
['foo_id' => 2, 'bar_id' => 3],
])->fetchAll();
order (string $columns, …$parameters): static
Καθορίζει τη σειρά με την οποία επιστρέφονται οι γραμμές. Μπορείτε να ταξινομήσετε με βάση μία ή περισσότερες στήλες, με αύξουσα ή φθίνουσα σειρά ή με βάση μια προσαρμοσμένη έκφραση:
$table->order('created'); // ORDER BY `δημιουργήθηκε`
$table->order('created DESC'); // ORDER BY `created` DESC
$table->order('priority DESC, created'); // ORDER BY `priority` DESC, `created`
$table->order('status = ? DESC', 'active'); // ORDER BY `status` = 'active' DESC
select (string $columns, …$parameters): static
Καθορίζει τις στήλες που θα επιστραφούν από τη βάση δεδομένων. Από
προεπιλογή, η Nette Database Explorer επιστρέφει μόνο τις στήλες που
χρησιμοποιούνται πραγματικά στον κώδικα. Χρησιμοποιήστε τη μέθοδο
select()
όταν πρέπει να ανακτήσετε συγκεκριμένες εκφράσεις:
// SELECT *, DATE_FORMAT(`created_at`, "%d.%m.%Y") AS `formatted_date`
$table->select('*, DATE_FORMAT(created_at, ?) AS formatted_date', '%d.%m.%Y');
Τα ψευδώνυμα που ορίζονται με τη χρήση του AS
είναι στη
συνέχεια προσβάσιμα ως ιδιότητες του αντικειμένου ActiveRow
:
foreach ($table as $row) {
echo $row->formatted_date; // πρόσβαση στο ψευδώνυμο
}
limit (?int $limit, ?int $offset = null): static
Περιορίζει τον αριθμό των επιστρεφόμενων γραμμών (LIMIT) και προαιρετικά ορίζει μια μετατόπιση:
$table->limit(10); // LIMIT 10 (επιστρέφει τις πρώτες 10 γραμμές)
$table->limit(10, 20); // LIMIT 10 OFFSET 20
Για σελιδοποίηση, είναι καταλληλότερο να χρησιμοποιείτε τη μέθοδο
page()
.
page (int $page, int $itemsPerPage, &$numOfPages = null): static
Απλοποιεί την σελιδοποίηση των αποτελεσμάτων. Δέχεται τον αριθμό σελίδας (ξεκινώντας από το 1) και τον αριθμό των στοιχείων ανά σελίδα. Προαιρετικά, μπορείτε να περάσετε μια αναφορά σε μια μεταβλητή όπου θα αποθηκευτεί ο συνολικός αριθμός σελίδων:
$numOfPages = null;
$table->page(page: 3, itemsPerPage: 10, $numOfPages);
echo "Total pages: $numOfPages";
group (string $columns, …$parameters): static
Ομαδοποιεί τις γραμμές με βάση τις καθορισμένες στήλες (GROUP BY). Χρησιμοποιείται συνήθως σε συνδυασμό με συναρτήσεις συνάθροισης:
// Μετρά τον αριθμό των προϊόντων σε κάθε κατηγορία
$table->select('category_id, COUNT(*) AS count')
->group('category_id');
having (string $having, …$parameters): static
Ορίζει μια συνθήκη για το φιλτράρισμα ομαδοποιημένων γραμμών (HAVING).
Μπορεί να χρησιμοποιηθεί σε συνδυασμό με τη μέθοδο group()
και τις
συναρτήσεις συνάθροισης:
// Βρίσκει κατηγορίες με περισσότερα από 100 προϊόντα
$table->select('category_id, COUNT(*) AS count')
->group('category_id')
->having('count > ?', 100);
Ανάγνωση δεδομένων
Για την ανάγνωση δεδομένων από τη βάση δεδομένων, υπάρχουν αρκετές χρήσιμες μέθοδοι:
foreach ($table as $key => $row) |
Επαναλαμβάνει όλες τις γραμμές, $key είναι η τιμή του
πρωτεύοντος κλειδιού, $row είναι ένα αντικείμενο ActiveRow |
$row = $table->get($key) |
Επιστρέφει μία μόνο γραμμή με βάση το πρωτεύον κλειδί |
$row = $table->fetch() |
Επιστρέφει την τρέχουσα γραμμή και προωθεί τον δείκτη στην επόμενη |
$array = $table->fetchPairs() |
Δημιουργεί έναν συσχετιστικό πίνακα από τα αποτελέσματα |
$array = $table->fetchAll() |
Επιστρέφει όλες τις γραμμές ως πίνακα |
count($table) |
Επιστρέφει τον αριθμό των γραμμών στο αντικείμενο Selection |
Το αντικείμενο ActiveRow είναι μόνο για ανάγνωση. Αυτό σημαίνει ότι δεν μπορείτε να αλλάξετε τις τιμές των ιδιοτήτων του. Αυτός ο περιορισμός διασφαλίζει τη συνοχή των δεδομένων και αποτρέπει απροσδόκητες παρενέργειες. Τα δεδομένα αντλούνται από τη βάση δεδομένων και οποιεσδήποτε αλλαγές θα πρέπει να γίνονται ρητά και με ελεγχόμενο τρόπο.
foreach
– Επανάληψη όλων των σειρών
Ο ευκολότερος τρόπος εκτέλεσης ενός ερωτήματος και ανάκτησης
γραμμών είναι η επανάληψη με τον βρόχο foreach
. Εκτελεί αυτόματα το
ερώτημα SQL.
$books = $explorer->table('book');
foreach ($books as $key => $book) {
// $key = πρωτεύον κλειδί, $book = ActiveRow
echo "$book->title ({$book->author->name})";
}
get ($key): ?ActiveRow
Εκτελεί ένα ερώτημα SQL και επιστρέφει μια γραμμή με βάση το πρωτεύον
κλειδί της ή το null
εάν δεν υπάρχει.
$book = $explorer->table('book')->get(123); // επιστρέφει ActiveRow με ID 123 ή null
if ($book) {
echo $book->title;
}
fetch(): ?ActiveRow
Επιστρέφει μια γραμμή και προωθεί τον εσωτερικό δείκτη στην επόμενη.
Εάν δεν υπάρχουν άλλες γραμμές, επιστρέφει null
.
$books = $explorer->table('book');
while ($book = $books->fetch()) {
$this->processBook($book);
}
fetchPairs (string|int|null $key = null, string|int|null $value = null): array
Επιστρέφει τα αποτελέσματα ως συσχετιστικό πίνακα. Το πρώτο όρισμα καθορίζει το όνομα της στήλης που θα χρησιμοποιηθεί ως κλειδί του πίνακα και το δεύτερο όρισμα καθορίζει το όνομα της στήλης που θα χρησιμοποιηθεί ως τιμή:
$authors = $explorer->table('author')->fetchPairs('id', 'name');
// [1 => 'John Doe', 2 => 'Jane Doe', ...]
Εάν παρέχεται μόνο η πρώτη παράμετρος, ολόκληρη η σειρά θα
χρησιμοποιηθεί ως τιμή, η οποία αναπαρίσταται ως αντικείμενο
ActiveRow
:
$authors = $explorer->table('author')->fetchPairs('id');
// [1 => ActiveRow(id: 1, ...), 2 => ActiveRow(id: 2, ...), ...]
Εάν το null
παρέχεται ως κλειδί, ο πίνακας θα έχει αριθμητική
ευρετηρίαση ξεκινώντας από το μηδέν:
$authors = $explorer->table('author')->fetchPairs(null, 'name');
// [0 => 'John Doe', 1 => 'Jane Doe', ...]
fetchPairs (Closure $callback): array
Εναλλακτικά, μπορείτε να περάσετε ένα callback ως παράμετρο. Το callback θα εφαρμοστεί σε κάθε γραμμή για να επιστρέψει είτε μια απλή τιμή είτε ένα ζεύγος κλειδιού-τιμής.
$titles = $explorer->table('book')
->fetchPairs(fn($row) => "$row->title ({$row->author->name})");
// [1 => 'Πρώτο βιβλίο (Jan Novak)', ...]
// Το callback μπορεί επίσης να επιστρέψει έναν πίνακα που περιέχει ένα ζεύγος κλειδιών-τιμών:
$titles = $explorer->table('book')
->fetchPairs(fn($row) => [$row->title, $row->author->name]);
// ['First Book' => 'Jan Novak', ...]
fetchAll(): array
Επιστρέφει όλες τις γραμμές ως συσχετιστικό πίνακα αντικειμένων
ActiveRow
, όπου τα κλειδιά είναι οι τιμές του πρωτεύοντος
κλειδιού.
$allBooks = $explorer->table('book')->fetchAll();
// [1 => ActiveRow(id: 1, ...), 2 => ActiveRow(id: 2, ...), ...]
count(): int
Η μέθοδος count()
χωρίς παραμέτρους επιστρέφει τον αριθμό των
γραμμών στο αντικείμενο Selection
:
$table->where('category', 1);
$count = $table->count();
$count = count($table); // εναλλακτική λύση
Σημείωση: Η μέθοδος count()
με μια παράμετρο εκτελεί τη
λειτουργία συνάθροισης COUNT στη βάση δεδομένων, όπως περιγράφεται
παρακάτω.
ActiveRow::toArray(): array
Μετατρέπει το αντικείμενο ActiveRow
σε συσχετιστικό πίνακα όπου
τα κλειδιά είναι ονόματα στηλών και οι τιμές είναι τα αντίστοιχα
δεδομένα.
$book = $explorer->table('book')->get(1);
$bookArray = $book->toArray();
// Το $bookArray θα είναι ['id' => 1, 'title' => '...', 'author_id' => ..., ...]
Συγκέντρωση
Η κλάση Selection
παρέχει μεθόδους για την εύκολη εκτέλεση
συναρτήσεων άθροισης (COUNT, SUM, MIN, MAX, AVG, κ.λπ.).
count($expr) |
Μετράει τον αριθμό των γραμμών |
min($expr) |
Επιστρέφει την ελάχιστη τιμή σε μια στήλη |
max($expr) |
Επιστρέφει τη μέγιστη τιμή σε μια στήλη |
sum($expr) |
Επιστρέφει το άθροισμα των τιμών σε μια στήλη |
aggregation($function) |
Επιτρέπει οποιαδήποτε συνάρτηση άθροισης, όπως AVG()
ή GROUP_CONCAT() |
count (string $expr): int
Εκτελεί ένα ερώτημα SQL με τη συνάρτηση COUNT και επιστρέφει το αποτέλεσμα. Αυτή η μέθοδος χρησιμοποιείται για να προσδιοριστεί πόσες γραμμές αντιστοιχούν σε μια συγκεκριμένη συνθήκη:
$count = $table->count('*'); // SELECT COUNT(*) FROM `table`
$count = $table->count('DISTINCT column'); // SELECT COUNT(DISTINCT `column`) FROM `table`
Σημείωση: η count() χωρίς παράμετρο επιστρέφει απλώς τον
αριθμό των γραμμών στο αντικείμενο Selection
.
min (string $expr) and max(string $expr)
Οι μέθοδοι min()
και max()
επιστρέφουν την ελάχιστη και τη
μέγιστη τιμή στην καθορισμένη στήλη ή έκφραση:
// SELECT MAX(`τιμή`) FROM `προϊόντα` WHERE `ενεργό` = 1
$maxPrice = $products->where('active', true)
->max('price');
sum (string $expr): int
Επιστρέφει το άθροισμα των τιμών στην καθορισμένη στήλη ή έκφραση:
// SELECT SUM(`Τιμή` * `Είδη_σε_απόθεμα`) FROM `Προϊόντα` WHERE `ενεργό` = 1
$totalPrice = $products->where('active', true)
->sum('price * items_in_stock');
aggregation (string $function, ?string $groupFunction = null): mixed
Επιτρέπει την εκτέλεση οποιασδήποτε συνάρτησης άθροισης.
// Υπολογίζει τη μέση τιμή των προϊόντων μιας κατηγορίας
$avgPrice = $products->where('category_id', 1)
->aggregation('AVG(price)');
// Συνδυάζει τις ετικέτες προϊόντων σε μια ενιαία συμβολοσειρά
$tags = $products->where('id', 1)
->aggregation('GROUP_CONCAT(tag.name) AS tags')
->fetch()
->tags;
Εάν χρειάζεται να αθροίσουμε αποτελέσματα που τα ίδια προκύπτουν από
μια συνάθροιση και ομαδοποίηση (π.χ. SUM(value)
πάνω σε
ομαδοποιημένες γραμμές), καθορίζουμε τη συνάρτηση συνάθροισης που θα
εφαρμοστεί σε αυτά τα ενδιάμεσα αποτελέσματα ως δεύτερο όρισμα:
// Υπολογίζει τη συνολική τιμή των προϊόντων σε απόθεμα για κάθε κατηγορία και στη συνέχεια αθροίζει τις τιμές αυτές.
$totalPrice = $products->select('category_id, SUM(price * stock) AS category_total')
->group('category_id')
->aggregation('SUM(category_total)', 'SUM');
Σε αυτό το παράδειγμα, υπολογίζουμε πρώτα τη συνολική τιμή των
προϊόντων σε κάθε κατηγορία (SUM(price * stock) AS category_total
) και
ομαδοποιούμε τα αποτελέσματα με βάση το category_id
. Στη συνέχεια
χρησιμοποιούμε το aggregation('SUM(category_total)', 'SUM')
για να αθροίσουμε αυτά
τα επιμέρους αθροίσματα. Το δεύτερο όρισμα 'SUM'
καθορίζει τη
συνάρτηση άθροισης που θα εφαρμοστεί στα ενδιάμεσα αποτελέσματα.
Εισαγωγή, ενημέρωση και διαγραφή
Η Nette Database Explorer απλοποιεί την εισαγωγή, την ενημέρωση και τη διαγραφή
δεδομένων. Όλες οι αναφερόμενες μέθοδοι πετούν ένα
Nette\Database\DriverException
σε περίπτωση σφάλματος.
Selection::insert (iterable $data): static
Εισάγει νέες εγγραφές σε έναν πίνακα.
Εισαγωγή μίας μόνο εγγραφής:
Η νέα εγγραφή παραδίδεται ως συσχετιστικός πίνακας ή αντικείμενο
επανάληψης (όπως το ArrayHash
που χρησιμοποιείται στις φόρμες), όπου τα κλειδιά αντιστοιχούν στα
ονόματα των στηλών του πίνακα.
Εάν ο πίνακας έχει καθορισμένο πρωτεύον κλειδί, η μέθοδος επιστρέφει
ένα αντικείμενο ActiveRow
, το οποίο φορτώνεται εκ νέου από τη βάση
δεδομένων για να αντικατοπτρίζει τυχόν αλλαγές που έγιναν σε επίπεδο
βάσης δεδομένων (π.χ. εναύσματα, προεπιλεγμένες τιμές στηλών ή
υπολογισμούς αυτόματης αύξησης). Αυτό διασφαλίζει τη συνέπεια των
δεδομένων και το αντικείμενο περιέχει πάντα τα τρέχοντα δεδομένα της
βάσης δεδομένων. Εάν δεν έχει οριστεί ρητά ένα πρωτεύον κλειδί, η
μέθοδος επιστρέφει τα δεδομένα εισόδου ως πίνακα.
$row = $explorer->table('users')->insert([
'name' => 'John Doe',
'email' => 'john.doe@example.com',
]);
// Η $row είναι μια περίπτωση της ActiveRow που περιέχει τα πλήρη δεδομένα της εισαγόμενης γραμμής,
// συμπεριλαμβανομένου του αναγνωριστικού που δημιουργείται αυτόματα και οποιωνδήποτε αλλαγών που πραγματοποιούνται από triggers
echo $row->id; // Εξάγει το ID του νεοεισαχθέντος χρήστη
echo $row->created_at; // Εκδίδει την ώρα δημιουργίας, εάν έχει οριστεί από ένα σκανδάλη
Εισαγωγή πολλαπλών εγγραφών ταυτόχρονα:
Η μέθοδος insert()
σας επιτρέπει να εισάγετε πολλαπλές εγγραφές
με ένα μόνο ερώτημα SQL. Σε αυτή την περίπτωση, επιστρέφει τον αριθμό των
εισαγόμενων γραμμών.
$insertedRows = $explorer->table('users')->insert([
[
'name' => 'John',
'year' => 1994,
],
[
'name' => 'Jack',
'year' => 1995,
],
]);
// INSERT INTO `users` (`name`, `year`) VALUES ('John', 1994), ('Jack', 1995)
// $insertedRows θα είναι 2
Μπορείτε επίσης να περάσετε ως παράμετρο ένα αντικείμενο
Selection
με μια επιλογή δεδομένων.
$newUsers = $explorer->table('potential_users')
->where('approved', 1)
->select('name, email');
$insertedRows = $explorer->table('users')->insert($newUsers);
Εισαγωγή ειδικών τιμών:
Οι τιμές μπορούν να περιλαμβάνουν αρχεία, αντικείμενα DateTime
ή
λογοτεχνικά στοιχεία SQL:
$explorer->table('users')->insert([
'name' => 'John',
'created_at' => new DateTime, // μετατρέπει σε μορφή βάσης δεδομένων
'avatar' => fopen('image.jpg', 'rb'), // εισάγει περιεχόμενο δυαδικού αρχείου
'uuid' => $explorer::literal('UUID()'), // καλεί τη συνάρτηση UUID()
]);
Selection::update (iterable $data): int
Ενημερώνει γραμμές σε έναν πίνακα με βάση ένα καθορισμένο φίλτρο. Επιστρέφει τον αριθμό των σειρών που τροποποιήθηκαν πραγματικά.
Οι προς ενημέρωση στήλες περνούν ως συσχετιστικός πίνακας ή
αντικείμενο επανάληψης (όπως το ArrayHash
που χρησιμοποιείται στις
φόρμες), όπου τα κλειδιά αντιστοιχούν στα
ονόματα των στηλών του πίνακα:
$affected = $explorer->table('users')
->where('id', 10)
->update([
'name' => 'John Smith',
'year' => 1994,
]);
// UPDATE `users` SET `name` = 'John Smith', `year` = 1994 WHERE `id` = 10
Για να αλλάξετε αριθμητικές τιμές, μπορείτε να χρησιμοποιήσετε τους
τελεστές +=
και -=
:
$explorer->table('users')
->where('id', 10)
->update([
'points+=' => 1, // αυξάνει την τιμή της στήλης "πόντοι" κατά 1
'coins-=' => 1, // μειώνει την τιμή της στήλης "νομίσματα" κατά 1
]);
// UPDATE `users` SET `points` = `points` + 1, `coins` = `coins` - 1 WHERE `id` = 10
Selection::delete(): int
Διαγράφει γραμμές από έναν πίνακα με βάση ένα καθορισμένο φίλτρο. Επιστρέφει τον αριθμό των διαγραμμένων γραμμών.
$count = $explorer->table('users')
->where('id', 10)
->delete();
// DELETE FROM `users` WHERE `id` = 10
Κατά την κλήση των update()
ή delete()
, φροντίστε να
χρησιμοποιήσετε το where()
για να καθορίσετε τις γραμμές που θα
ενημερωθούν ή θα διαγραφούν. Εάν δεν χρησιμοποιηθεί το where()
, η
λειτουργία θα εκτελεστεί σε ολόκληρο τον πίνακα!
ActiveRow::update (iterable $data): bool
Ενημερώνει τα δεδομένα σε μια γραμμή της βάσης δεδομένων που
αντιπροσωπεύεται από το αντικείμενο ActiveRow
. Δέχεται επαναλήψιμα
δεδομένα ως παράμετρο, όπου τα κλειδιά είναι ονόματα στηλών. Για να
αλλάξετε αριθμητικές τιμές, μπορείτε να χρησιμοποιήσετε τους τελεστές
+=
και -=
:
Αφού εκτελεστεί η ενημέρωση, το ActiveRow
φορτώνεται αυτόματα εκ
νέου από τη βάση δεδομένων για να αντικατοπτρίζει τυχόν αλλαγές που
έγιναν σε επίπεδο βάσης δεδομένων (π.χ. εναύσματα). Η μέθοδος επιστρέφει
το true
μόνο εάν έχει πραγματοποιηθεί πραγματική αλλαγή
δεδομένων.
$article = $explorer->table('article')->get(1);
$article->update([
'views += 1', // αυξάνει τον αριθμό προβολών
]);
echo $article->views; // Εκδίδει τον τρέχοντα αριθμό προβολών
Αυτή η μέθοδος ενημερώνει μόνο μια συγκεκριμένη γραμμή στη βάση δεδομένων. Για μαζικές ενημερώσεις πολλών γραμμών, χρησιμοποιήστε τη μέθοδο Selection::update().
ActiveRow::delete()
Διαγράφει μια γραμμή από τη βάση δεδομένων που αντιπροσωπεύεται από
το αντικείμενο ActiveRow
.
$book = $explorer->table('book')->get(1);
$book->delete(); // Διαγράφει το βιβλίο με ID 1
Αυτή η μέθοδος διαγράφει μόνο μια συγκεκριμένη γραμμή στη βάση δεδομένων. Για μαζική διαγραφή πολλών γραμμών, χρησιμοποιήστε τη μέθοδο Selection::delete().
Σχέσεις μεταξύ πινάκων
Στις σχεσιακές βάσεις δεδομένων, τα δεδομένα χωρίζονται σε πολλούς πίνακες και συνδέονται μέσω ξένων κλειδιών. Ο Nette Database Explorer προσφέρει έναν επαναστατικό τρόπο εργασίας με αυτές τις σχέσεις – χωρίς να γράφει ερωτήματα JOIN ή να απαιτεί οποιαδήποτε διαμόρφωση ή δημιουργία οντοτήτων.
Για την επίδειξη, θα χρησιμοποιήσουμε τη βάση δεδομένων παράδειγμα(διαθέσιμη στο GitHub). Η βάση δεδομένων περιλαμβάνει τους ακόλουθους πίνακες:
author
– συγγραφείς και μεταφραστές (στήλεςid
,name
,web
,born
)book
– βιβλία (στήλεςid
,author_id
,translator_id
,title
,sequel_id
)tag
– ετικέτες (στήλεςid
,name
)book_tag
– πίνακας συνδέσμων μεταξύ βιβλίων και ετικετών (στήλεςbook_id
,tag_id
)
Δομή της βάσης δεδομένων
Σε αυτό το παράδειγμα βάσης δεδομένων βιβλίων, βρίσκουμε διάφορους τύπους σχέσεων (απλοποιημένους σε σχέση με την πραγματικότητα):
- Ένα προς πολλά (1:N) – Κάθε βιβλίο έχει έναν συγγραφέα- ένας συγγραφέας μπορεί να γράψει πολλαπλά βιβλία.
- Νέο προς πολλά (0:N) – Ένα βιβλίο μπορεί να έχει έναν μεταφραστή- ένας μεταφραστής μπορεί να μεταφράσει πολλαπλά βιβλία.
- Μηδέν προς ένα (0:1) – Ένα βιβλίο μπορεί να έχει συνέχεια.
- Πολλοί-προς-πολλούς (Μ:Ν) – Ένα βιβλίο μπορεί να έχει πολλές ετικέτες και μια ετικέτα μπορεί να ανατεθεί σε πολλά βιβλία.
Σε αυτές τις σχέσεις, υπάρχει πάντα ένας πίνακας γονέας και ένας
πίνακας παιδί. Για παράδειγμα, στη σχέση μεταξύ συγγραφέων και
βιβλίων, ο πίνακας author
είναι ο γονέας και ο πίνακας book
είναι το παιδί – μπορείτε να το φανταστείτε ότι ένα βιβλίο “ανήκει”
πάντα σε έναν συγγραφέα. Αυτό αντικατοπτρίζεται και στη δομή της βάσης
δεδομένων: ο πίνακας-παιδί book
περιέχει το ξένο κλειδί
author_id
, το οποίο παραπέμπει στον πίνακα-γονέα author
.
Αν θέλουμε να εμφανίσουμε τα βιβλία μαζί με τα ονόματα των συγγραφέων τους, έχουμε δύο επιλογές. Είτε ανακτούμε τα δεδομένα χρησιμοποιώντας ένα ενιαίο ερώτημα SQL με ένα JOIN:
SELECT book.*, author.name FROM book LEFT JOIN author ON book.author_id = author.id;
Ή ανακτούμε τα δεδομένα σε δύο βήματα – πρώτα τα βιβλία, μετά τους συγγραφείς τους – και τα συναρμολογούμε σε PHP:
SELECT * FROM book;
SELECT * FROM author WHERE id IN (1, 2, 3); -- IDs of authors retrieved from books
Η δεύτερη προσέγγιση είναι, παραδόξως, πιο αποδοτική. Τα δεδομένα ανακτώνται μόνο μία φορά και μπορούν να αξιοποιηθούν καλύτερα στην κρυφή μνήμη. Έτσι ακριβώς λειτουργεί ο Nette Database Explorer – χειρίζεται τα πάντα κάτω από την κουκούλα και σας παρέχει ένα καθαρό API:
$books = $explorer->table('book');
foreach ($books as $book) {
echo 'title: ' . $book->title;
echo 'written by: ' . $book->author->name; // $book->author είναι μια εγγραφή από τον πίνακα 'author'
echo 'translated by: ' . $book->translator?->name;
}
Πρόσβαση στον γονικό πίνακα
Η πρόσβαση στον γονικό πίνακα είναι απλή. Πρόκειται για σχέσεις όπως
ένα βιβλίο έχει έναν συγγραφέα ή ένα βιβλίο μπορεί να έχει έναν
μεταφραστή. Η σχετική εγγραφή μπορεί να προσπελαστεί μέσω της
ιδιότητας του αντικειμένου ActiveRow
– το όνομα της ιδιότητας
ταιριάζει με το όνομα της στήλης του ξένου κλειδιού χωρίς την κατάληξη
id
:
$book = $explorer->table('book')->get(1);
echo $book->author->name; // βρίσκει τον συγγραφέα μέσω της στήλης 'author_id'
echo $book->translator?->name; // βρίσκει τον μεταφραστή μέσω της στήλης 'translator_id'.
Κατά την πρόσβαση στην ιδιότητα $book->author
, ο Explorer αναζητά μια
στήλη στον πίνακα book
που περιέχει τη συμβολοσειρά author
(π.χ. author_id
). Με βάση την τιμή σε αυτή τη στήλη, ανακτά την
αντίστοιχη εγγραφή από τον πίνακα author
και την επιστρέφει ως
αντικείμενο ActiveRow
. Ομοίως, το $book->translator
χρησιμοποιεί τη
στήλη translator_id
. Δεδομένου ότι η στήλη translator_id
μπορεί να
περιέχει null
, χρησιμοποιείται ο τελεστής ?->
.
Μια εναλλακτική προσέγγιση παρέχεται από τη μέθοδο ref()
, η
οποία δέχεται δύο ορίσματα – το όνομα του πίνακα-στόχου και τη στήλη
σύνδεσης – και επιστρέφει ένα αντικείμενο ActiveRow
ή null
:
echo $book->ref('author', 'author_id')->name; // σύνδεση με τον συγγραφέα
echo $book->ref('author', 'translator_id')->name; // σύνδεσμος προς τον μεταφραστή
Η μέθοδος ref()
είναι χρήσιμη εάν δεν μπορεί να χρησιμοποιηθεί
πρόσβαση με βάση την ιδιότητα, για παράδειγμα, όταν ο πίνακας περιέχει
μια στήλη με το ίδιο όνομα με την ιδιότητα (author
). Σε άλλες
περιπτώσεις, συνιστάται η χρήση της πρόσβασης με βάση την ιδιότητα για
καλύτερη αναγνωσιμότητα.
Ο Explorer βελτιστοποιεί αυτόματα τα ερωτήματα στη βάση δεδομένων. Κατά την επανάληψη των βιβλίων και την πρόσβαση στις σχετικές εγγραφές τους (συγγραφείς, μεταφραστές), ο Explorer δεν δημιουργεί ένα ερώτημα για κάθε βιβλίο ξεχωριστά. Αντ' αυτού, εκτελεί μόνο ένα ερώτημα SELECT για κάθε τύπο σχέσης, μειώνοντας σημαντικά το φορτίο της βάσης δεδομένων. Για παράδειγμα:
$books = $explorer->table('book');
foreach ($books as $book) {
echo $book->title . ': ';
echo $book->author->name;
echo $book->translator?->name;
}
Αυτός ο κώδικας θα εκτελέσει μόνο τρία βελτιστοποιημένα ερωτήματα στη βάση δεδομένων:
SELECT * FROM `book`;
SELECT * FROM `author` WHERE (`id` IN (1, 2, 3)); -- IDs from 'author_id' column in selected books
SELECT * FROM `author` WHERE (`id` IN (2, 3)); -- IDs from 'translator_id' column in selected books
Η λογική για τον προσδιορισμό της συνδετικής στήλης καθορίζεται από την υλοποίηση των Συμβάσεων. Συνιστούμε τη χρήση του DiscoveredConventions, το οποίο αναλύει τα ξένα κλειδιά και σας επιτρέπει να εργάζεστε απρόσκοπτα με τις υπάρχουσες σχέσεις πινάκων.
Πρόσβαση στον πίνακα "παιδί
Η πρόσβαση στον πίνακα “παιδί” λειτουργεί προς την αντίθετη
κατεύθυνση. Τώρα ρωτάμε ποια βιβλία έγραψε αυτός ο συγγραφέας ή
ποια βιβλία μετέφρασε αυτός ο μεταφραστής. Για αυτού του είδους το
ερώτημα, χρησιμοποιούμε τη μέθοδο related()
, η οποία επιστρέφει ένα
αντικείμενο Selection
με σχετικές εγγραφές. Ακολουθεί ένα
παράδειγμα:
$author = $explorer->table('author')->get(1);
// Βγάζει όλα τα βιβλία που έχει γράψει ο συγγραφέας
foreach ($author->related('book.author_id') as $book) {
echo "Wrote: $book->title";
}
// Εκδίδει όλα τα βιβλία που έχουν μεταφραστεί από τον συγγραφέα
foreach ($author->related('book.translator_id') as $book) {
echo "Translated: $book->title";
}
Η μέθοδος related()
δέχεται την περιγραφή της σχέσης ως ενιαίο
όρισμα με τη χρήση σημείωσης τελείας ή ως δύο ξεχωριστά ορίσματα:
$author->related('book.translator_id'); // ένα μόνο επιχείρημα
$author->related('book', 'translator_id'); // δύο επιχειρήματα
Ο Explorer μπορεί να εντοπίσει αυτόματα τη σωστή στήλη σύνδεσης με βάση
το όνομα του γονικού πίνακα. Σε αυτή την περίπτωση, συνδέει μέσω της
στήλης book.author_id
επειδή το όνομα του πίνακα προέλευσης είναι
author
:
$author->related('book'); // χρησιμοποιεί book.author_id
Εάν υπάρχουν πολλαπλές πιθανές συνδέσεις, ο Explorer θα πετάξει μια εξαίρεση AmbiguousReferenceKeyException.
Μπορούμε, φυσικά, να χρησιμοποιήσουμε τη μέθοδο related()
και κατά
την επανάληψη πολλαπλών εγγραφών σε έναν βρόχο, και ο Explorer θα
βελτιστοποιήσει αυτόματα τα ερωτήματα και σε αυτή την περίπτωση:
$authors = $explorer->table('author');
foreach ($authors as $author) {
echo $author->name . ' wrote:';
foreach ($author->related('book') as $book) {
echo $book->title;
}
}
Αυτός ο κώδικας παράγει μόνο δύο αποδοτικά ερωτήματα SQL:
SELECT * FROM `author`;
SELECT * FROM `book` WHERE (`author_id` IN (1, 2, 3)); -- IDs of the selected authors
Σχέση Πολλοί-προς-Πολλούς
Για μια σχέση πολλών προς πολλούς (Μ:Ν), απαιτείται ένας πίνακας
σύνδεσης (στην περίπτωσή μας, book_tag
). Ο πίνακας αυτός περιέχει
δύο στήλες ξένου κλειδιού (book_id
, tag_id
). Κάθε στήλη
αναφέρεται στο πρωτεύον κλειδί ενός από τους συνδεδεμένους πίνακες.
Για να ανακτήσουμε τα συνδεδεμένα δεδομένα, πρώτα αντλούμε εγγραφές
από τον πίνακα σύνδεσης χρησιμοποιώντας το related('book_tag')
, και στη
συνέχεια συνεχίζουμε με τα δεδομένα-στόχο:
$book = $explorer->table('book')->get(1);
// Βγάζει τα ονόματα των ετικετών που έχουν αντιστοιχιστεί στο βιβλίο
foreach ($book->related('book_tag') as $bookTag) {
echo $bookTag->tag->name; // αντλεί το όνομα της ετικέτας μέσω του πίνακα συνδέσμων
}
$tag = $explorer->table('tag')->get(1);
// Αντίθετη κατεύθυνση: εξάγει τους τίτλους των βιβλίων με αυτή την ετικέτα
foreach ($tag->related('book_tag') as $bookTag) {
echo $bookTag->book->title; // αντλεί τον τίτλο του βιβλίου
}
Ο Explorer βελτιστοποιεί και πάλι τα ερωτήματα SQL σε μια αποδοτική μορφή:
SELECT * FROM `book`;
SELECT * FROM `book_tag` WHERE (`book_tag`.`book_id` IN (1, 2, ...)); -- IDs of the selected books
SELECT * FROM `tag` WHERE (`tag`.`id` IN (1, 2, ...)); -- IDs of the tags found in book_tag
Ερώτηση μέσω σχετικών πινάκων
Στις μεθόδους where()
, select()
, order()
και group()
,
μπορείτε να χρησιμοποιήσετε ειδικούς συμβολισμούς για να αποκτήσετε
πρόσβαση σε στήλες από άλλους πίνακες. Ο Explorer δημιουργεί αυτόματα τις
απαιτούμενες JOINs.
Ο συμβολισμός Dot (parent_table.column
) χρησιμοποιείται για σχέσεις
1:Ν, όπως φαίνεται από την οπτική γωνία του μητρικού πίνακα:
$books = $explorer->table('book');
// Βρίσκει βιβλία των οποίων τα ονόματα των συγγραφέων αρχίζουν με 'Jon'
$books->where('author.name LIKE ?', 'Jon%');
// Ταξινομεί τα βιβλία με βάση το όνομα του συγγραφέα κατά φθίνουσα σειρά
$books->order('author.name DESC');
// Βγάζει τον τίτλο του βιβλίου και το όνομα του συγγραφέα
$books->select('book.title, author.name');
Ο συμβολισμός με τελεία χρησιμοποιείται για σχέσεις 1:Ν από την οπτική γωνία του γονικού πίνακα:
$authors = $explorer->table('author');
// Βρίσκει συγγραφείς που έγραψαν ένα βιβλίο με 'PHP' στον τίτλο
$authors->where(':book.title LIKE ?', '%PHP%');
// Μετράει τον αριθμό των βιβλίων για κάθε συγγραφέα
$authors->select('*, COUNT(:book.id) AS book_count')
->group('author.id');
Στο παραπάνω παράδειγμα με συμβολισμό άνω και κάτω τελείας
(:book.title
), η στήλη ξένου κλειδιού δεν προσδιορίζεται ρητά. Η
Εξερεύνηση εντοπίζει αυτόματα τη σωστή στήλη με βάση το όνομα του
γονικού πίνακα. Σε αυτή την περίπτωση, συνδέεται μέσω της στήλης
book.author_id
επειδή το όνομα του πίνακα προέλευσης είναι author
.
Εάν υπάρχουν πολλαπλές πιθανές συνδέσεις, ο Explorer πετάει την εξαίρεση AmbiguousReferenceKeyException.
Η στήλη σύνδεσης μπορεί να καθοριστεί ρητά σε παρένθεση:
// Βρίσκει συγγραφείς που μετέφρασαν ένα βιβλίο με το 'PHP' στον τίτλο
$authors->where(':book(translator).title LIKE ?', '%PHP%');
Οι συμβολισμοί μπορούν να συνδεθούν αλυσιδωτά για πρόσβαση σε δεδομένα σε πολλούς πίνακες:
// Βρίσκει συγγραφείς βιβλίων με ετικέτα 'PHP'
$authors->where(':book:book_tag.tag.name', 'PHP')
->group('author.id');
Επέκταση των όρων για JOIN
Η μέθοδος joinWhere()
προσθέτει πρόσθετες συνθήκες στις συνδέσεις
πινάκων στην SQL μετά τη λέξη-κλειδί ON
.
Για παράδειγμα, ας πούμε ότι θέλουμε να βρούμε βιβλία που έχουν μεταφραστεί από έναν συγκεκριμένο μεταφραστή:
// Βρίσκει βιβλία μεταφρασμένα από έναν μεταφραστή με το όνομα 'David'
$books = $explorer->table('book')
->joinWhere('translator', 'translator.name', 'David');
// LEFT JOIN author translator ON book.translator_id = translator.id AND (translator.name = 'David')
Στη συνθήκη joinWhere()
, μπορείτε να χρησιμοποιήσετε τις ίδιες
δομές όπως στη μέθοδο where()
– τελεστές, σημεία τοποθέτησης,
πίνακες τιμών ή εκφράσεις SQL.
Για πιο σύνθετα ερωτήματα με πολλαπλές JOINs, μπορούν να οριστούν ψευδώνυμα πινάκων:
$tags = $explorer->table('tag')
->joinWhere(':book_tag.book.author', 'book_author.born < ?', 1950)
->alias(':book_tag.book.author', 'book_author');
// LEFT JOIN `book_tag` ON `tag`.`id` = `book_tag`.`tag_id`
// LEFT JOIN `book` ON `book_tag`.`book_id` = `book`.`id`
// LEFT JOIN `author` `book_author` ON `book`.`author_id` = `book_author`.`id`
// AND (`book_author`.`born` < 1950)
Σημειώστε ότι ενώ η μέθοδος where()
προσθέτει συνθήκες στη ρήτρα
WHERE
, η μέθοδος joinWhere()
επεκτείνει τις συνθήκες στη ρήτρα
ON
κατά τη διάρκεια των ενώσεων πινάκων.
Χειροκίνητη δημιουργία Explorer
Εάν δεν χρησιμοποιείτε το δοχείο Nette DI, μπορείτε να δημιουργήσετε μια
περίπτωση του Nette\Database\Explorer
με μη αυτόματο τρόπο:
use Nette\Database;
// $storage υλοποιεί Nette\Caching\Storage, π.χ.:
$storage = new Nette\Caching\Storages\FileStorage('/path/to/temp/dir');
// σύνδεση με βάση δεδομένων
$connection = new Database\Connection('mysql:host=127.0.0.1;dbname=mydatabase', 'user', 'password');
// διαχειρίζεται την αντανάκλαση της δομής της βάσης δεδομένων
$structure = new Database\Structure($connection, $storage);
// ορίζει κανόνες για την αντιστοίχιση ονομάτων πινάκων, στηλών και ξένων κλειδιών
$conventions = new Database\Conventions\DiscoveredConventions($structure);
$explorer = new Database\Explorer($connection, $structure, $conventions, $storage);