请求将SQL查询转换为Laravel 5.6 Eloquent以实现分页与Collection获取
转换Laravel 5.6 Eloquent语法实现分页与Collection获取
针对你的需求,我提供两种贴近原生SQL逻辑且符合Laravel Eloquent规范的实现方案,都能直接返回带分页的Collection集合:
方案一:直接使用JOIN(最贴近原生SQL)
这种方式和你原有的SQL逻辑完全对齐,适合快速迁移:
假设你已经创建了对应表的Eloquent模型:
Norma对应表normasRelNodoTem对应表rel_nodo_temTipoNorma对应表tipo_norma
在控制器中可以这样编写查询:
// 替换为你的实际codNodo参数值 $codNodo = '目标节点编码'; $normas = Norma::select( 'n.id_norma', 'n.id_tipo_norma', 'n.texto_norma', 'n.fec_norma', 'r.cod_nodo', 'r.articulo', 't.desc_tipo_norma', 'n.desc_norma' ) ->from('normas as n') ->join('rel_nodo_tem as r', function ($join) { // 注意这里是复合关联条件:同时匹配id_norma和id_tipo_norma $join->on('r.id_norma', '=', 'n.id_norma') ->on('r.id_tipo_norma', '=', 'n.id_tipo_norma'); }) ->join('tipo_norma as t', 'n.id_tipo_norma', '=', 't.id_tipo_norma') ->where('r.cod_nodo', $codNodo) ->orderBy('t.desc_tipo_norma', 'asc') ->orderBy('n.fec_norma', 'desc') ->orderBy('n.id_norma', 'desc') ->paginate(15); // 15为每页显示条数,可根据需求调整
执行后,$normas 是 LengthAwarePaginator 实例,其中 $normas->items() 就是你需要的Collection集合,同时自带分页所需的总条数、当前页、每页条数等参数,直接在视图中使用分页链接即可。
方案二:使用Eloquent关联关系(更符合Laravel风格)
先在模型中定义好关联关系,让代码更具可读性和维护性:
Norma模型:
namespace App; use Illuminate\Database\Eloquent\Model; class Norma extends Model { protected $table = 'normas'; protected $primaryKey = 'id_norma'; // 主键不是默认id时必须指定 // 关联TipoNorma表 public function tipoNorma() { return $this->belongsTo(TipoNorma::class, 'id_tipo_norma'); } // 关联RelNodoTem表(复合关联条件) public function relNodoTems() { return $this->hasMany(RelNodoTem::class, 'id_norma', 'id_norma') ->whereColumn('rel_nodo_tem.id_tipo_norma', '=', 'normas.id_tipo_norma'); } }
TipoNorma模型:
namespace App; use Illuminate\Database\Eloquent\Model; class TipoNorma extends Model { protected $table = 'tipo_norma'; protected $primaryKey = 'id_tipo_norma'; }
RelNodoTem模型:
namespace App; use Illuminate\Database\Eloquent\Model; class RelNodoTem extends Model { protected $table = 'rel_nodo_tem'; // 由于是复合主键,Laravel默认不支持,无需指定primaryKey,不影响关联查询 }
然后在控制器中编写查询:
$codNodo = '目标节点编码'; $normas = Norma::select( 'normas.id_norma', 'normas.id_tipo_norma', 'normas.texto_norma', 'normas.fec_norma', 'rel_nodo_tem.cod_nodo', 'rel_nodo_tem.articulo', 'tipo_norma.desc_tipo_norma', 'normas.desc_norma' ) ->join('rel_nodo_tem', function ($join) { $join->on('rel_nodo_tem.id_norma', '=', 'normas.id_norma') ->on('rel_nodo_tem.id_tipo_norma', '=', 'normas.id_tipo_norma'); }) ->join('tipo_norma', 'normas.id_tipo_norma', '=', 'tipo_norma.id_tipo_norma') ->where('rel_nodo_tem.cod_nodo', $codNodo) ->orderBy('tipo_norma.desc_tipo_norma', 'asc') ->orderBy('normas.fec_norma', 'desc') ->orderBy('normas.id_norma', 'desc') ->paginate(15);
关键注意事项
- 务必确保模型的
$table和$primaryKey属性设置正确,否则会出现表名或主键匹配错误 - 如果查询结果出现重复数据,可以添加
->groupBy('n.id_norma')(方案一)或->groupBy('normas.id_norma')(方案二)来去重 - Laravel 5.6的
paginate()方法会自动识别URL中的page参数,无需手动处理分页逻辑
内容的提问来源于stack exchange,提问作者G.Battiato
相关产品推荐
相关产品推荐

