当前位置: 首页 > news >正文

后端工程中使用 Model + Trait 设计可复用的数据模型(完整实现示例)

后端工程中使用 Model + Trait 设计可复用的数据模型(完整实现示例)

在实际的后端项目开发中,例如 CRM、ERP 或用户系统,Model 很容易变得越来越臃肿。随着业务增加,很多通用能力会不断叠加,例如:

  • 自动生成 UUID
  • 软删除
  • 操作日志
  • 搜索封装
  • 审计字段(created_by、updated_by)

如果把这些功能全部写在 Model 里,最终很容易出现一个 2000~3000 行的 Model 文件,维护成本非常高。

一种在企业项目中非常常见的解决方案是:

Model + Trait 组合设计

Trait 用来承载可复用的横切功能(Cross-cutting concerns),Model 只负责数据结构和关系定义。

下面通过一个完整工程示例说明这种设计。


一、目标结构

假设有一个 Student 模型,需要具备以下能力:

1 自动生成 UUID

2 软删除

3 操作日志

4 搜索条件封装

5 审计字段自动记录

项目目录结构可以设计为:

app

├─ Models

│ └─ Student.php

│ └─ OperationLog.php

├─ Traits

│ ├─ SoftDeleteTrait.php

│ ├─ OperationLogTrait.php

│ ├─ UuidTrait.php

│ ├─ SearchTrait.php

│ └─ BlameableTrait.php


二、Student Model

Student 模型只负责数据结构和使用 Trait。

app/Models/Student.php

<?phpnamespace App\Models;use Illuminate\Database\Eloquent\Model;
use App\Traits\SoftDeleteTrait;
use App\Traits\OperationLogTrait;
use App\Traits\UuidTrait;
use App\Traits\SearchTrait;
use App\Traits\BlameableTrait;class Student extends Model
{use SoftDeleteTrait, OperationLogTrait, UuidTrait, SearchTrait, BlameableTrait;protected $table = 'students';protected $fillable = ['uuid','name','phone','email','created_by','updated_by'];
}

这里可以看到,Student 模型本身非常干净,只负责表结构定义。


三、软删除 Trait

SoftDeleteTrait 用来实现逻辑删除,而不是直接删除数据。

app/Traits/SoftDeleteTrait.php

<?phpnamespace App\Traits;trait SoftDeleteTrait
{public static function bootSoftDeleteTrait(){static::addGlobalScope('soft_delete', function ($builder) {$builder->whereNull('deleted_at');});}public function softDelete(){$this->deleted_at = now();$this->save();}public function restore(){$this->deleted_at = null;$this->save();}
}

数据库需要增加字段:

deleted_at datetime

这样删除数据时只会记录时间,而不会真正删除。


四、UUID 自动生成

很多系统希望主键或业务 ID 使用 UUID。

app/Traits/UuidTrait.php

<?phpnamespace App\Traits;use Illuminate\Support\Str;trait UuidTrait
{public static function bootUuidTrait(){static::creating(function ($model) {if (empty($model->uuid)) {$model->uuid = (string) Str::uuid();}});}
}

数据库字段:

uuid varchar(36)

当创建数据时自动生成 UUID。


五、操作日志 Trait

在很多后台系统中,记录操作日志是非常重要的功能。

app/Traits/OperationLogTrait.php

<?phpnamespace App\Traits;use App\Models\OperationLog;trait OperationLogTrait
{public static function bootOperationLogTrait(){static::created(function ($model) {OperationLog::create(['model' => get_class($model),'model_id' => $model->id,'action' => 'create','content' => json_encode($model->toArray())]);});static::updated(function ($model) {OperationLog::create(['model' => get_class($model),'model_id' => $model->id,'action' => 'update','content' => json_encode($model->getDirty())]);});static::deleted(function ($model) {OperationLog::create(['model' => get_class($model),'model_id' => $model->id,'action' => 'delete','content' => '']);});}
}

日志表 operation_logs 示例字段:

id

model

model_id

action

content

created_at

这样所有模型的增删改都会自动记录。


六、搜索 Trait

很多列表页面都有搜索需求,可以把查询逻辑封装在 Trait 里。

app/Traits/SearchTrait.php

<?phpnamespace App\Traits;trait SearchTrait
{public function scopeSearch($query, $params){if (!empty($params['name'])) {$query->where('name', 'like', '%' . $params['name'] . '%');}if (!empty($params['phone'])) {$query->where('phone', $params['phone']);}if (!empty($params['email'])) {$query->where('email', 'like', '%' . $params['email'] . '%');}return $query;}
}

使用方式:

Student::search($params)->paginate(20);

这样所有查询逻辑都集中在 Trait 中。


七、审计字段 Trait

很多企业系统需要记录是谁创建或修改了数据。

