Laravel 5.5 Database

DATABASE(数据库)

// 原生SQL
    (SELECT)
        $users = DB::select('select * from users where active = ?', [1]);
        $results = DB::select('select * from users where id = :id', ['id' => 1]);
    (INSERT)
        DB::insert('insert into users (id, name) values (?, ?)', [1, '学院君']);
    (UPDATE)
        $affected = DB::update('update users set votes = 100 where name = ?', ['学院君']);
    (DELETE)
        $deleted = DB::delete('delete from users');
    (运行一个通用语句)
        有些数据库语句不返回任何值,比如新增表,修改表,删除表等,对于这种类型的操作,可以使用 DB 门面的 statement 方法
        DB::statement('drop table users');


// 查询构造器
    (从一张表中取出所有行)
        $users = DB::table('users')->get();  // get 方法获取表中所有记录
    
    (从一张表中获取一行/一列)
        $user = DB::table('users')->where('name', 'John')->first();  // 返回单个 StdClass 对象
        $email = DB::table('users')->where('name', 'John')->value('email');  // 返回指定列的值
    
    (获取数据列值列表)
        $titles = DB::table('roles')->pluck('title');  // 获取包含单个列值的数组
        $roles = DB::table('roles')->pluck('title', 'name');
    
    (组块结果集)
        处理成千上百条数据库记录,可以考虑使用 chunk 方法,该方法一次获取结果集的一小块,然后传递每一小块数据到闭包函数进行处理,该方法在编写处理大量数据库记录的 Artisan 命令的时候非常有用
        DB::table('users')->orderBy('id')->chunk(100, function($users) {
            foreach ($users as $user) {
                //
            }
        });
    
        你可以通过从闭包函数中返回 false 来终止组块的运行
        DB::table('users')->orderBy('id')->chunk(100, function($users) {
            // 处理结果集...
            return false;
        });
    
    (聚合函数)
        count, max, min, avg 和 sum ...
        $users = DB::table('users')->count();
        $price = DB::table('orders')->max('price');
    
    (SELECT)
        * 指定查询子句
            $users = DB::table('users')->select('name', 'email as user_email')->get();
            $users = DB::table('users')->distinct()->get();  // distinct 方法允许你强制查询返回不重复的结果集
    
        * Where子句
            $users = DB::table('users')->where('votes', '=', 100)->get();
    
            $users = DB::table('users')->where([
                ['status', '=', '1'],
                ['subscribed', '<>', '1'],
            ])->get();
    
            $users = DB::table('users')
                        ->whereBetween('votes', [1, 100])->get();
    
            $users = DB::table('users')
                        ->whereNotBetween('votes', [1, 100])
                        ->get();
    
            $users = DB::table('users')
                        ->whereIn('id', [1, 2, 3])
                        ->get();
    
            $users = DB::table('users')
                        ->whereNotIn('id', [1, 2, 3])
                        ->get();
    
            $users = DB::table('users')
                        ->whereNull('updated_at')
                        ->get();
    
            $users = DB::table('users')
                        ->whereNotNull('updated_at')
                        ->get();
    
            $users = DB::table('users')
                        ->whereDate('created_at', '2016-10-10')
                        ->get();
    
            $users = DB::table('users')
                        ->whereMonth('created_at', '10')
                        ->get();
    
            $users = DB::table('users')
                        ->whereDay('created_at', '10')
                        ->get();
    
            $users = DB::table('users')
                        ->whereYear('created_at', '2017')
                        ->get();
    
            $users = DB::table('users')
                        ->whereColumn('first_name', 'last_name')
                        ->get();
    
        * or 语句
            $users = DB::table('users')
                            ->where('votes', '>', 100)
                            ->orWhere('name', 'John')
                            ->get();
    
        * 排序、分组、限定
            $users = DB::table('users')
                    ->orderBy('name', 'desc')
                    ->get();
    
            $user = DB::table('users')
                    ->latest()
                    ->first(); // latest 和 oldest 方法允许你通过日期对结果进行排序,默认情况下,结果集根据 created_at 字段进行排序,或者,你可以按照你想要排序的字段作为字段名传入
    
            $randomUser = DB::table('users')
                    ->inRandomOrder()
                    ->first();  // inRandomOrder 方法可用于对查询结果集进行随机排序,比如,你可以用该方法获取一个随机用户
    
            $users = DB::table('users')
                    ->groupBy('account_id')
                    ->having('account_id', '>', 100)
                    ->get();
    
            $users = DB::table('users')->skip(10)->take(5)->get(); // 限定查询返回的结果集的数目,查询中跳过给定数目的结果
    
    (INSERT)
        DB::table('users')->insert(
            ['email' => '[email protected]', 'votes' => 0]
        );
        DB::table('users')->insert([
            ['email' => '[email protected]', 'votes' => 0],
            ['email' => '[email protected]', 'votes' => 0]
        ]);
        $id = DB::table('users')->insertGetId(
            ['email' => '[email protected]', 'votes' => 0]
        );
    
    (UPDATE)
        DB::table('users')
            ->where('id', 1)
            ->update(['votes' => 1]);
        DB::table('users')->increment('votes');
        DB::table('users')->increment('votes', 5);  // 参数二为步长
        DB::table('users')->decrement('votes');
        DB::table('users')->decrement('votes', 5);  // 参数二为步长
        DB::table('users')->increment('votes', 1, ['name' => 'John']);  // 在操作过程中你还可以指定额外的列进行更新
    
    (DELETE)
        DB::table('users')->delete();
        DB::table('users')->where('votes', '>', 100)->delete();
        DB::table('users')->truncate(); // 清除整张表,并将自增 ID 置为 0
    
    (悲观锁 & 乐观锁)
        * 悲观锁
            DB::table('users')->where('votes', '>', 100)->sharedLock()->get();
            DB::table('users')->where('votes', '>', 100)->lockForUpdate()->get();


