Para executar instruções SQL puras, utilize:
DB::statement($consulta);
A seguir, apresento os principais métodos da classe Illuminate\Database\Query\Builder:
Definição de Colunas
select — Especifica as colunas desejadas:
Aviso::select('titulo')->obter();
Aviso::select(['titulo', 'conteudo'])->obter();
selectRaw — Permite expressões SQL personalizadas:
Aviso::selectRaw("COUNT('id') AS total_avisos")->obter();
addSelect — Adiciona colunas a uma consulta existente:
$consulta = DB::table('usuarios')->select('nome');
$usuarios = $consulta->addSelect('idade')->obter();
distinct — Força resultados únicos:
$usuarios = DB::table('usuarios')->distinct()->obter();
Definição de Tabela
from — Define a tabela de origem (o método table() utiliza internamente este método):
DB::table('usuarios')
->ondeExiste(function ($consulta) {
$consulta->select(DB::raw(1))
->from('pedidos')
->whereRaw('pedidos.usuario_id = usuarios.id');
})
->obter();
O SQL gerado:
SELECT * FROM usuarios
WHERE EXISTS (
SELECT 1 FROM pedidos WHERE pedidos.usuario_id = usuarios.id
)
Relacionamentos entre Modelos
hasOne — Relacionamento um-para-um onde a chave estrangiera está no modelo filho:
public function cliente($classe = Cliente::class)
{
return $this->hasOne($classe, 'id', 'cliente_id');
}
Para obter o registro mais recente:
public function ultimoPedido($classe = Pedido::class)
{
return $this->hasOne($classe, 'cliente_id', 'id')
->ordenarPor('id', 'desc');
}
Com condições adicionais:
public function pedidoAtivo($classe = Pedido::class)
{
return $this->hasOne($classe, 'cliente_id', 'id')
->onde('situacao', Pedido::SITUACAO_ABERTO);
}
hasMany — Relacionamento um-para-muitos:
public function pedidos($classe = Pedido::class)
{
return $this->hasMany($classe, 'cliente_id', 'id');
}
belongsTo — Relacionamento inverso, onde a chave estrangeira está no modelo atual:
public function cliente($classe = Cliente::class)
{
return $this->belongsTo($classe, 'cliente_id', 'id');
}
Diferença fundamental: hasOne/hasMany é usado quando o modelo atual possui a relação (chave estrangeira na outra tabela). belongsTo/belongsToMany é usado quando o modelo atual é "possuído" (chave estrangeira na própria tabela).
belongsToMany — Relacionamento muitos-para-muitos com tabela intermediária:
public function permissoes()
{
return $this->belongsToMany(
\App\Models\Permissao::class,
'usuario_possui_permissoes',
'usuario_id',
'permissao_id'
);
}
Junções (Joins)
O método join() aceita parâmetros para tipo de junção (inner, left, right, cross) e condição (on, where).
join — Junção interna:
$usuarios = DB::table('usuarios')
->join('contatos', 'usuarios.id', '=', 'contatos.usuario_id')
->join('pedidos', 'usuarios.id', '=', 'pedidos.usuario_id')
->select('usuarios.*', 'contatos.telefone', 'pedidos.valor')
->obter();
joinWhere — Junção com condição WHERE em vez de ON:
$usuarios = DB::table('usuarios')
->joinWhere('contatos', 'contatos.tipo', '=', '1')
->join('pedidos', 'usuarios.id', '=', 'pedidos.usuario_id')
->select('usuarios.*', 'contatos.telefone', 'pedidos.valor')
->obter();
leftJoin / leftJoinWhere — Junção à esquerda:
$usuarios = DB::table('usuarios')
->leftJoin('publicacoes', 'usuarios.id', '=', 'publicacoes.usuario_id')
->obter();
$usuarios = DB::table('usuarios')
->leftJoinWhere('publicacoes', 'publicacoes.tipo', '=', '1')
->obter();
rightJoin / rightJoinWhere — Junção à direita (mesma lógica).
crossJoin — Produto cartesiano:
DB::table('usuarios')->crossJoin('preferencias')->obter();
Cláusulas WHERE
O método onde() aceita múltiplos formatos, com parâmetro $boolean padrão and (pode ser or):
$usuario = DB::table('usuarios')->onde('nome', 'João')->primeiro();
$usuario = DB::table('usuarios')->onde('nome', '=', 'João')->primeiro();
$usuario = DB::table('usuarios')->onde([['nome', '=', 'João'], ['telefone', '=', '11999998888']])->primeiro();
ouOnde:
$usuarios = DB::table('usuarios')
->onde('votos', '>', 100)
->ouOnde('nome', 'João')
->obter();
Argupamento e Ordenação
agruparPor — Aceita array ou múltiplos argumentos:
Aviso::agruparPor('titulo', 'id')->obter();
Aviso::agruparPor(['titulo', 'id'])->obter();
tendo / ouTendo / tendoRaw / ouTendoRaw:
Aviso::tendo('titulo', '=', '2')->obter();
Aviso::tendo('titulo', '=', '2')->ouTendo('titulo', '=', '1')->obter();
$pedidos = DB::table('pedidos')
->select('departamento', DB::raw('SUM(valor) AS total_vendas'))
->agruparPor('departamento')
->tendoRaw('SUM(valor) > ?', [2500])
->obter();
ordenarPor / ordenarPorDesc:
Aviso::ordenarPor('titulo')->obter();
Aviso::ordenarPor('titulo')->ordenarPor('conteudo')->obter();
Aviso::ordenarPorDesc('titulo')->obter();
maisRecente / maisAntigo — Ordenam por created_at:
public function maisRecente($coluna = 'created_at')
{
return $this->ordenarPor($coluna, 'desc');
}
public function maisAntigo($coluna = 'created_at')
{
return $this->ordenarPor($coluna, 'asc');
}
emOrdemAleatoria — Ordenação aleatória (seed opcional):
Aviso::emOrdemAleatoria()->obter();
Aviso::emOrdemAleatoria(1)->obter();
ordenarPorRaw:
Aviso::ordenarPorRaw('titulo, conteudo')->obter();
Recuperação de Registros
encontrar — Busca por chave primária (aceita array para múltiplos registros):
Aviso::encontrar(1);
Aviso::encontrar(1, ['titulo']);
Aviso::encontrar([1, 2], ['titulo']);
valor — Obtém valor de uma única coluna:
Aviso::onde('titulo', 1)->valor('titulo');
obter — Retorna coleção (array vazio se não encontrar):
Aviso::onde('titulo', 1)->obter();
paginar / paginarSimples:
DB::table('avisos')->paginar();
DB::table('avisos')->paginarSimples(); // Mais performático para grandes volumes
cursor — Iterador eficiente para grandes volumes:
foreach (DB::table('avisos')->cursor() as $aviso) {
var_dump($aviso);
}
agruparPorId — Processamento em lotes (cuidado com atualizações):
$resultados = [];
DB::table('avisos')->agruparPorId(10, function($avisos) use (&$resultados) {
$resultados[] = json_decode(json_encode($avisos, 256), true);
}, 'aviso_id');
extrair — Obtém valores de uma coluna como array:
DB::table('funcoes')->extrair('titulo');
DB::table('funcoes')->extrair('titulo', 'nome'); // Chave-valor
juntar — Concatena valores com delimitador:
DB::table('avisos')->juntar('titulo', ','); // titulo1,titulo2,titulo3
Verificação de Existência
DB::table('avisos')->onde('situacao', 1)->existe(); // true/false
DB::table('avisos')->onde('situacao', 1)->naoExiste(); // inverso
Funções de Agregação
DB::table('avisos')->onde('situacao', 1)->contar();
DB::table('avisos')->minimo('aviso_id');
DB::table('avisos')->maximo('aviso_id');
DB::table('avisos')->soma('aviso_id');
DB::table('avisos')->media('aviso_id');
DB::table('avisos')->agregar('soma', ['aviso_id']);
DB::table('avisos')->agregarNumerico('soma', ['aviso_id']); // Retorna número
Operações de Escrita
inserir — Retorna booleano:
Aviso::inserir(['titulo' => 'Novo']);
Aviso::inserir(['titulo' => 'Novo', 'status' => 1]);
inserirObterId — Retorna o ID gerado:
Aviso::inserirObterId(['titulo' => 'Novo']);
atualizar:
$aviso = Aviso::encontrar(1);
$aviso->atualizar(['titulo' => 'Atualizado']);
atualizarOuInserir:
Aviso::atualizarOuInserir(['titulo' => 'Novo'], ['conteudo' => 'Descrição']);
incrementar / decrementar:
Aviso::incrementar('visualizacoes'); // +1
Aviso::incrementar('visualizacoes', 5); // +5
Aviso::decrementar('visualizacoes'); // -1
Aviso::decrementar('visualizacoes', 5); // -5
excluir:
$aviso = Aviso::encontrar(1);
$aviso->excluir();
truncar — Remove todos os registros e reseta auto-incremento:
DB::table('avisos')->truncar();
Consultas Avançadas
novaConsulta — Nova instância do construtor:
$consulta = (new Aviso())->novaConsulta();
return $consulta->encontrar(1);
raw — Expresssões SQL brutas:
DB::table('avisos')->select(DB::raw('COUNT(*) AS total'))->obter();
Trait BuildsQueries
bloco — Processamento em lotes com controle de memória:
$estatisticas = ['sucesso' => 0, 'falha' => 0];
DB::table('avisos')->ordenarPor('aviso_id')->bloco(500, function ($avisos) use (&$estatisticas) {
foreach ($avisos as $aviso) {
$aviso->situacao == 1 ? $estatisticas['sucesso']++ : $estatisticas['falha']++;
}
});
cada — Iteração automática:
$estatisticas = ['sucesso' => 0, 'falha' => 0];
DB::table('avisos')->ordenarPor('id')->cada(function ($aviso, $indice) use (&$estatisticas) {
$aviso->situacao ? $estatisticas['sucesso']++ : $estatisticas['falha']++;
}, 500);
Métodos do Eloquent Builder
aPartirDaConsulta — Para consultas SQL complexas:
Aviso::aPartirDaConsulta("SELECT titulo FROM avisos");
Aviso::aPartirDaConsulta('SELECT titulo FROM avisos WHERE titulo = ?', [1]);
encontrarMuitos:
Aviso::encontrarMuitos([1, 2], ['titulo']);
encontrarOuFalhar — Lança ModelNotFoundException:
Aviso::encontrarOuFalhar(100);
encontrarOuNovo / primeiroOuNovo — Cria instância se não encontrar:
Aviso::encontrarOuNovo(100);
Aviso::primeiroOuNovo(['titulo' => 14]);
Aviso::primeiroOuNovo(['titulo' => 100], ['conteudo' => 123]);
novaInstanciaModelo:
Aviso::novaInstanciaModelo(['titulo' => 100, 'conteudo' => 123]);
primeiroOuCriar:
Aviso::primeiroOuCriar(['titulo' => 14], ['conteudo' => 123]);
atualizarOuCriar:
Aviso::atualizarOuCriar(['titulo' => 14], ['conteudo' => 1234]);
Implementação interna:
public function atualizarOuCriar(array $atributos, array $valores = [])
{
return tap($this->primeiroOuNovo($atributos), function ($instancia) use ($valores) {
$instancia->preencher($valores)->salvar();
});
}
primeiroOuFalhar:
Aviso::primeiroOuFalhar();
Aviso::onde('titulo', 321)->primeiroOuFalhar();
primeiroOu — Executa callback se não encontrar:
$titulo = 1;
return Aviso::onde('titulo', 100)->primeiroOu(function() use ($titulo) {
return Aviso::atualizarOuCriar(['titulo' => $titulo], ['conteudo' => 1234]);
});
Carregamento de Relacionamentos
com:
class Aviso {
public function arquivosRelacionados()
{
return $this->hasMany(ArquivoRelacionado::class, 'relacao_id', 'id')
->onde('tipo_relacao', '=', ArquivoRelacionado::TIPO_AVISO)
->select('tipo_relacao', 'relacao_id', 'arquivo_id');
}
}
class ArquivoRelacionado {
public function arquivo()
{
return $this->hasOne(Arquivo::class, 'id', 'arquivo_id');
}
}
Utilização:
Aviso::com('arquivosRelacionados')->obter();
Aviso::com('arquivosRelacionados.arquivo')->obter();
Aviso::com([
'arquivosRelacionados' => function($consulta) {
$consulta->select('relacao_id', 'arquivo_id');
}
])->obter();
Aviso::com([
'arquivosRelacionados' => function($consulta) {
$consulta->select('relacao_id', 'arquivo_id')->com([
'arquivo' => function($consulta) {
$consulta->select('id', 'caminho');
}
]);
}
])->obter();
sem — Remove relacionamento carregado:
Aviso::com('arquivosRelacionados')->sem('arquivosRelacionados')->obter();
comContagem — Obtém apenas a contagem:
Aviso::comContagem('arquivosRelacionados')->obter();
Verificação de Nulos
->ondeNaoNulo('atualizado_em');
->ondeNulo('atualizado_em');
Junções Complexas
Para condições elaboradas, utilize closure:
DB::table('usuarios')
->join('contatos', function ($juncao) {
$juncao->on('usuarios.id', '=', 'contatos.usuario_id')->ouOn(...);
})
->obter();
DB::table('usuarios')
->join('contatos', function ($juncao) {
$juncao->on('usuarios.id', '=', 'contatos.usuario_id')
->onde('contatos.usuario_id', '>', 5);
})
->obter();