Schnellstart
Das Webman-Modell basiert auf Eloquent ORM. Jede Datenbanktabelle hat ein entsprechendes "Modell", das mit dieser Tabelle interagiert. Sie können das Modell verwenden, um Daten aus der Tabelle abzufragen und neue Datensätze in die Tabelle einzufügen.
Bevor Sie beginnen, stellen Sie sicher, dass die Datenbankverbindung in config/database.php
konfiguriert ist.
Hinweis: Um Modellbeobachter mit Eloquent ORM zu verwenden, müssen Sie zusätzlich
composer require "illuminate/events"
importieren. Beispiel
Beispiel
<?php
namespace app\model;
use support\Model;
class User extends Model
{
/**
* Name der mit dem Modell verknüpften Tabelle
*
* @var string
*/
protected $table = 'user';
/**
* Neudefinition des Primärschlüssels, standardmäßig ist es "id"
*
* @var string
*/
protected $primaryKey = 'uid';
/**
* Gibt an, ob Zeitstempel automatisch gepflegt werden
*
* @var bool
*/
public $timestamps = false;
}
Tabellenname
Sie können einen benutzerdefinierten Tabellennamen angeben, indem Sie das table
-Attribut im Modell definieren:
class User extends Model
{
/**
* Name der mit dem Modell verknüpften Tabelle
*
* @var string
*/
protected $table = 'user';
}
Primärschlüssel
Eloquent geht auch davon aus, dass jede Datenbanktabelle eine Spalte mit dem Namen "id" als Primärschlüssel hat. Sie können ein geschütztes Attribut $primaryKey
definieren, um diese Konvention zu überschreiben.
class User extends Model
{
/**
* Neudefinition des Primärschlüssels, standardmäßig ist es "id"
*
* @var string
*/
protected $primaryKey = 'uid';
}
Eloquent nimmt an, dass der Primärschlüssel ein inkrementierter Ganzzahlwert ist, was bedeutet, dass der Primärschlüssel standardmäßig in einen int-Typ umgewandelt wird. Wenn Sie einen nicht-inkrementierenden oder nicht-numerischen Primärschlüssel verwenden möchten, müssen Sie das öffentliche Attribut $incrementing
auf false
setzen.
class User extends Model
{
/**
* Gibt an, ob der Modell-Primärschlüssel inkrementiert wird
*
* @var bool
*/
public $incrementing = false;
}
Wenn Ihr Primärschlüssel kein Integer ist, müssen Sie das geschützte $keyType
-Attribut im Modell auf "string" setzen:
class User extends Model
{
/**
* "Typ" des automatisch inkrementierten IDs
*
* @var string
*/
protected $keyType = 'string';
}
Zeitstempel
Standardmäßig erwartet Eloquent, dass Ihre Datenbanktabelle created_at
und updated_at
enthält. Wenn Sie nicht möchten, dass Eloquent diese beiden Spalten automatisch verwaltet, setzen Sie das $timestamps
Attribut im Modell auf false
:
class User extends Model
{
/**
* Gibt an, ob Zeitstempel automatisch gepflegt werden
*
* @var bool
*/
public $timestamps = false;
}
Wenn Sie das Format des Zeitstempels anpassen möchten, setzen Sie das $dateFormat
Attribut in Ihrem Modell. Dieses Attribut bestimmt die Speicherweise des Datumsattributs in der Datenbank sowie das Format, in dem das Modell als Array oder JSON serialisiert wird:
class User extends Model
{
/**
* Format für die Speicherung des Zeitstempels
*
* @var string
*/
protected $dateFormat = 'U';
}
Wenn Sie die Namen der Zeitstempelfelder anpassen möchten, können Sie die Werte der Konstanten CREATED_AT
und UPDATED_AT
im Modell setzen:
class User extends Model
{
const CREATED_AT = 'creation_date';
const UPDATED_AT = 'last_update';
}
Datenbankverbindung
Standardmäßig verwendet das Eloquent-Modell die in Ihrer Anwendungsconfiguration festgelegte Standarddatenbankverbindung. Wenn Sie dem Modell eine andere Verbindung zuweisen möchten, setzen Sie das $connection
Attribut:
class User extends Model
{
/**
* Name der Verbindung des Modells
*
* @var string
*/
protected $connection = 'connection-name';
}
Standardattributwerte
Wenn Sie Standardwerte für bestimmte Attribute des Modells definieren möchten, können Sie das $attributes
Attribut im Modell definieren:
class User extends Model
{
/**
* Standardattributwerte des Modells
*
* @var array
*/
protected $attributes = [
'delayed' => false,
];
}
Modellabfrage
Nachdem Sie das Modell und die zugehörige Datenbanktabelle erstellt haben, können Sie nun Daten aus der Datenbank abrufen. Stellen Sie sich jedes Eloquent-Modell als leistungsstarken Abfrage-Builder vor, mit dem Sie schnell auf die damit verbundene Datenbanktabelle zugreifen können. Zum Beispiel:
$users = app\model\User::all();
foreach ($users as $user) {
echo $user->name;
}
Hinweis: Da Eloquent-Modelle auch Abfrage-Builder sind, sollten Sie alle verfügbaren Methoden der Abfrage-Builder einsehen. Diese Methoden können in Eloquent-Abfragen verwendet werden.
Zusätzliche Einschränkungen
Die all
-Methode von Eloquent gibt alle Ergebnisse des Modells zurück. Da jedes Eloquent-Modell als Abfrage-Builder fungiert, können Sie auch Abfragebedingungen hinzufügen und die get
-Methode verwenden, um die Abfrageergebnisse abzurufen:
$users = app\model\User::where('name', 'like', '%tom')
->orderBy('uid', 'desc')
->limit(10)
->get();
Modell neu laden
Sie können die Methoden fresh
und refresh
verwenden, um das Modell neu zu laden. Die fresh
-Methode ruft das Modell erneut aus der Datenbank ab. Die bestehende Modellinstanz bleibt unberührt:
$user = app\model\User::where('name', 'tom')->first();
$fresh_user = $user->fresh();
Die refresh
-Methode aktualisiert das vorhandene Modell mit den neuen Daten aus der Datenbank. Darüber hinaus werden bereits geladene Beziehungen ebenfalls aktualisiert:
$user = app\model\User::where('name', 'tom')->first();
$user->name = 'jerry';
$user = $user->fresh();
$user->name; // "tom"
Sammlung
Die Methoden all
und get
von Eloquent können mehrere Ergebnisse abfragen und eine Instanz der Klasse Illuminate\Database\Eloquent\Collection
zurückgeben. Die Klasse Collection
bietet viele Hilfsfunktionen zum Verarbeiten von Eloquent-Ergebnissen:
$users = $users->reject(function ($user) {
return $user->disabled;
});
Verwendung von Cursor
Die Methode cursor
ermöglicht es Ihnen, den Cursor zum Durchlaufen der Datenbank zu verwenden. Es führt nur eine Abfrage durch. Bei der Verarbeitung großer Datenmengen kann die Methode cursor
den Speicherbedarf erheblich reduzieren:
foreach (app\model\User::where('sex', 1')->cursor() as $user) {
//
}
cursor
gibt eine Instanz von Illuminate\Support\LazyCollection
zurück. Lazy Collections ermöglichen die Verwendung der meisten Methoden von Laravel Collections und laden jedes Mal nur ein einzelnes Modell in den Speicher:
$users = app\model\User::cursor()->filter(function ($user) {
return $user->id > 500;
});
foreach ($users as $user) {
echo $user->id;
}
Selects-Subquery
Eloquent bietet fortschrittliche Unterabfrage-Unterstützung, mit der Sie mit einer einzelnen Abfrage Informationen aus verwandten Tabellen abrufen können. Zum Beispiel, nehmen wir an, wir haben eine Tabelle destinations
und eine Tabelle flights
, die die Flüge zu den Zielen enthält. Die flights
-Tabelle enthält ein Feld arrival_at
, das angibt, wann der Flug am Ziel ankommt.
Mit den Funktionen select
und addSelect
von Subqueries können wir mit einer einzigen Abfrage alle Destinationen abfragen und den Namen des letzten Flugs, der an jedem Ziel angekommen ist, abrufen:
use app\model\Destination;
use app\model\Flight;
return Destination::addSelect(['last_flight' => Flight::select('name')
->whereColumn('destination_id', 'destinations.id')
->orderBy('arrived_at', 'desc')
->limit(1)
])->get();
Sortieren nach einer Unterabfrage
Außerdem unterstützt die orderBy
-Funktion des Abfrage-Builders auch Unterabfragen. Mit dieser Funktion können wir alle Ziele basierend auf der Ankunftszeit des letzten Flugs am Ziel sortieren. Auch hier erfolgt nur eine einzelne Abfrage an die Datenbank:
return Destination::orderByDesc(
Flight::select('arrived_at')
->whereColumn('destination_id', 'destinations.id')
->orderBy('arrived_at', 'desc')
->limit(1)
)->get();
Einzelnes Modell / Sammlung abrufen
Neben dem Abrufen aller Datensätze aus einer bestimmten Datenbanktabelle können Sie die Methoden find, first oder firstWhere verwenden, um einen einzelnen Datensatz abzurufen. Diese Methoden geben eine einzelne Modellinstanz zurück, anstatt eine Modellsammlung zurückzugeben:
// Ein Modell anhand des Primärschlüssels finden...
$flight = app\model\Flight::find(1);
// Das erste Modell abrufen, das der Abfragebedingung entspricht...
$flight = app\model\Flight::where('active', 1)->first();
// Schnelle Implementierung, um das erste Modell abzurufen, das der Abfragebedingung entspricht...
$flight = app\model\Flight::firstWhere('active', 1);
Sie können auch die Methode find mit einem Array als Parameter aufrufen, um eine Sammlung von übereinstimmenden Datensätzen zurückzugeben:
$flights = app\model\Flight::find([1, 2, 3]);
Manchmal möchten Sie zusätzliche Aktionen ausführen, wenn Sie nach dem ersten Ergebnis suchen, das nicht gefunden wird. Die Methode firstOr gibt das erste Ergebnis zurück, wenn eines gefunden wird, andernfalls führt sie den angegebenen Callback aus. Der Rückgabewert des Callbacks wird als Rückgabewert der Methode firstOr verwendet:
$model = app\model\Flight::where('legs', '>', 100)->firstOr(function () {
// ...
});
Die firstOr Methode akzeptiert auch ein Feldarray für die Abfrage:
$model = app\model\Flight::where('legs', '>', 100)
->firstOr(['id', 'legs'], function () {
// ...
});
"Nicht gefunden" Ausnahme
Manchmal möchten Sie eine Ausnahme auslösen, wenn das Modell nicht gefunden wird. Dies ist besonders nützlich in Controllern und Routen. Die Methoden findOrFail und firstOrFail rufen das erste abgefragte Ergebnis ab. Wenn kein Ergebnis gefunden wird, wird eine Illuminate\Database\Eloquent\ModelNotFoundException-Ausnahme ausgelöst:
$model = app\model\Flight::findOrFail(1);
$model = app\model\Flight::where('legs', '>', 100)->firstOrFail();
Sammlung abrufen
Sie können auch die count, sum und max Methoden sowie andere Sammlungsfunktionen des Abfrage-Generators verwenden, um mit Sammlungen zu arbeiten. Diese Methoden geben nur den entsprechenden skalaren Wert zurück, anstatt eine Modellinstanz:
$count = app\model\Flight::where('active', 1)->count();
$max = app\model\Flight::where('active', 1)->max('price');
Einfügen
Um einen Datensatz in die Datenbank einzufügen, erstellen Sie zunächst eine neue Modellinstanz, setzen Sie die Attribute und rufen Sie dann die save Methode auf:
<?php
namespace app\controller;
use app\model\User;
use support\Request;
use support\Response;
class FooController
{
/**
* Fügt einen neuen Datensatz in die Benutzertabelle ein
*
* @param Request $request
* @return Response
*/
public function store(Request $request)
{
// Anfrage validieren
$user = new User;
$user->name = $request->get('name');
$user->save();
}
}
created_at und updated_at Zeitstempel werden automatisch gesetzt (wenn die $timestamps Eigenschaft im Modell true ist) und müssen nicht manuell zugewiesen werden.
Aktualisierung
Die save Methode kann auch zum Aktualisieren eines bereits vorhandenen Modells in der Datenbank verwendet werden. Um ein Modell zu aktualisieren, müssen Sie es zuerst abrufen, die zu aktualisierenden Attribute festlegen und dann die save Methode aufrufen. Ebenso wird der updated_at Zeitstempel automatisch aktualisiert, sodass keine manuelle Zuweisung erforderlich ist:
$user = app\model\User::find(1);
$user->name = 'jerry';
$user->save();
Massenaktualisierung
app\model\User::where('uid', '>', 10)
->update(['name' => 'tom']);
Überprüfen von Attributänderungen
Eloquent bietet die isDirty, isClean und wasChanged Methoden, um den internen Zustand des Modells zu überprüfen und festzustellen, wie sich seine Attribute seit dem ursprünglichen Laden geändert haben.
Die isDirty Methode bestimmt, ob seit dem Laden des Modells Änderungen an einem Attribut vorgenommen wurden. Sie können einen spezifischen Attributnamen übergeben, um festzustellen, ob ein bestimmtes Attribut schmutzig ist. Die Methode isClean ist das Gegenteil von isDirty und akzeptiert auch optionale Attributparameter:
$user = User::create([
'first_name' => 'Taylor',
'last_name' => 'Otwell',
'title' => 'Entwickler',
]);
$user->title = 'Maler';
$user->isDirty(); // true
$user->isDirty('title'); // true
$user->isDirty('first_name'); // false
$user->isClean(); // false
$user->isClean('title'); // false
$user->isClean('first_name'); // true
$user->save();
$user->isDirty(); // false
$user->isClean(); // true
Die wasChanged Methode bestimmt, ob seit dem letzten Speichern des Modells in der aktuellen Anforderungsperiode Änderungen an einem Attribut vorgenommen wurden. Sie können auch einen Attributnamen übergeben, um festzustellen, ob ein bestimmtes Attribut geändert wurde:
$user = User::create([
'first_name' => 'Taylor',
'last_name' => 'Otwell',
'title' => 'Entwickler',
]);
$user->title = 'Maler';
$user->save();
$user->wasChanged(); // true
$user->wasChanged('title'); // true
$user->wasChanged('first_name'); // false
Massenzuweisung
Sie können auch die create Methode verwenden, um ein neues Modell zu speichern. Diese Methode gibt eine Modellinstanz zurück. Bevor Sie sie verwenden, müssen Sie jedoch die fillable- oder guarded-Eigenschaften des Modells festlegen, da alle Eloquent-Modelle standardmäßig nicht für Massenzuweisungen zugelassen sind.
Wenn ein Benutzer versehentlich unerwartete HTTP-Parameter überträgt, die zu Feldern in der Datenbank führen, die Sie nicht ändern möchten, kann es zu einer Massenzuweisungslücke kommen. Zum Beispiel könnte ein bösartiger Benutzer den Parameter is_admin über ein HTTP-Request übertragen und diesen an die create Methode übergeben, was es dem Benutzer ermöglichen würde, sich selbst zum Administrator zu befördern.
Daher ist es wichtig, vorher festzulegen, welche Eigenschaften des Modells für Massenzuweisungen zugelassen sind. Sie können dies mit der $fillable-Eigenschaft des Modells erreichen. Zum Beispiel können Sie das name-Attribut des Flight-Modells für Massenzuweisungen zulassen:
<?php
namespace app\model;
use support\Model;
class Flight extends Model
{
/**
* Eigenschaften, die für Massenzuweisungen zugelassen sind.
*
* @var array
*/
protected $fillable = ['name'];
}
Sobald Sie die für Massenzuweisungen zugelassenen Eigenschaften festgelegt haben, können Sie die create Methode verwenden, um neue Daten in die Datenbank einzufügen. Die create Methode gibt die gespeicherte Modellinstanz zurück:
$flight = app\modle\Flight::create(['name' => 'Flug 10']);
Wenn Sie bereits eine Modellinstanz haben, können Sie ein Array an die fill Methode übergeben, um Werte zuzuweisen:
$flight->fill(['name' => 'Flug 22']);
$fillable kann als eine Art "Whitelist" für Massenzuweisungen betrachtet werden. Sie können auch die $guarded-Eigenschaft verwenden. Die $guarded-Eigenschaft enthält ein Array von Attributen, die nicht für Massenzuweisungen zugelassen sind. Mit anderen Worten, $guarded wird funktional eher wie eine "Blacklist" sein. Beachten Sie: Sie können nur $fillable oder $guarded verwenden, nicht beide gleichzeitig. Im folgenden Beispiel können alle Attribute außer dem Preis für Massenzuweisungen verwendet werden:
<?php
namespace app\model;
use support\Model;
class Flight extends Model
{
/**
* Nicht für Massenzuweisungen zugelassene Eigenschaften.
*
* @var array
*/
protected $guarded = ['price'];
}
Wenn Sie möchten, dass alle Eigenschaften für Massenzuweisungen zugelassen sind, können Sie $guarded als leeres Array definieren:
/**
* Nicht für Massenzuweisungen zugelassene Eigenschaften.
*
* @var array
*/
protected $guarded = [];
Andere Erstellungsmethoden
firstOrCreate/ firstOrNew
Es gibt zwei Methoden, die Sie möglicherweise für Massenzuweisungen verwenden möchten: firstOrCreate und firstOrNew. Die Methode firstOrCreate passt die Datensätze in der Datenbank anhand der angegebenen Schlüssel/Wert-Paare an. Wenn das Modell in der Datenbank nicht gefunden wird, wird ein Datensatz eingefügt, der die Attribute des ersten Parameters sowie optional die Attribute des zweiten Parameters enthält.
Die Methode firstOrNew versucht, ähnlich wie die Methode firstOrCreate, anhand der angegebenen Attribute Datensätze in der Datenbank zu finden. Wenn die Methode firstOrNew jedoch kein entsprechendes Modell findet, wird eine neue Modellinstanz zurückgegeben. Beachten Sie, dass die von firstOrNew zurückgegebene Modellinstanz noch nicht in der Datenbank gespeichert ist. Sie müssen die save-Methode manuell aufrufen, um sie zu speichern:
// Flug anhand des Namens abrufen oder erstellen, wenn nicht vorhanden...
$flight = app\modle\Flight::firstOrCreate(['name' => 'Flug 10']);
// Flug anhand des Namens abrufen oder mit den Attributen name, delayed und arrival_time erstellen...
$flight = app\modle\Flight::firstOrCreate(
['name' => 'Flug 10'],
['delayed' => 1, 'arrival_time' => '11:30']
);
// Flug anhand des Namens abrufen oder eine Instanz erstellen, wenn nicht vorhanden...
$flight = app\modle\Flight::firstOrNew(['name' => 'Flug 10']);
// Flug anhand des Namens abrufen oder eine Modellinstanz mit den Attributen name, delayed und arrival_time erstellen...
$flight = app\modle\Flight::firstOrNew(
['name' => 'Flug 10'],
['delayed' => 1, 'arrival_time' => '11:30']
);
Es kann auch vorkommen, dass Sie bestehende Modelle aktualisieren oder bei Nichtexistenz neue Modelle erstellen möchten. Dies kann mit der Methode updateOrCreate in einem Schritt erfolgen. Ähnlich wie bei der Methode firstOrCreate persistiert updateOrCreate das Modell, sodass Sie save() nicht aufrufen müssen:
// Wenn ein Flug von Oakland nach San Diego existiert, wird der Preis auf 99 USD festgelegt.
// Wenn kein passendes Modell gefunden wird, wird eins erstellt.
$flight = app\modle\Flight::updateOrCreate(
['departure' => 'Oakland', 'destination' => 'San Diego'],
['price' => 99, 'discounted' => 1]
);
Modell löschen
Sie können die Methode delete auf einer Modellinstanz aufrufen, um die Instanz zu löschen:
$flight = app\modle\Flight::find(1);
$flight->delete();
Modell anhand des Primärschlüssels löschen
app\modle\Flight::destroy(1);
app\modle\Flight::destroy(1, 2, 3);
app\modle\Flight::destroy([1, 2, 3]);
app\modle\Flight::destroy(collect([1, 2, 3]));
Modell anhand einer Abfrage löschen
$deletedRows = app\modle\Flight::where('active', 0)->delete();
Modell kopieren
Sie können die Methode replicate verwenden, um eine neue, noch nicht in der Datenbank gespeicherte Instanz zu kopieren. Diese Methode ist besonders nützlich, wenn Modellinstanzen viele gemeinsame Attribute haben:
$shipping = App\Address::create([
'type' => 'Versand',
'line_1' => '123 Beispielstraße',
'city' => 'Victorville',
'state' => 'CA',
'postcode' => '90001',
]);
$billing = $shipping->replicate()->fill([
'type' => 'Rechnungsstellung'
]);
$billing->save();
Modellvergleich
Manchmal müssen Sie überprüfen, ob zwei Modelle "gleich" sind. Die is-Methode kann verwendet werden, um schnell zu überprüfen, ob zwei Modelle dieselben Primärschlüssel, Tabellen und Datenbankverbindungen haben:
if ($post->is($anotherPost)) {
//
}
Modell-Observer
Verwenden Sie die folgende ReferenzLaravel 中的模型事件与 Observer
Hinweis: Um den Modell-Observer in Eloquent ORM zu verwenden, muss zusätzlich composer require "illuminate/events" importiert werden.
<?php
namespace app\model;
use support\Model;
use app\observer\UserObserver;
class User extends Model
{
public static function boot()
{
parent::boot();
static::observe(UserObserver::class);
}
}