Laravel Tutorial

Bài 23: Query Builder trong Laravel

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

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

Ví dụ: Lấy hết user trong table users

use Illuminate\Support\Facades\DB;

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

// In ra giá trị
foreach ($users as $user) {
    echo $user->name;
}

# Lấy dữ liệu theo hàng

Ví dụ: Lấy ra user đầu tiên trong bảng users

use Illuminate\Support\Facades\DB;

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

Ví dụ: Lấy ra user đầu tiên có tên là "John"

use Illuminate\Support\Facades\DB;

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

# Lấy dữ liệu theo cột

Ví dụ: Lấy ra user có id=3

use Illuminate\Support\Facades\DB;

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

# Chi nhỏ dữ liệu lấy 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

Ví dụ: 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

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ề

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 maxminavg và sum để 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

use Illuminate\Support\Facades\DB;

$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

use Illuminate\Support\Facades\DB;

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

# Slelect data trong table

Ví dụ: select ra nameemail của table users

use Illuminate\Support\Facades\DB;

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

Hoặc

use Illuminate\Support\Facades\DB;

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

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

Ví dụ: select ra nameemail 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

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

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

Bạn cũng có thể query distint (dữ liệu không trùng nhau) dữ liệu trong database bằng cách sử dụng phương thức distinct

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

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

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

# Join table trong database

$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 leftJoinrightJoin và crrossJoin để thực hiện LEFT JOINRIGHT JOIN và CROSS JOIN trong Database

$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 code

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

$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

UNION được sử dụng để kết hợp tập hợp kết quả của hai hoặc nhiều câu lệnh SELECT

use Illuminate\Support\Facades\DB;

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

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

# Where query

$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à =.

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

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

$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

$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 whereNullwhereNotNullorWhereNull và orWhereNotNull để thực thi các câu lệnh WHERE IS NULLWHERE IS NOT NULLOR WHERE IS NULLOR WHERE IS NOT NULL trong database

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

Bạn cũng có thể sử dụng các phương thức whereDatewhereMonthwhereDaywhereYearwhereTime để truy vấn với các column dữ liệu date

$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();

 

2 Comments

Leave a Comment