Upload
carlos-santos
View
1.242
Download
1
Embed Size (px)
Citation preview
PHP + MySQL: master-detail + navegação
Carlos SantosLabMM 4 - NTC - DeCA - UAAula PHP+MySQL 02, 03-05-2012
visualizar dados de várias tabelas
Quando queremos visualizar dados que estão distribuídos por duas tabelas ligadas entre si, podemos:
• criar um query baseado num JOIN que permita obter todos os dados;• criar vários recordsets de acordo com a informação necessária
A solução adequada depende da situação em que se aplica
base para exemplos
listar os mariachis
$query = "SELECT idMariachi, nome FROM Mariachi";$rsMari = mysql_query($query , $connection);
while ($row_rsMari = mysql_fetch_assoc($rsMari)){ echo $row_rsMari[“nome"];}
listar os mariachis com família
$query = "SELECT Mariachi.idMariachi, Mariachi.nome, Familia.nomeFamilia FROM Mariachi INNER JOIN Familia ON Mariachi.Familia_idFamilia = Familia.idFamilia";$rsMari = mysql_query($query , $connection);
while ($row_rsMari = mysql_fetch_assoc($rsMari)){ echo $row_rsMari[“nome"].” - “. $row_rsMari[“nomeFamilia].”<br/>”;}
listar os mariachis com família (not so good)
$query = "SELECT idMariachi, nome, Familia_idFamilia FROM Mariachi";$rsMari = mysql_query($query , $connection);
while ($row_rsMari = mysql_fetch_assoc($rsMari)){ $qFami = "SELECT nomeFamilia FROM Familia WHERE idFamilia = ".$row_rsMari[“Familia_idFamilia”]; $rsFami = mysql_query($qFami , $connection);
$row_rsFami = mysql_fetch_assoc($rsFami);
echo $row_rsMari[“nome"].” - “. $row_rsFami[“nomeFamilia].”<br/>”;}
observações
uma página pode ter muitos recordsets
os valores obtidos num recordset podem ser utilizados para filtrar resultados a obter noutro recordset
soluções com múltiplos acessos há BD são, normalmente, mais lentas
no entanto, existem circunstâncias em que a quantidade de informação resultante de um INNER JOIN pode justificar a opção por múltiplos queries!
master - detail
nesta estrutrura de informação temos:
• uma página inicial que lista vários tópicos de um modo genérico;• uma página de detalhe que permite ver os detalhes do tópico escolhido na
página master
que informação é necessário transferir entre as páginas?
masteritem1item2item3
detaildetalhes do item
escolhido na página master
voltar
querystring: id_item.../page.php?a=5
exemplo: master-detail
master: listar todas as famílias
detail: listar os mariachis dessa família
exemplo: master > familias.php
$qFami = "SELECT * FROM Familia";$rsFami = mysql_query($qFami , $connection);
while ($row_rsFami = mysql_fetch_assoc($rsFami)){ $line = ‘<p><a href=”mariachisFamilia.php?id=’. $row_rsFami[“idFamilia”]. ’”>’. $row_rsFami[“nomeFamilia"]. ‘</a></p>’;
echo $line;}
os URLs na página serão, por exemplo: “mariachisFamilia.php?id=3”
exemplo: detail > mariachisFamilia.php
$idValue = intval($_GET['id']);$qMari = "SELECT * FROM Mariachi WHERE Familia_idFamilia = ".$idValue;$rsMari = mysql_query($qMari , $connection);
while ($row_rsMari = mysql_fetch_assoc($rsMari)){ $line = ‘<p>$row_rsMari[“nome”]</p>’;
echo $line;}
Como mostrar nesta página o nome da família?
exemplo: master-detail (parte 2)
master: listar todas as famílias
detail: listar os mariachis dessa família e incluir o número de relacionamentos com chicas
exemplo: master-detail (parte 2)
soluções a discutir:
• um query único baseado num INNER JOIN entre Mariachis e Mariachi_has_chica com operação de COUNT e filtragem pelo Mariachi?
• um query para o nome do Mariachi e um query para contar o número de registos do Mariachi em Mariachi_has_Chica?
exemplo: master-detail (parte 2)
problema com query único, típico destas situações:
• se um Mariachi não tiver uma ocorrência em Mariachi_has_Chica o resultado será um recordset vazio! Porquê?
• não será possível mostrar os dados da informação pessoal do Mariachi
neste cenário, a solução a adotar deve ser a segunda!
ou ainda melhor... uma solução com OUTER JOIN
TPC -> implementar esta solução :)
exemplo: master-detail (parte 2)
por zonas condicionais entende-se partes do código que devem ser processadas quando um recordset está ou não vazio
por exemplo:
• se o mariachi nunca teve relacionamentos apresentar uma mensagem “este mariachi não é um bom exemplo!”
• nos outros casos mostrar os relacionamentos
como implementar este tipo de condição?
• if ($rsName) ...
navegação e paginação
imagina que uma família pode ter centenas de mariachis!
• faz sentido mostrar numa página uma listagem com um número ilimitado de itens?
navegação - permite navegar nos itens, tipicamente:
• previous - next (page 3 of 6)
paginação - mais complexa e permite navegar diretamente para uma página, tipicamente
• 1 ... 5 6 7 8 9 ... 20
navegação
o que é necessário saber
• número total de registos• número de itens por página• número da página atual• registos para mostrar na página atual
navegação - número total de registos
recordset com query de COUNT de registos da tabela
navegação - número de itens por página
é um valor definido por nós e pode simplesmente ser guardado numa variável
se o utilizador tiver a possibilidade de alterar então podemos necessitar de uma cookie ou um parâmetro adicional na querystring
navegação - número da página atual
passado na querystring!
• next -> lê página atual e soma 1• previous -> lê página atual e subtrai 1• chama novamente a página com o novo id da página a visualizar• é necessário ter em atenção as condições para não permitir clicar nas
opções quando não existem mais páginas para trás ou para a frente• se não há valor da página deve assumir-se que é a primeira que deve ser
mostrada• verificar valores que podem ser introduzidos manualmente no URL
navegação - registos para mostrar na página atual
NUNCA fazer uma query a pedir sempre todos os registos!
na query do pedido deve ser especificado o LIMIT (length e offset)
• SELECT .... LIMIT offset, length• length é o valor do número de itens por página• offset é calculado com base na página atual e o número de itens por
página
desafio
criar uma função genérica que adicione, em qualquer cenário, uma barra de navegação!
• navigation_bar(nrTotalItens, nrItensPerPage, pageNumber)
NOTA: a função não é responsável por mostrar os registos na página! Essa lógica é da página e não da função.
DICA: para construir o URL ver chaves da super-variável _SERVER