// Eloquent ORM
    
    (获取单个模型/聚合结果)
        $flight = App\Flight::find(1);  // 通过主键获取模型...
        $flights = App\Flight::find([1, 2, 3]);
        $flight = App\Flight::where('active', 1)->first();  // 获取匹配查询条件的第一个模型...
        $model = App\Flight::findOrFail(1);  // 获取查询到的第一个结果,如果没有任何查询结果,异常将会被抛出
        $count = App\Flight::where('active', 1)->count();
        $max = App\Flight::where('active', 1)->max('price');
        ...
    
    (插入/更新模型)
        * 插入
             $flight = new Flight;
             $flight->name = $request->name;
             $flight->save();
    
        * 批量更新
            App\Flight::where('active', 1)
                  ->where('destination', 'San Diego')
                  ->update(['delayed' => 1]);
    
        * 批量复制
            $flight = App\Flight::create(['name' => 'Flight 10']);
    
        * 其他创建方法
            firstOrNew 方法和 firstOrCreate 方法一样先尝试在数据库中查找匹配的记录,如果没有找到,则返回一个新的模型实例。需要注意的是,通过 firstOrNew 方法返回的模型实例并没有持久化到数据库中,你还需要调用 save 方法手动持久化
    
            $flight = App\Flight::firstOrCreate(['name' => 'Flight 10']);  // 通过属性获取航班, 如果不存在则创建...
    
            $flight = App\Flight::firstOrNew(['name' => 'Flight 10']);  // 通过属性获取航班, 如果不存在初始化一个新的实例...
    
            $flight = App\Flight::updateOrCreate(
                ['departure' => 'Oakland', 'destination' => 'San Diego'],
                ['price' => 99]
            );  // 如果模型已存在则更新,否则创建新模型的场景, updateOrCreate 方法会持久化模型,所以无需调用 save()
    
    (删除模型)
        $flight = App\Flight::find(1);
        $flight->delete();
    
        * 通过主键删除模型
            App\Flight::destroy(1);
            App\Flight::destroy([1, 2, 3]);
            App\Flight::destroy(1, 2, 3);
    
        * 通过查询删除模型
            $deletedRows = App\Flight::where('active', 0)->delete();
    
    (软删除)
        $table->softDeletes(); // 添加 deleted_at 列到数据表
        if ($flight->trashed()) {
            // 判断给定模型实例是否被软删除
        }
        
        * 查询被软删除的模型
            
            // 包含软删除模型
            $flights = App\Flight::withTrashed()
                        ->where('account_id', 1)
                        ->get();
            $flight->history()->withTrashed()->get();
            
            // 只获取软删除模型
            $flights = App\Flight::onlyTrashed()
                        ->where('airline_id', 1)
                        ->get();
            
            // 恢复软删除模型
            $flight->restore();
            App\Flight::withTrashed()
                ->where('airline_id', 1)
                ->restore();
            $flight->history()->restore();
            
            // 永久删除模型
            $flight->forceDelete();
            $flight->history()->forceDelete();

