在 Laravel 框架中,模型与数据库 是最核心的部分之一。模型是 Laravel 与数据库交互的主要方式,而数据库操作则通过 Laravel 的 Eloquent ORM (对象关系映射)实现。Eloquent 提供了一个非常强大且直观的方式来处理数据,使得与数据库的交互变得更加简单和高效。
Laravel 使用 Eloquent ORM 作为数据库交互的主要方式。ORM 是一种映射关系型数据库与对象之间的技术,Eloquent ORM 提供了一个非常简洁的 ActiveRecord 实现,让开发者能够直接通过模型操作数据库记录。
在 Laravel 中,模型和数据库迁移通常是一起创建的。模型是与数据库表对应的 PHP 类,而迁移则用来定义数据库表的结构。
php artisan make:model Product -m
这条命令做了两件事:
Product.php
文件,存放在 app/Models
目录。create_products_table.php
,存放在 database/migrations
目录。模型通常定义在 app/Models/
目录中。每个模型都扩展了 Eloquent 的 Model
类,模型的名称通常是数据库表名的单数形式。
示例: app/Models/Product.php
namespace App\\Models;
use Illuminate\\Database\\Eloquent\\Factories\\HasFactory;
use Illuminate\\Database\\Eloquent\\Model;
class Product extends Model
{
use HasFactory; // Laravel 8 引入的工厂特性,用于生成假数据
// 可选:指定数据库表名,如果模型名与表名不同
protected $table = 'products'; // 如果表名不与模型名匹配时
// 可选:指定模型使用的主键
protected $primaryKey = 'id';
// 可选:定义哪些字段可以批量赋值
protected $fillable = ['name', 'description', 'price'];
// 可选:禁用时间戳
public $timestamps = false;
}
迁移文件定义了数据库表的结构。通过迁移,Laravel 提供了一种结构化且可版本化的方式来创建和修改数据库表。
示例: database/migrations/xxxx_xx_xx_create_products_table.php
use Illuminate\\Database\\Migrations\\Migration;
use Illuminate\\Database\\Schema\\Blueprint;
use Illuminate\\Support\\Facades\\Schema;
class CreateProductsTable extends Migration
{
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->text('description');
$table->decimal('price', 8, 2); // 8位数字,2位小数
$table->timestamps(); // 创建 created_at 和 updated_at 时间戳字段
});
}
public function down()
{
Schema::dropIfExists('products');
}
}
up()
方法用于定义迁移逻辑,在运行迁移时创建数据库表。down()
方法用于回滚迁移,删除数据库表。运行迁移以创建数据库表:
php artisan migrate
通过模型,可以非常简便地插入数据。你可以使用模型的 create()
方法插入一条记录,或者先创建一个模型实例,然后调用 save()
方法。
示例: 插入一条记录
use App\\Models\\Product;
// 方法1:通过 create()
Product::create([
'name' => 'Product A',
'description' => 'A description of Product A',
'price' => 99.99
]);
// 方法2:通过模型实例化并调用 save()
$product = new Product();
$product->name = 'Product B';
$product->description = 'A description of Product B';
$product->price = 199.99;
$product->save();
create()
方法需要确保你已经设置了 $fillable
或 $guarded
属性来防止批量赋值漏洞。save()
方法可以将一个模型实例保存到数据库。Eloquent 提供了多种方法来查询数据库中的数据。
获取所有记录:
$products = Product::all(); // 返回所有产品的集合
条件查询:
// 获取价格大于100的所有产品
$products = Product::where('price', '>', 100)->get();
查找单个记录:
$product = Product::find(1); // 根据主键查找产品
查找符合条件的单个记录:
$product = Product::where('name', 'Product A')->first();
分页查询:
$products = Product::paginate(10); // 分页查询,每页显示10条记录
通过模型,你可以轻松地更新数据。
$product = Product::find(1);
$product->price = 149.99;
$product->save();
删除数据的方法同样简单。
$product = Product::find(1);
$product->delete(); // 删除该记录
或者使用 destroy()
方法:
Product::destroy(1); // 直接通过 ID 删除记录
如果你希望删除数据时不立即从数据库中删除,而是标记为“删除”状态,可以启用软删除。软删除可以让你恢复数据。
启用软删除:
use Illuminate\\Database\\Eloquent\\SoftDeletes;
class Product extends Model
{
use SoftDeletes; // 引入软删除功能
// 软删除会自动使用 deleted_at 字段
}
删除记录时会将 deleted_at 字段设置为当前时间:
$product = Product::find(1);
$product->delete(); // 使用软删除
$product = Product::withTrashed()->find(1); // 获取已软删除的记录
$product->restore(); // 恢复软删除的记录
$deletedProducts = Product::onlyTrashed()->get(); // 获取已删除的记录
在 Laravel 中,Eloquent 支持多种类型的数据库表关系:一对多、一对一、多对多等。通过定义模型间的关系,可以非常简便地操作相关数据。
假设一个用户有多篇文章,文章模型和用户模型之间有一对多的关系。
用户模型:
class User extends Model
{
public function posts()
{
return $this->hasMany(Post::class);
}
}
文章模型:
class Post extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}
hasMany()
用于在父模型中定义一对多关系。belongsTo()
用于在子模型中定义反向的一对多关系。多对多关系通常用在两个模型之间,例如用户和角色。
用户模型:
class User extends Model
{
public function roles()
{
return $this->belongsToMany(Role::class);
}
}
角色模型:
class Role extends Model
{
public function users()
{
return $this->belongsToMany(User::class);
}
}
例如,一个用户有一个个人资料。
用户模型:
class User extends Model
{
public function profile()
{
return $this->hasOne(Profile::class);
}
}
在开发过程中,可能需要生成一些假数据进行测试或填充数据库。Laravel 提供了数据库填充功能。
php artisan make:seeder ProductSeeder
然后,你可以在 database/seeders/ProductSeeder.php
中定义数据填充逻辑:
use App\\Models\\Product;
class ProductSeeder extends Seeder
{
public function run()
{
Product::factory()->count(10)->create(); // 使用工厂生成10条数据
}
}
php artisan db:seed --class=ProductSeeder