Khi làm việc với cơ sở dữ liệu trong Laravel, không phải truy vấn nào cũng cần đến Eloquent Model. Với những trường hợp cần xây dựng câu truy vấn linh hoạt, kết hợp nhiều điều kiện hoặc làm việc trực tiếp với bảng dữ liệu, Laravel Query Builder là một công cụ rất hữu ích. Query Builder cung cấp cú pháp PHP dễ đọc để thực hiện các thao tác như lấy dữ liệu, thêm, cập nhật, xóa bản ghi, JOIN, GROUP BY, ORDER BY và nhiều dạng truy vấn khác mà không cần viết toàn bộ SQL thủ công.
Laravel Query Builder là gì?
Laravel Query Builder là một giao diện hỗ trợ xây dựng và thực thi truy vấn cơ sở dữ liệu bằng cú pháp PHP.
Query Builder được truy cập thông qua Facade DB:
use Illuminate\Support\Facades\DB;
Ví dụ lấy toàn bộ sản phẩm:
$products = DB::table('products')->get();
Thay vì viết:
SELECT * FROM products;
Bạn có thể xây dựng truy vấn bằng các phương thức của Query Builder.
Một truy vấn có điều kiện:
$products = DB::table('products')
->where('status', 'active')
->get();
Laravel sẽ xây dựng câu SQL tương ứng và sử dụng cơ chế binding tham số khi thực thi truy vấn, giúp hạn chế các rủi ro liên quan đến việc ghép trực tiếp dữ liệu người dùng vào SQL.
Query Builder đặc biệt hữu ích khi truy vấn có nhiều bảng, nhiều điều kiện hoặc cần tận dụng các câu lệnh SQL nhưng vẫn muốn giữ cú pháp trong PHP dễ quản lý.
Cách sử dụng Laravel Query Builder
Query Builder thường bắt đầu bằng:
DB::table('ten_bang')
Sau đó có thể nối thêm các phương thức để tạo truy vấn.
Ví dụ:
$users = DB::table('users')
->where('status', 'active')
->orderBy('created_at', 'desc')
->get();
Truy vấn trên thực hiện các bước:
- Chọn bảng
users. - Lọc những người dùng có
status = active. - Sắp xếp theo thời gian tạo giảm dần.
- Lấy kết quả.
Đây là cách tiếp cận khá trực quan khi cần xây dựng truy vấn từ nhiều điều kiện.
Các thao tác Query Builder thường dùng
Lấy dữ liệu
Lấy nhiều bản ghi:
$users = DB::table('users')->get();
Lấy một bản ghi:
$user = DB::table('users')->first();
Lấy một bản ghi theo ID:
$user = DB::table('users')
->where('id', 10)
->first();
Nếu chỉ cần một số cột:
$users = DB::table('users')
->select('id', 'name', 'email')
->get();
Có thể sử dụng value() để lấy một giá trị:
$email = DB::table('users')
->where('id', 10)
->value('email');
Lọc dữ liệu với where()
where() là một trong những phương thức được sử dụng nhiều nhất:
$products = DB::table('products')
->where('price', '>', 100000)
->get();
Có thể kết hợp nhiều điều kiện:
$products = DB::table('products')
->where('status', 'active')
->where('price', '>', 100000)
->get();
Hoặc sử dụng orWhere():
$products = DB::table('products')
->where('status', 'active')
->orWhere('featured', true)
->get();
Với dữ liệu được nhập từ người dùng, nên truyền giá trị qua các phương thức điều kiện của Query Builder thay vì tự nối chuỗi SQL.
Sắp xếp và giới hạn kết quả
Sắp xếp:
$users = DB::table('users')
->orderBy('created_at', 'desc')
->get();
Giới hạn số lượng:
$users = DB::table('users')
->limit(10)
->get();
Có thể kết hợp với offset():
$users = DB::table('users')
->offset(10)
->limit(10)
->get();
Trong các trang danh sách, Query Builder cũng hỗ trợ paginate() để phân trang kết quả:
$users = DB::table('users')->paginate(20);
Query Builder với JOIN
Một trong những điểm mạnh của Query Builder là khả năng kết hợp dữ liệu từ nhiều bảng.
Ví dụ lấy danh sách sản phẩm cùng tên danh mục:
$products = DB::table('products')
->join('categories', 'products.category_id', '=', 'categories.id')
->select(
'products.id',
'products.name',
'categories.name as category_name'
)
->get();
Có thể sử dụng nhiều loại JOIN tùy nhu cầu:
->join()
->leftJoin()
->rightJoin()
Ví dụ với leftJoin():
$products = DB::table('products')
->leftJoin(
'categories',
'products.category_id',
'=',
'categories.id'
)
->select('products.*', 'categories.name as category_name')
->get();
Query Builder phù hợp với những truy vấn báo cáo hoặc truy vấn kết hợp nhiều bảng mà việc viết Model Relationship không phải lúc nào cũng thuận tiện.
GROUP BY, HAVING và truy vấn tổng hợp
Query Builder cũng hỗ trợ các hàm tổng hợp như:
$count = DB::table('orders')->count();
$total = DB::table('orders')->sum('amount');
$average = DB::table('orders')->avg('amount');
$max = DB::table('orders')->max('amount');
$min = DB::table('orders')->min('amount');
Ví dụ thống kê số lượng đơn hàng theo trạng thái:
$orders = DB::table('orders')
->select('status', DB::raw('COUNT(*) as total'))
->groupBy('status')
->get();
Với những truy vấn cần tính toán hoặc tổng hợp dữ liệu, Query Builder thường giúp biểu diễn câu SQL rõ ràng hơn so với việc tự nối chuỗi SQL.
Thêm, cập nhật và xóa dữ liệu
Query Builder không chỉ dùng để SELECT.
Thêm dữ liệu
DB::table('users')->insert([
'name' => 'Nguyen Van A',
'email' => 'a@example.com',
]);
Có thể thêm nhiều bản ghi:
DB::table('users')->insert([
[
'name' => 'Nguyen Van A',
'email' => 'a@example.com',
],
[
'name' => 'Nguyen Van B',
'email' => 'b@example.com',
],
]);
Cập nhật dữ liệu
DB::table('users')
->where('id', 10)
->update([
'name' => 'Nguyen Van C',
]);
Xóa dữ liệu
DB::table('users')
->where('id', 10)
->delete();
Với các thao tác update() và delete(), cần đặc biệt kiểm tra điều kiện where() để tránh tác động ngoài ý muốn lên nhiều bản ghi.
Query Builder và Eloquent khác nhau thế nào?
Query Builder và Eloquent đều được Laravel sử dụng để làm việc với database nhưng cách tiếp cận khác nhau.
| Tiêu chí | Query Builder | Eloquent |
|---|---|---|
| Cách làm việc | Trực tiếp với bảng | Thông qua Model |
| Cú pháp | Query Builder | ORM |
| Quan hệ Model | Không phải trọng tâm | Hỗ trợ mạnh |
| Truy vấn phức tạp | Linh hoạt | Có thể thực hiện nhưng đôi khi dài hơn |
| Model Event | Không sử dụng theo cách của Eloquent | Có |
| Hydration Model | Không | Có |
| Phù hợp | Truy vấn dữ liệu, báo cáo, JOIN | Làm việc với Model và quan hệ |
Ví dụ Query Builder:
$users = DB::table('users')
->where('status', 'active')
->get();
Eloquent:
$users = User::where('status', 'active')->get();
Không có lựa chọn nào luôn tốt hơn lựa chọn còn lại. Việc chọn công cụ phụ thuộc vào cấu trúc dữ liệu và mục đích của truy vấn.
Nếu ứng dụng chủ yếu làm việc với các đối tượng như User, Product, Order và có nhiều quan hệ giữa chúng, Eloquent thường thuận tiện hơn. Ngược lại, Query Builder có thể phù hợp khi cần truy vấn bảng trực tiếp hoặc xây dựng các câu truy vấn nhiều JOIN và tổng hợp dữ liệu.
Khi nào nên sử dụng Query Builder?
Query Builder phù hợp với các trường hợp như:
- Truy vấn trực tiếp một hoặc nhiều bảng.
- Cần nhiều
JOIN. - Xây dựng báo cáo thống kê.
- Thực hiện các phép tính
COUNT,SUM,AVG,GROUP BY. - Truy vấn dữ liệu không nhất thiết cần Model.
- Cần xây dựng câu truy vấn linh hoạt theo nhiều điều kiện.
- Muốn kiểm soát rõ cấu trúc truy vấn.
Ví dụ một trang báo cáo doanh thu có thể cần kết hợp nhiều bảng:
$reports = DB::table('orders')
->join('users', 'orders.user_id', '=', 'users.id')
->select(
'users.name',
DB::raw('SUM(orders.amount) as total')
)
->groupBy('users.id', 'users.name')
->orderByDesc('total')
->get();
Đây là kiểu truy vấn mà Query Builder có thể phát huy ưu thế.
Trong quá trình Học Laravel, bạn không cần cố ghi nhớ toàn bộ phương thức của Query Builder ngay từ đầu. Quan trọng hơn là hiểu cách ghép một truy vấn từ các thành phần như select(), where(), join(), groupBy() và orderBy().
Một số lưu ý khi sử dụng Query Builder
Không nên nối chuỗi SQL từ dữ liệu người dùng
Không nên làm theo cách:
DB::select("SELECT * FROM users WHERE name = '$name'");
Thay vào đó, sử dụng cơ chế binding hoặc Query Builder:
$users = DB::table('users')
->where('name', $name)
->get();
Chỉ lấy những cột cần thiết
Thay vì luôn sử dụng:
DB::table('users')->get();
có thể chọn cột cần dùng:
DB::table('users')
->select('id', 'name', 'email')
->get();
Điều này giúp giảm lượng dữ liệu không cần thiết khi bảng có nhiều cột.
Kiểm tra truy vấn phức tạp
Khi Query Builder có nhiều điều kiện hoặc JOIN, nên kiểm tra SQL được tạo ra và xem xét execution plan khi cần tối ưu hiệu năng.
Đồng thời, cần chú ý đến index của các cột thường xuyên được sử dụng trong WHERE, JOIN, ORDER BY hoặc các truy vấn tìm kiếm.
Nếu bạn đang xây dựng nền tảng kiến thức database từ đầu, Laravel cơ bản sẽ là phần nền phù hợp để nắm các khái niệm về Model, Migration và cơ sở dữ liệu trước khi đi sâu vào những truy vấn phức tạp.
Kết luận
Laravel Query Builder là công cụ giúp xây dựng truy vấn cơ sở dữ liệu bằng cú pháp PHP rõ ràng và linh hoạt. Từ những thao tác cơ bản như select, where, insert, update, delete đến các truy vấn phức tạp với JOIN, GROUP BY và hàm tổng hợp, Query Builder đáp ứng được nhiều nhu cầu xử lý dữ liệu trong Laravel.
Điểm quan trọng không phải là lựa chọn Query Builder thay cho Eloquent trong mọi trường hợp, mà là biết khi nào nên sử dụng từng công cụ. Eloquent phù hợp với cách làm việc dựa trên Model và quan hệ, trong khi Query Builder rất hữu ích cho các truy vấn trực tiếp, nhiều JOIN hoặc các bài toán thống kê. Khi đã nắm được Query Builder, bạn sẽ có thêm một phương án linh hoạt để xử lý database và xây dựng các chức năng thực tế trong Laravel.
