ThinkPHP 6.0深度实战:模型关联与复杂查询优化全攻略
一、模型关联高级用法
ThinkPHP 6.0 ORM的核心关联功能解析:
// 用户模型定义关联
class User extends Model
{
// 一对多关联文章
public function articles()
{
return $this->hasMany(Article::class);
}
// 多对多关联角色
public function roles()
{
return $this->belongsToMany(Role::class, 'user_role');
}
// 远程一对多关联(用户->文章->评论)
public function comments()
{
return $this->hasManyThrough(Comment::class, Article::class);
}
}
// 关联预加载优化查询
$users = User::with(['articles' => function($query) {
$query->where('status', 1)->field('id,title,user_id');
}])
->where('score', '>', 80)
->select();
关联优势:延迟加载、预加载优化、链式调用、自动维护
二、复杂查询构建技巧
1. 高级条件查询
// 动态条件构造器
$map = [];
if ($request->has('keywords')) {
$map[] = ['title|content', 'like', '%'.$request->param('keywords').'%'];
}
if ($request->has('category_id')) {
$map[] = ['category_id', '=', $request->param('category_id')];
}
$list = Article::withJoin(['user' => ['name', 'avatar']])
->where($map)
->whereTime('create_time', 'between', ['2022-01-01', '2022-12-31'])
->order('read_count', 'desc')
->paginate(10);
2. 原生查询优化
// 复杂SQL构建
$result = Db::query("
SELECT u.name, COUNT(a.id) as article_count
FROM blog_user u
LEFT JOIN blog_article a ON u.id = a.user_id
WHERE u.status = 1
GROUP BY u.id
HAVING article_count > 5
ORDER BY article_count DESC
LIMIT 10
");
// 参数绑定安全查询
$sql = "SELECT * FROM blog_article WHERE category_id = :cid AND status = :status";
$articles = Db::query($sql, [
'cid' => $categoryId,
'status' => 1
]);
三、性能优化实战
1. 查询缓存策略
// 模型缓存实现
$user = User::cache(true, 3600)
->where('id', $userId)
->find();
// 关联查询缓存
$articles = Article::with(['user' => function($query) {
$query->cache(300);
}])
->cache('article_list_'.$page, 600)
->paginate(10);
// 更新时自动清除缓存
$article = Article::find($id);
$article->title = $newTitle;
$article->save();
Cache::delete('article_list_*'); // 通配符清除
2. 批量操作优化
// 批量插入优化
$data = [];
for ($i = 0; $i '测试标题'.$i,
'content' => '内容'.$i
];
}
Db::name('article')->insertAll($data);
// 批量更新方案
Db::name('user')
->whereIn('id', $ids)
->update([
'status' => Db::raw('IF(score>80, 2, status)'),
'update_time' => time()
]);
// 事务处理
Db::transaction(function() use ($orderData) {
$order = Order::create($orderData);
OrderItem::insertAll($orderItems);
Inventory::decStock($orderItems);
});
四、电商系统实战案例
1. 订单关联查询系统
class Order extends Model
{
// 订单关联定义
public function user()
{
return $this->belongsTo(User::class);
}
public function items()
{
return $this->hasMany(OrderItem::class);
}
public function payment()
{
return $this->hasOne(Payment::class);
}
// 订单状态范围查询
public function scopePaid($query)
{
$query->where('status', '>', 0);
}
}
// 复杂订单查询
$orders = Order::with(['user', 'items.product', 'payment'])
->where('create_time', '>=', strtotime('-1 month'))
->scope('paid')
->chunk(100, function($orders) {
foreach ($orders as $order) {
// 批量处理逻辑
}
});
五、最佳实践总结
- 模型分层:业务逻辑放入Service层
- 查询监控:开启SQL日志分析慢查询
- 字段严格:模型设置$schema和$type属性
- 版本控制:数据库迁移管理表结构变更
- 安全防护:输入过滤和参数绑定防SQL注入