app/Traits/BlameableTrait.php

<?phpnamespace App\Traits;use Illuminate\Support\Facades\Auth;trait BlameableTrait
{public static function bootBlameableTrait(){static::creating(function ($model) {if (Auth::check()) {$model->created_by = Auth::id();}});static::updating(function ($model) {if (Auth::check()) {$model->updated_by = Auth::id();}});}
}

数据库字段:

created_by

updated_by

这样系统可以自动记录数据是谁创建、谁修改。


八、使用示例

创建学生

Student::create(['name' => '张三','phone' => '13800000000'
]);

自动触发:

UUID 生成

操作日志记录

created_by 自动写入

更新学生

$student = Student::find(1);
$student->name = '李四';
$student->save();

自动触发:

更新日志

updated_by 自动写入


九、这种架构的优点

第一,Model 变得非常干净

只负责数据结构和关系定义。

第二,功能高度复用

多个模型可以共享同一个 Trait。

第三,代码更易维护

横切逻辑统一管理。

第四,更符合大型系统架构

Trait 负责通用能力,Service 负责业务逻辑。

典型调用结构如下:

Controller

Service

Model + Traits

Database


十、总结

在大型后端系统中,Model 不应该承担过多业务逻辑。通过 Trait 可以把通用能力模块化,例如:

  • 软删除
  • 日志记录
  • UUID 生成
  • 搜索封装
  • 审计字段

这种 Model + Trait 的组合模式,可以显著降低代码耦合度,使系统结构更加清晰。

在实际项目中,很多成熟的 CRM、ERP 系统都会采用这种设计模式。

http://www.jsqmd.com/news/444309/

相关文章:

  • 通用商品打标模块实现方案(基于位运算,适配多框架多语言)
  • 机械设备出海新选择:Facebook、TikTok、Google、INS、Linkedin代运营如何助力机械海外推广获客 - 品牌2026
  • 企业海外营销获客公司推荐:Google、LinkedIn、Facebook、TikTok、INS等全渠道代运营 - 品牌2026
  • Windows下安装Node.js
  • 2026年3月贵州省角钢厂家推荐:市场趋势与优质企业盘点 - 深度智识库
  • 2026呼吸道感染恢复期养肺指南——久咳气短怎么养?附10款护肺产品参考 - 资讯焦点
  • 怎么优雅地将 Markdown 转换为 Word 文档? - AI
  • Matlab疲劳监测系统:基于灰度积分投影和Perclos技术的眼睛定位与疲劳评估
  • 考主管护师听谁的课?阿虎精英讲师天团,助你高效通关 - 医考机构品牌测评专家
  • NMN哪个牌子最靠谱?评测2026年NMN十大品牌口碑与技术产品,助你科学抗衰,少走弯路! - 资讯焦点
  • 2026年贵州省不锈钢与角钢采购指南:五家实力厂家深度解析与推荐 - 深度智识库
  • 一文搞懂ThreadLocal 底层原理
  • 卫生资格考试课程通过率对比,哪家更值得选? - 医考机构品牌测评专家
  • NMN哪个牌子效果最好?NMN服用感受分享,NMN十大排名品牌深度测评 - 资讯焦点
  • 2026年中国灵活用工平台TOP10 灵活用工代发薪平台哪个好 - 资讯焦点
  • NAD+哪个产品最好?2026年十大NMN抗衰老品牌排行榜:榜首高活NMN核心效能解析 - 资讯焦点
  • 蓄热式催化焚烧设备RCO行业十佳企业实力厂家 - 品牌推荐大师1
  • 关于我使用MinMix创建了一个Tailwindcss学习网站
  • NAD+哪个牌子效果最好?最值得入手的nad+品牌是谁?2026十大nad+品牌公布!主打抗衰+精力提升 - 资讯焦点
  • 2026年贵州省镀锌管厂家推荐:深耕西南基建,品质服务引领区域发展 - 深度智识库
  • 【黑马点评项目笔记 | 优惠券秒杀篇】构建高并发秒杀平台
  • 终极指南:推流搅拌机厂家综合评估—从实力、质量到服务的全维度考察 - 品牌推荐大师1
  • 不踩坑、不花冤枉钱!2026年商标转让平台榜单,甄标网凭全流程闭环实力上榜 - 资讯焦点
  • 2026电压力锅哪个牌子最好最安全?真实用户体验分享 - 品牌排行榜
  • 常见代数恒等式
  • dp
  • 2026年贵州省螺旋钢管厂家推荐本土优质企业精选 - 深度智识库
  • 2026年3月贵州省钢材采购指南:无缝钢管、螺旋钢管等主力建材厂家综合评析与推荐 - 深度智识库
  • 四川设备回收厂家哪家好?最新权威排行揭晓 - 深度智识库
  • RAG开发存在的潜在问题