Laravel 数据库操作:Eloquent ORM详解

数据库操作:Eloquent ORM详解

在本章中,我们将详细介绍Laravel的Eloquent ORM,讲解如何定义模型、执行数据库查询、以及建立模型之间的关系。通过学习本章,你将能够高效地与数据库进行交互。

1. Eloquent ORM简介

Eloquent ORM(对象关系映射)是Laravel自带的ORM,用于简化数据库操作。Eloquent允许你使用模型类与数据库表进行交互,每个模型类通常对应一个数据库表。

1.1 创建模型

你可以使用 artisan 命令创建一个模型:

php artisan make:model Post

上述命令将在 app/Models 目录下创建一个名为 Post.php 的模型文件。你也可以使用 -m 选项同时创建模型和迁移文件:

php artisan make:model Post -m
1.2 定义模型

模型类通常继承自 Illuminate\Database\Eloquent\Model。以下是一个基本的模型类:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    // 模型代码
}

Eloquent将默认使用复数形式的类名作为数据库表名,例如,Post 模型将使用 posts 表。如果你的表名不同,可以在模型中指定:

class Post extends Model
{
    protected $table = 'my_posts';
}

2. 数据库迁移

数据库迁移是定义数据库结构的方式,它们是可版本控制的文件。让我们来创建和应用一个简单的迁移。

2.1 创建迁移

如果你在创建模型时使用了 -m 选项,迁移文件会自动生成。你也可以单独生成迁移文件:

php artisan make:migration create_posts_table

迁移文件将存储在 database/migrations 目录下。

2.2 定义迁移

打开迁移文件 create_posts_table,添加以下代码:

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreatePostsTable extends Migration
{
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('content');
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('posts');
    }
}

up 方法定义了迁移中要执行的操作,而 down 方法定义了回滚迁移时要执行的操作。

2.3 运行迁移

运行以下命令来执行迁移:

php artisan migrate

此命令将创建 posts 表。

3. Eloquent 模型基础操作

Eloquent 提供了一些基本的数据库操作方法,如创建、读取、更新和删除(CRUD)。

3.1 创建数据

你可以使用模型的 create 方法来插入数据。确保在模型中定义 fillable 属性,以防止批量赋值漏洞:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    protected $fillable = ['title', 'content'];
}

然后,你可以使用以下代码创建一条记录:

use App\Models\Post;

$post = Post::create([
    'title' => 'First Post',
    'content' => 'This is the content of the first post.',
]);
3.2 读取数据

你可以使用模型的 all 方法读取所有数据,或使用 find 方法按主键查找数据:

$posts = Post::all();

$post = Post::find(1);

你还可以使用查询构建器方法:

$posts = Post::where('title', 'First Post')->get();
3.3 更新数据

你可以使用模型实例的 save 方法来更新数据:

$post = Post::find(1);
$post->title = 'Updated Post Title';
$post->save();

或者使用 update 方法:

Post::where('id', 1)->update(['title' => 'Updated Post Title']);
3.4 删除数据

你可以使用模型实例的 delete 方法来删除数据:

$post = Post::find(1);
$post->delete();

或者使用 destroy 方法按主键删除数据:

Post::destroy(1);

4. 模型关系

Eloquent 提供了多种类型的模型关系,包括一对一、一对多和多对多关系。

4.1 一对一关系

一对一关系是指一个模型对应另一个模型。例如,一个用户有一个手机号码。

创建相关模型:

php artisan make:model User -m
php artisan make:model Phone -m

定义迁移:

class CreateUsersTable extends Migration
{
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('users');
    }
}

class CreatePhonesTable extends Migration
{
    public function up()
    {
        Schema::create('phones', function (Blueprint $table) {
            $table->id();
            $table->string('phone_number');
            $table->foreignId('user_id')->constrained()->onDelete('cascade');
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('phones');
    }
}

运行迁移:

php artisan migrate

User 模型中定义关系:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    public function phone()
    {
        return $this->hasOne(Phone::class);
    }
}

Phone 模型中定义关系:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Phone extends Model
{
    public function user()
    {
        return $this->belongsTo(User::class);
    }
}

使用关系:

$user = User::find(1);
$phone = $user->phone;

$phone = Phone::find(1);
$user = $phone->user;
4.2 一对多关系

一对多关系是指一个模型对应多个模型。例如,一个博客文章有多个评论。

创建相关模型:

php artisan make:model Post -m
php artisan make:model Comment -m

定义迁移:

class CreatePostsTable extends Migration
{
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('content');
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('posts');
    }
}