// 查询作用域
    * 全局作用域
        全局作用域可以提供一种方便的、简单的方式来确保给定模型的每个查询都有特定的条件约束。
        
        // 编写全局作用域
            自定义全局作用域很简单,首先定义一个实现 Illuminate\Database\Eloquent\Scope 接口的类,该接口要求你实现一个方法:apply。需要的话可以在 apply 方法中添加 where 条件到查询:
            <?php
            namespace App\Scopes;

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

            class AgeScope implements Scope
            {
                /**
                 * 应用作用域到给定的Eloquent查询构建器.
                 *
                 * @param  \Illuminate\Database\Eloquent\Builder  $builder
                 * @param  \Illuminate\Database\Eloquent\Model  $model
                 * @return void
                 * @translator laravelacademy.org
                 */
                public function apply(Builder $builder, Model $model)
                {
                    return $builder->where('age', '>', 200);
                }
            }
        
        // 应用全局作用域
            要将全局作用域应用到模型,需要重写给定模型的 boot 方法并使用 addGlobalScope 方法:
            <?php
            namespace App;

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

            class User extends Model
            {
                /**
                 * 模型的“启动”方法.
                 *
                 * @return void
                 */
                protected static function boot()
                {
                    parent::boot();

                    static::addGlobalScope(new AgeScope);
                }
            }
    
    *本地作用域
        本地作用域允许我们定义通用的约束集合以便在应用中复用
        // 创建本地作用域
            <?php

            namespace App;

            use Illuminate\Database\Eloquent\Model;

            class User extends Model
            {
                /**
                 * 只包含活跃用户的查询作用域
                 *
                 * @return \Illuminate\Database\Eloquent\Builder
                 */
                public function scopePopular($query)
                {
                    return $query->where('votes', '>', 100);
                }

                /**
                 * 只包含激活用户的查询作用域
                 *
                 * @return \Illuminate\Database\Eloquent\Builder
                 */
                public function scopeActive($query)
                {
                    return $query->where('active', 1);
                }
            }
        
        // 使用本地作用域
            $users = App\User::popular()->active()->orderBy('created_at')->get();


