Toidicode.com

Toidicode.com

BASIC TO ADVANCE

Bài 25: Query Builder trong Laravel 8

Phần trước mình đã giới thiệu với mọi người về database trong Laravel 8 và mình có sử dụng class DB thực thi một vài câu lệnh đến databse. Bài này mình sẽ nói thêm về class này cho mọi người cũng thấy sức mạnh của nó trong việc query đến database.

1. Query Builder là gì?

Query builder là một class trong Laravel, cung cấp cho chúng ta các phương thức để làm việc với database một cách thuận tiện hơn.

Class này sử dụng PDO parameter binding để thực thi các câu lệnh, điều này sẽ giúp cho ứng dụng của bạn tránh được các lỗi liên quan đến SQL injection. Chính vì thế các bạn không cần thiết phải làm sạch dữ liệu khi sử dụng query builder.

2. Thực thi câu lệnh trong database.

Vì class này cung cấp rất nhiều các phương thức cho các bạn làm việc với database, nên mình sẽ chỉ giới thiệu những phương thức hay sử dụng thôi còn chi tiết các bạn có thể lên trang chủ để đọc thêm.

Lấy tất cả dữ liệu trong table.

Bạn có thể sử dụng phương thức table để chỉ định table mà bạn muốn thực hiện truy vấn sau đó dùng phương thức get để lấy ra dữ liệu của truy vấn đó.

VD: Lấy hết user trong table users.

use Illuminate\Support\Facades\DB;

$users = DB::table('users')->get();

Phương thức get sẽ trả về một collection chứa kết quả trả về của câu query. với các dữ liệu của từng row là PHP stdClass.

VD: in ra name của các users lấy được ở ví dụ trên.

use Illuminate\Support\Facades\DB;

$users = DB::table('users')->get();

foreach ($users as $user) {
    echo $user->name;
}

Lấy ra một dùng dữ liệu trong table.

Nếu muốn lấy ra một dòng dữ liệu các bạn có thể sử dụng phương thức first. Phương thức này sẽ limit kết quả trả về của query, phương thức này sẽ trả về một PHP stdClass nếu có dữ liệu trả về và nếu như không có kết quả nào trả về thì nó sẽ là null

VD: Lấy ra user đầu tiên trong bảng users.

$user = DB::table('users')->first();

VD: Lấy ra user đầu tiên có tên là "Tai".

$user = DB::table('users')->where('name', 'Tai')->first();

Hoặc nếu như bạn muốn, lấy ra một dòng data theo cột id các bạn có thể sử dụng phương thức find.

VD: Lấy ra user có id=3.

$user = DB::table('users')->find(3);

Chunk giá trị trả về.

Đôi lúc bạn cần lấy ra số lượng bản ghi lớn trong database, nhưng lại sợ điều đó làm quá tải cho database, bạn có thể sử dụng phương thức chunk để chia nhỏ data mỗi lần lấy.

VD: Chia nhỏ data, mỗi lần lấy 100 bản ghi trong bảng users.

use Illuminate\Support\Facades\DB;

DB::table('users')->orderBy('id')->chunk(100, function ($users) {
    foreach ($users as $user) {
        //
    }
});

Nếu như bạn muốn ngừng việc chunk data lại tại một thời điểm nào đó. Bạn có thể return false để báo cho Laravel biết để dừng lại.

VD:

DB::table('users')->orderBy('id')->chunk(100, function ($users) {
    foreach ($users as $user) {
        if ($users->id) {
            return false; // Stop chunking
        }

        // code
    }
});

Đếm số lượng bản ghi trả về.

Để đếm số lượng bản ghi của table các bạn sử dụng phương thức count.

VD:

use Illuminate\Support\Facades\DB;

$users = DB::table('users')->count();

Tương tự bạn có thể sử dụng các phương thức max, min, avgsum để lấy ra các giá trị lớn nhất, nhỏ nhất, trung bình và tổng giá trị của một cột nào đó trong table.

VD:

$price = DB::table('orders')->max('price');

$price = DB::table('orders')->min('price');

$price = DB::table('orders')->avg('price');

$price = DB::table('orders')->sum('price');

Kiểm tra sự tồn tại của dữ liệu.

Bạn có thể kiểm tra xem câu query kia có tồn tại giá trị trong database hay không bằng phương thức exist. Phương thức này sẽ trả về true nếu có dữ liệu matching với câu query.

VD:

if (DB::table('orders')->where('finalized', 1)->exists()) {
    // ...
}

Ngược lại bạn có thể sử dụng phương thức doesntExist để kiểm tra dữ liệu không tồn tại, nếu không tồn tại dữ liệu matching với câu query nó sẽ trả về true.

VD:

if (DB::table('orders')->where('finalized', 1)->doesntExist()) {
    // ...
}

Slelect data trong table.

Để xác định các column sẽ lấy ra trong database các bạn sử dụng phương thức select.

VD: select ra name, email của table users.

use Illuminate\Support\Facades\DB;

$users = DB::table('users')
            ->select('name', 'email')
            ->get();

Hoặc bạn cũng có thể sử dụng dữ liệu truyền vào là mảng

VD:

$users = DB::table('users')
            ->select(['name', 'email'])
            ->get();

Bạn cũng có thể as được column name trong phương thức select.

VD: select ra name, email của table users, và đổi column email thành user_email.

use Illuminate\Support\Facades\DB;

$users = DB::table('users')
            ->select('name', 'email as user_email')
            ->get();

Trong trường hợp bạn đã sử dụng phương thức select để thiết lập các column data trả về rồi và muốn add thêm column khác nữa bạn có thể sử dụng phương thức addSelect.

VD:

$query = DB::table('users')->select('name');