class CreateCommentsTable extends Migration
{
    public function up()
    {
        Schema::create('comments', function (Blueprint $table) {
            $table->id();
            $table->text('content');
            $table->foreignId('post_id')->constrained()->onDelete('cascade');
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('comments');
    }
}

运行迁移:

php artisan migrate

Post 模型中定义关系:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    public function comments()
    {
        return $this->hasMany(Comment::class);
    }
}

Comment 模型中定义关系:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Comment extends Model
{
    public function post()
    {
        return $this->belongsTo(Post::class);
    }
}

使用关系:

$post = Post::find(1);
$comments = $post->comments;

$comment = Comment::find(1);
$post = $comment->post;
4.3 多对多关系

多对多关系是指多个模型对应另一个多个模型。例如,一个学生可以参加多个课程,一个课程可以有多个学生。

创建相关模型:

php artisan make:model Student -m
php artisan make:model Course -m
php artisan make:migration create_course_student_table --create=course_student

定义迁移:

class CreateStudentsTable extends Migration
{
    public function up()
    {
        Schema::create('students', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('students');
    }
}

class CreateCoursesTable extends Migration
{
    public function up()
    {
        Schema::create('courses', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('courses');
    }
}

class CreateCourseStudentTable extends Migration
{
    public function up()
    {
        Schema::create('course_student', function (Blueprint $table) {
            $table->id();
            $table->foreignId('student_id')->constrained()->onDelete('cascade');
            $table->foreignId('course_id')->constrained()->onDelete('cascade');
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('course_student');
    }
}

运行迁移:

php artisan migrate

Student 模型中定义关系:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Student extends Model
{
    public function courses()
    {
        return $this->belongsToMany(Course::class);
    }
}

Course 模型中定义关系:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Course extends Model
{
    public function students()
    {
        return $this->belongsToMany(Student::class);
    }
}

使用关系:

$student = Student::find(1);
$courses = $student->courses;

$course = Course::find(1);
$students = $course->students;

5. Eloquent事件

Eloquent 提供了模型事件,你可以在模型的生命周期中执行一些操作。例如,当模型被创建、更新或删除时触发相应的事件。

5.1 定义事件

你可以在模型中定义事件,例如 creatingcreatedupdatingupdateddeletingdeleted

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    protected static function booted()
    {
        static::creating(function ($post) {
            // 在模型创建之前执行的操作
        });

        static::created(function ($post) {
            // 在模型创建之后执行的操作
        });
    }
}
5.2 使用事件类

你也可以使用事件类来组织你的事件处理逻辑:

namespace App\Providers;

use App\Models\Post;
use App\Observers\PostObserver;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Post::observe(PostObserver::class);
    }
}

app/Observers 目录下创建一个观察者类:

namespace App\Observers;

use App\Models\Post;

class PostObserver
{
    public function creating(Post $post)
    {
        // 在模型创建之前执行的操作
    }

    public function created(Post $post)
    {
        // 在模型创建之后执行的操作
    }
}

6. Eloquent作用域

作用域是一种将常用的查询逻辑封装在模型中的方式,使得代码更具可读性和重用性。

6.1 本地作用域

本地作用域使用模型的方法定义。以下是一个示例:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    public function scopePopular($query)
    {
        return $query->where('views', '>', 100);
    }
}

你可以使用本地作用域来查询数据:

$popularPosts = Post::popular()->get();
6.2 全局作用域

全局作用域应用于模型的所有查询。以下是一个示例:

namespace App\Scopes;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope;

class ActiveScope implements Scope
{
    public function apply(Builder $builder, Model $model)
    {
        $builder->where('status', 'active');
    }
}

在模型中应用全局作用域:

namespace App\Models;

use App\Scopes\ActiveScope;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    protected static function booted()
    {
        static::addGlobalScope(new ActiveScope);
    }
}

你可以使用 withoutGlobalScope 方法临时禁用全局作用域:

$users = User::withoutGlobalScope(ActiveScope::class)->get();

7. 序列化

Eloquent 模型可以轻松地转换为数组或JSON,这在构建API时非常有用。

7.1 转换为数组

你可以使用 toArray 方法将模型转换为数组:

$post = Post::find(1);

$array = $post->toArray();
7.2 转换为JSON

你可以使用 toJson 方法将模型转换为JSON:

$post = Post::find(1);

$json = $post->toJson();

也可以直接返回模型实例来自动转换为JSON:

return Post::find(1);

总结

在本章中,我们详细介绍了Laravel的Eloquent ORM,包括模型定义、数据库迁移、基本CRUD操作、模型关系、事件、作用域和序列化。通过这些知识,你可以高效地与数据库进行交互,并构建复杂的数据模型。在接下来的章节中,我们将探讨Laravel的中间件和用户认证。

希望这篇文章能帮助你更好地理解Laravel的Eloquent ORM,欢迎继续关注后续的教学文章!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值