Asked Jul 16th, 2:24 AM 156 1 6
  • 156 1 6
+3

Các pro Laravel cho em hỏi chút về Query Builder với ạ

Share
  • 156 1 6

Chả là em mới nhận maintain 1 dự án Laravel.
Cũng 3 năm toàn làm C#, ko động tới Laravel nên e cũng quên tiệt rồi.
Nên có thể câu hỏi sẽ hơi ngu nên mong mọi người gạch đá cho ít đáp án để củng cố kiến thức ạ.

Dự án hiện tại source code Laravel 5.8, mà k thấy dùng tí Eloquent nào, toàn dùng query builder Dùng DB:: và thực hiện truy vấn ngay tại controller.
Vấn đề là em đang thấy có khá nhiều đoạn code bị lặp đi lặp lại ở nhiều controller khác nhau 😦, chắc trc do cao thủ viết Nên em muốn gom nó lại thành các function viết ở class mới để tái sử dụng. Em định tạo các class đóng vai trò là model (do ko dùng eloquent nên e cũng sẽ ko extends Model của Laravel) để copy đưa các hàm giống nhau kia vào để tái sử dụng. Đại loại như

namespace ABC;

use DB;

class ABC {
    public static function common1() {
        //copy from controller 
        DB::...
    }
    public static function common2() {DB::...}
}

Và ở các controllers thì call tới đây để gọi hàm.

Không biết các refactor code này của em có hợp lý không ạ. Mong mọi người cho ý kiến ạ.

P/s: Tất nhiên phần mới e viết thì em sẽ dùng Eloquent cho nhàn ạ 😄

Vinh Nguyen @vinhnguyen
Jul 16th, 1:22 PM
Rybak Alexander @KAITOKIDK10
Jul 30th, 4:34 AM

Lâu lâu cũng gặp các cao thủ như vậy. Nếu sau muốn sửa thì phải kiếm hết 20 chỗ để sửa. Bác đã chia kiểu trên thì chia luôn ra 2 loại: ObjectBuilder{} hay ObjectService{} và AbcBuilder{}/AbcService{} Cái nào chung thì gọi ObjectBuilder, riêng thì gọi AbcBuilder.

0
| Reply
Share

6 ANSWERS


Answered Jul 16th, 2:28 AM
+2

Mình thấy cách này ổn mà, dự án của mình cũng đang viết các query theo kiểu như vậy.

Share
Thanh Nguyen @thanhnguyen
Jul 16th, 2:30 AM

Dự án của bạn cũng tách thành các class để viết hàm hàm chung sử dụng query builder à 😄
Thấy code dự án mình, có chỗ viết cả function sử dụng query builder trong Eloquent Model. (nanqua)

0
| Reply
Share
Dao Thai Son @dao.thai.son
Jul 16th, 2:44 AM

@thanhnguyen Mình tách thành class Query nhưng đa số vẫn dùng Eloquent Model, chỉ những query phức tạp quá thì viết Query Builder để sửa dụng Raw query thôi.

0
| Reply
Share
Thanh Nguyen @thanhnguyen
Jul 16th, 2:50 AM

@dao.thai.son Uhm bạn, mình cũng thi thoảng dùng builder cho câu khó 😄 chắc người code dự án của mình trc có quan niệm query builder thì luôn nhanh hơn eloquent thì phải.
ko dùng model thay bằng dùng DB:: trực tiếp trong controller và views 😦

0
| Reply
Share
Dao Thai Son @dao.thai.son
Jul 16th, 3:19 AM

@thanhnguyen Mình thường không viết query trong views đâu, viết trong Controller hoặc gọi đến query trong Controller thôi.

0
| Reply
Share
Answered Jul 16th, 2:42 AM
+1

Mình thấy dùng query builder cũng ổn mà, nếu nhiều người dùng nhiều data thì có khả năng còn nhanh hơn eloquent nữa. Nhưng để cho dễ thì phần query nên để ra 1 class riêng, có thể sử dụng cấu trúc repository và viết query trong đó, controller gọi ra (giống cách của bạn)

Share
Thanh Nguyen @thanhnguyen
Jul 16th, 2:47 AM

Uhm, cũng công nhận là nhiều cases ko thể dùng Eloquent thì vẫn dùng Query builder để tối ưu.
OK, thanks bạn. 2 người đồng quan điểm là ok rồi 😄

+1
| Reply
Share
Answered Jul 16th, 2:51 AM
+1

theo mình thì việc bạn tách như vậy cũng là ok rồi. Việc sử dụng query builder cũng không có vấn đề gì 💯

Share
Answered Jul 16th, 1:24 PM
+1

Mình nghĩ việc refactor sẽ tùy vào việc phần code bạn muốn tách ra đang làm gì

  • Với những phần logic đơn giản có thể tách các hàm utilities và re-use lại
  • Với những phần logic phức tạp, hoặc đại diện cho một feature hay business logic nào đó, thì bạn có thể sử dụng Query Object (thực chất là việc tách class thôi 😄). Đảm bảo tên class mô tả đúng cái đang thực hiện và nội dụng class tập trung vào 1 vấn đề thôi. Hoặc nguy hiểm hơn thì dùng Repository (nhưng thực sự theo mình dùng Repository vs Active Record của Laravel là hơi thừa và làm codebase phức tạp hơn)
  • Tất nhiên là có thể sử dụng pattern này pattern khác vào nữa nhưng mình nghĩ cái đó ko quá quan trọng, miễn sao sau một vài tháng bạn quay lại đọc đoạn code đó vẫn hiểu là đc.
Share
Thanh Nguyen @thanhnguyen
Jul 16th, 2:22 PM

mình cũng đang dùng Query Object bạn ak. Thanks bạn 😄

0
| Reply
Share
Answered Jul 16th, 2:46 AM
0

Mình thấy cách của bạn ổn. Còn về việc viết Eloquent thì cũng tuy thuộc vào dự án của bạn nếu dự án của bạn lớn thì mình thấy query builder sẽ giúp cho bạn tốc độ nhanh hơn so với Eloquent. Còn nếu dự án vừa vừa thì mình dùng Eloquent cho tiện 😃

Share
Answered Jul 16th, 6:58 AM
0

Bạn có thể sử dụng một class như là repository. Ví dụ như thế này, đảm bảo không cần extend Models

namespace App\Repo;

use Illuminate\Database\Connection;
use Illuminate\Support\Collection;

class StreetRepository implements StreetRepositoryInterface
{
    /**
     * @var \Illuminate\Database\Connection
     */
    protected $db;

    /**
     * StreetRepository constructor.
     *
     * @param \Illuminate\Database\Connection $db
     */
    public function __construct(Connection $db)
    {
        $this->db = $db;
    }

    /**
     * @return \Illuminate\Database\Query\Builder
     */
    protected function query()
    {
        return $this->db->table('streets');
    }

    public function paginateList($page = null, array $columns = ['*'], $perPage = StreetRepositoryInterface::DEFAULT_LIMIT)
    {
        return $this->query()
            ->paginate($perPage, $columns, 'page', $page);
    }
....
Share
Rybak Alexander @KAITOKIDK10
Jul 30th, 4:28 AM