自定义 Builder ,职责分离 - 图1

Builder.php

  1. <?php
  2. namespace App\Extensions;
  3. use Illuminate\Database\Eloquent\Model;
  4. use Illuminate\Support\Facades\DB;
  5. use Illuminate\Support\Facades\Log;
  6. use Symfony\Component\HttpKernel\Exception\HttpException;
  7. use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
  8. use Illuminate\Database\Query\Builder as QueryBuilder;
  9. use Throwable;
  10. /**
  11. * @property-read Model $model
  12. * @property-read EloquentBuilder|null $query
  13. * @property-read string|null $table
  14. * @property-read QueryBuilder|null $rawQuery
  15. */
  16. class Builder
  17. {
  18. private ?string $modelClass = null;
  19. private ?string $table = null;
  20. public function __get(string $name)
  21. {
  22. switch ($name) {
  23. case 'table':
  24. if (!$this->table) {
  25. $this->table = $this->makeModel()->getTable();
  26. }
  27. return $this->table;
  28. case 'model':
  29. return $this->makeModel();
  30. case 'query':
  31. return $this->makeModel(false)::query();
  32. case 'rawQuery':
  33. abort_if($this->table === null,'获取当前模型错误',403);
  34. return DB::table($this->table);
  35. default:
  36. return null;
  37. }
  38. }
  39. private function getModel(): string
  40. {
  41. if (!$this->modelClass) {
  42. $baseName = last(explode('\\', get_called_class()));
  43. if (str_ends_with($baseName, 'Service')) {
  44. $baseName = substr($baseName, 0, -7);
  45. } else if (str_ends_with($baseName, 'Repository')) {
  46. $baseName = substr($baseName, 0, -10);
  47. }
  48. $class = 'App\\Models\\' . $baseName;
  49. if (!class_exists($class)) {
  50. abort(500,'缺少模型');
  51. }
  52. $this->modelClass = $class;
  53. return $this->modelClass;
  54. }
  55. return $this->modelClass;
  56. }
  57. private function makeModel($instance = true): Model|string
  58. {
  59. $class = $this->getModel();
  60. if (!is_subclass_of($class, Model::class)) {
  61. Log::error('模型文件错误');
  62. abort(500,'模型文件错误');
  63. }
  64. if (!$instance) {
  65. return $class;
  66. }
  67. try {
  68. return app($class);
  69. } catch (Throwable $e) {
  70. throw new HttpException(500, $e->getMessage());
  71. }
  72. }
  73. }

BaseService.php

实现了增、删、改

<?php

namespace App\Services;

use App\Extensions\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Support\Facades\Log;

class BaseService extends Builder
{
    public function createOrUpdate(array $data, string $by = 'id'): Model|EloquentBuilder|null
    {
        if ($byVal = ($data[$by] ?? null)) {
            if ($by === 'id') {
                unset($data['id']);
            }

            return $this->query->updateOrCreate([$by => $byVal], $data);
        }

        return $this->query->create($data);
    }

    public function destroy(int $value, string $by = 'id')
    {
        if (blank($value)) {
           abort(422,'参数不能为空');
        }

        $m = $this->query->where($by, $value)->first();

        try {
            $m->delete();
        } catch (ModelNotFoundException) {
            abort(422,'数据不存在');
        } catch (\Exception $e) {
            Log::error('[' . class_basename($this) . '::destroy' . $e->getMessage());
            abort(500,'删除数据失败!');
        }
    }
}

BaseRepository.php

<?php

namespace App\Repository;

use App\Extensions\Builder;

abstract class BaseRepository extends Builder
{

}