// 关联关系
    $user->posts()->where('active', 1)->get();
    * 关联方法 Vs. 动态属性
        $user = App\User::find(1);
        foreach ($user->posts as $post) {
            //
        }
    
    * 查询存在的关联关系
        $posts = App\Post::has('comments')->get();  // 获取所有至少有一条评论的文章...
        $posts = Post::has('comments', '>=', 3)->get();  // 获取所有至少有三条评论的文章...
        $posts = Post::has('comments.votes')->get();  // 获取所有至少有一条评论获得投票的文章...
        $posts = Post::whereHas('comments', function ($query) {
            $query->where('content', 'like', 'foo%');
        })->get();  // 获取所有至少有一条评论包含foo字样的文章
    
    * 无关联结果查询
        $posts = App\Post::doesntHave('comments')->get();
        $posts = Post::whereDoesntHave('comments', function ($query) {
            $query->where('content', 'like', 'foo%');
        })->get();
    
    * 统计关联模型
        $posts = App\Post::withCount('comments')->get();
        foreach ($posts as $post) {
            echo $post->comments_count;
        }
    
    * 渴求式加载
        渴求式加载缓解 N+1 查询问题
        $books = App\Book::with('author')->get();
        foreach ($books as $book) {
            echo $book->author->name;
        }
        $books = App\Book::with('author', 'publisher')->get();  // 渴求式加载多个关联关系
        $books = App\Book::with('author.contacts')->get();  // 嵌套的渴求式加载
        $users = App\Book::with('author:id,name')->get();   // 渴求式加载指定字段,使用这个特性时,id 字段是必须列出的。
        $users = App\User::with(['posts' => function ($query) {
            $query->where('title', 'like', '%first%');
        }])->get();  // 带条件约束的渴求式加载

        $books = App\Book::all();  // 懒惰渴求式加载
        if ($someCondition) {
            $books->load('author', 'publisher');
        }
    
    * 插入 & 更新关联模型
        · save 方法
            $comment = new App\Comment(['message' => 'A new comment.']);
            $post = App\Post::find(1);
            $post->comments()->save($comment);

            $post = App\Post::find(1);
            $post->comments()->saveMany([
                new App\Comment(['message' => 'A new comment.']),
                new App\Comment(['message' => 'Another comment.']),
            ]);
    
        · create 方法
            $post = App\Post::find(1);
            $comment = $post->comments()->create([
                'message' => 'A new comment.',
            ]);

            $post = App\Post::find(1);
            $post->comments()->createMany([
                [
                    'message' => 'A new comment.',
                ],
                [
                    'message' => 'Another new comment.',
                ],
            ]);
    
    * 多对多关联

// 数据库迁移
    (检查表/列是否存在)
        if (Schema::hasTable('users')) {
            //
        }
        if (Schema::hasColumn('users', 'email')) {
            //
        }
    
    (重命名/删除表)
        Schema::rename($from, $to);  // 重命名
        Schema::drop('users');  // 删除表
        Schema::dropIfExists('users'); // 删除表
    
    (修改数据列)
        $table->string('name', 50)->change();
        $table->renameColumn('from', 'to');
    
    (删除数据列)
        $table->dropColumn('votes');
        $table->dropColumn(['votes', 'avatar', 'location']);

// 数据库事务
    (DB门面)
        想要在一个数据库事务中运行一连串操作,可以使用 DB 门面的 transaction 方法,使用 transaction 方法时不需要手动回滚或提交:如果事务闭包中抛出异常,事务将会自动回滚;如果闭包执行成功,事务将会自动提交
        DB::transaction(function () {
            DB::table('users')->update(['votes' => 1]);
            DB::table('posts')->delete();
        });
    
    (手动使用事务)
        如果你想要手动开启事务从而对回滚和提交有更好的控制,可以使用 DB 门面的 beginTransaction 方法
        DB::beginTransaction();
        DB::rollBack();
        DB::commit();
    
    (处理死锁)
        数据库死锁指的是有两个或两个以上数据库操作相互依赖,一方需要等待另一方退出才能获取资源,但是没有一方提前退出,就会造成死锁,数据库事务容易造成的一个副作用就是死锁。为此 transaction 方法接收一个可选参数作为第二个参数,用于定义死锁发生时事务的最大重试次数。如果尝试次数超出指定值,会抛出异常
        
        DB::transaction(function () {
            DB::table('users')->update(['votes' => 1]);
            DB::table('posts')->delete();
        }, 5);

猜你喜欢

转载自blog.csdn.net/qq_37910492/article/details/84545375