$users = $query->addSelect('age')->get();

Bạn cũng có thể query distint dữ liệu trong database bằng cách sử dụng phương thức distinct.

VD:

$users = DB::table('users')->distinct()->get();

Nếu như select của bạn chứa các SQL logic bạn có thể sử dụng phương thức raw để đưa logic đó vào trong câu query.

VD:

$users = DB::table('users')
             ->select(DB::raw('count(*) as user_count, status'))
             ->where('status', '<>', 1)
             ->groupBy('status')
             ->get();

Chú ý: Câu lệnh này sẽ đưa trực tiếp những gì bạn truyền vào trong database, chính vì thế bạn nên cân nhắc kỹ nếu không sẽ bị dính lỗ hổng SQL injection.

Join table trong database.

Bạn có thể sử dụng phương join để join table trong database.

VD:

$users = DB::table('users')
            ->join('contacts', 'users.id', '=', 'contacts.user_id')
            ->join('orders', 'users.id', '=', 'orders.user_id')
            ->select('users.*', 'contacts.phone', 'orders.price')
            ->get();

Tương tự, bạn có thể sử dụng phương thức leftJoin, rightJoincrrossJoin để thực hiện LEFT JOIN, RIGHT JOINCROSS JOIN trong Database.

VD:

$users = DB::table('users')
            ->leftJoin('posts', 'users.id', '=', 'posts.user_id')
            ->get();

$users = DB::table('users')
            ->rightJoin('posts', 'users.id', '=', 'posts.user_id')
            ->get();

$sizes = DB::table('sizes')
            ->crossJoin('colors')
            ->get();

Nếu trong câu lệnh join của các bạn chứa nhiều điều kiện phức tạp, bạn có thể truyền tham số thứ 2 là một closure để thực thi logic.

VD:

DB::table('users')
        ->join('contacts', function ($join) {
            $join->on('users.id', '=', 'contacts.user_id')
                 ->where('contacts.user_id', '>', 5);
        })
        ->get();

Tương tự bạn cũng có thể join với một sub query khác.

VD:

$latestPosts = DB::table('posts')
                   ->select('user_id', DB::raw('MAX(created_at) as last_post_created_at'))
                   ->where('is_published', true)
                   ->groupBy('user_id');

$users = DB::table('users')
        ->joinSub($latestPosts, 'latest_posts', function ($join) {
            $join->on('users.id', '=', 'latest_posts.user_id');
        })->get();

Union qurey.

Bạn có thể thực thi câu lệnh UNION trong database bằng cách sử dụng phương thức union.

VD:

use Illuminate\Support\Facades\DB;

$first = DB::table('users')
            ->whereNull('first_name');

$users = DB::table('users')
            ->whereNull('last_name')
            ->union($first)
            ->get();

Where query.

Bạn có thể sử dụng phương thức where để thực hiện câu lệnh WHERE trong database.

VD:

$users = DB::table('users')
                ->where('votes', '=', 100)
                ->where('age', '>', 35)
                ->get();

Khi bạn sử dụng phương thức where nhiều lần thì Laravel sẽ tự convert các lần sau thành "and where".

Nếu bạn sử dụng phương thức where với 2 tham số truyền vào thì Laravel sẽ tự hiểu nó là =.

VD:

DB::table('users')->where('votes', '=', 100);

// Tương tự

DB::table('users')->where('votes', 100);

Bạn cũng có thể tryền một array vào trong phương thức where.

VD:

DB::table('users')->where('votes', 100)->where('age', 15);

// Tương tự

DB::table('users')->where(['votes' => 100, 'age' => 15]);

Nếu bạn muốn sử dụng "OR WHERE" trong database bạn có thể sử dụng phương thức orWhere.

VD:

$users = DB::table('users')
                    ->where('votes', '>', 100)
                    ->orWhere('name', 'John')
                    ->get();

Bạn có thể truyền vào trong orWhere một closure chứa các câu query khác.

VD:

$users = DB::table('users')
            ->where('votes', '>', 100)
            ->orWhere(function($query) {
                $query->where('name', 'Abigail')
                      ->where('votes', '>', 50);
            })
            ->get();

Tương tự bạn có thể sử dụng whereNull, whereNotNull, orWhereNullorWhereNotNull Để thực thi các câu lệnh WHERE IS NULL, WHERE IS NOT NULL, OR WHERE IS NULL, OR WHERE IS NOT NULL trong database.

VD:

$users = DB::table('users')
                ->whereNull('updated_at')
                ->get();

Bạn cũng có thể sử dụng các phương thức whereDate, whereMonth, whereDay, whereYear, whereTime để truy vấn với các column dữ liệu date.

VD:

$users = DB::table('users')
                ->whereDate('created_at', '2016-12-31')
                ->get();

$users = DB::table('users')
                ->whereMonth('created_at', '12')
                ->get();

$users = DB::table('users')
                ->whereDay('created_at', '31')
                ->get();

$users = DB::table('users')
                ->whereYear('created_at', '2016')
                ->get();

$users = DB::table('users')
                ->whereTime('created_at', '=', '11:20:45')
                ->get();

3. Lời kết.

Bài này mình mới chỉ trình bày một phần về Query Builder trong Laravel, những method khác ít dùng mình không nói ở bài này vì nó cũng khá nhiều, nên các bạn cần có thể lên đây để xem.

Đăng ký nhận tin.

Chúng tôi chỉ gửi tối đa 2 lần trên 1 tháng. Tuyên bố không spam mail!

Vũ Thanh Tài

About author
The best way to learn is to share
Xem tất cả bài đăng

0 Comments

Bài viết chưa có ai bình luận, hãy là người đầu tiên đi bạn!

Bình luận

Captcha