Buscar

Apostila Projeto de Banco de Dados

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 38 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 38 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 38 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

APOSTILA DA DISCIPLINA 
PROJETO DE BANCO DE DADOS - 2013
Prof. Rodrigo Dantas Nunes
Versão 1.0.1
http://www.linkedin.com/in/rdantasnunes
http://lattes.cnpq.br/5868835072659556
1 – Linguagem Structured Query Language (SQL)
• Desenvolvida originalmente pela IBM no início de 1970, foi implementada a primeira vez em um protótipo da 
IBM chamado System R. Seu nome original era SEQUEL (Structured English Query Language)
• Rapidamente outras empresas criaram vários dialetos, onde surgiu a necessidade de um padrão, que foi criado 
pela ANSI em 1986.
• Versões SQL-86, SQL-89, SQL-92, SQL:1999, SQL:2003, SQL:2006, SQL:2008,SQL:2011
• Mesmo assim, há pequenas variações na SQL de um SGBD para outro.
• A SQL é composta pelos subconjuntos:
◦ DML – Data Manipulation Language – Subconjunto utilizado para inserções, consultas, alterações e 
exclusões de dados presentes em registros. Comandos: Insert, Select, Update e Delete.
◦ DDL – Data Definition Language – Subconjunto que permite definir tabelas novas e elementos 
associados. A maioria dos SGBD's tem extensões proprietárias no DDL. Comandos: CREATE, ALTER e 
DROP.
◦ DCL – Data Control Language – Controla os aspectos de autorização de dados e licenças de usuários para 
controlar quem tem acesso para ver ou manipular dados dentro do SGBD. Comandos: GRANT e 
REVOKE
◦ DTL – Data Transaction Language – Controla aspectos relativos a transações do SGBD, garantindo 
atomicidade na execução de um conjunto de comandos. Comandos: BEGIN WORK (START 
TRANSACTION, dependendo do dialeto SQL), COMMIT e ROLLBACK.
◦ DQL – Data Query Language – Possui apenas um comando, que é o próprio SELECT, e permite ao 
usuário especificar uma consulta com uma descrição do resultado desejado. Possui uma série de cláusulas 
e opções, possibilitando elaborar consultas das mais simples às mais elaboradas.
• Alguns SGBD's que usam SQL:
Apache Derby Informix Oracle
Caché Ingres PointBase Micro – Implementado em Java
DB2 InterBase SQLite
Firebird Microsoft Access LiteBase Mobile (Palm OS, Pocket PC, WinCE, etc...)
HSQLDB – Implementado em 
Java
Microsoft SQL Server Sybase Adaptive Server Enterprise
IDMS MySQL Teradata 
IMS PostgreSQL
1.2 Diferença entre dados e informação.
Dados – Os dados podem ser considerados a unidade básica da informação, ou seja, é a informação não tratada. 
Os dados representam um ou mais significados que isoladamente não transmitem uma mensagem, ou representam 
algum conhecimento.
 Ex.: Em quem o Fulano vai votar para prefeito?
 
Informação – Informações são dados tratados. O resultado do processamento de dados são as informações. As 
informações tem significado, podem ser tomadas decisões ou fazer afirmações considerando as informações
Ex.: Após processar a intenção de voto de todos os entrevistados, qual candidato tem mais chance de ganhar.
1.3 Tipos de Dados Padrão ANSI
A SQL oferece os seguintes tipos embutidos, mais ou menos auto-explicativos:
• BOOLEAN
• BIT [VARYING] (n) (Removidos na versão SQL:2003)
• BYNARY LARGE OBJECT (n)
• CHAR(n)
• CHARACTER [VARYING] (n)
• CHARACTER LARGE OBJECT (n)
• NUMERIC (p, q)
• INTEGER (p)
• SMALLINT
• FLOAT (p, q)
• DATE
• TIME
• TIMESTAMP
• INTERVAL
Diversos defaults, abreviações e ortografias alternativas também são aceitos. Como por exemplo: CHAR para 
CHARACTER, VARCHAR para CHARACTER VARYING, BLOB para BINARY LARGE OBJECT, etc...
1.4 Nomes de identificadores
Nomes de banco de dados, índices, colunas e alias seguem as mesmas regras no MySQL.
Identificador Tam máximo Caracteres permitidos
Banco de dados 64 Qualquer caractere permitido em um nome de diretório, exceto “/”, “\”ou '.'
Tabela 64 Qualquer caractere permitido em um nome de arquivo, exceto “/”, “\”ou '.'
Coluna 64 Todos os caracteres
Índice 64 Todos os caracteres
Alias 255 Todos os caracteres
As regras para nomes são as seguintes:
• Um nome pode conter caracteres alfanuméricos do character set corrente e também os caracteres “_” e “$”. O 
character set default ISO-8859-1 também conhecido como Latin1 que pode ser alterado recompilando o 
MySQL.
• Um nome pode iniciar com qualquer caractere válido, inclusive um número, mas não somente números.
• O caractere “.” (ponto) não pode ser utilizado dentro do nome pois é utilizado nas referências de colunas, que 
podem ser feitas das seguintes formas:
Referência Significado
Coluna Nome da coluna que é utilizada dentro de um comando select, update, etc...
'coluna' Nome de uma coluna delimitada com apóstrofe indica que o nome da coluna é uma palavra 
reservada ou contêm caracteres especiais.
tabela.coluna Nome da coluna da tabela especificada do banco de dados corrente.
bd.tabela.coluna Nome da coluna da tabela e banco de dados especificados.
1.5 Uso de maiúsculas e minúsculas
No MySQL, bancos de dados e tabelas correspondem a diretórios e arquivos dentro desses diretórios. Em razão 
disso, no Unix é feita distinção entre maiúsculas e minúsculas nos nomes de tabelas e bancos de dados, e no Windows 
não é feita distinção. Para manter compatibilidade de softwares que rodem em Unix, e Windows, pode ser colocado o 
parâmetro lowe_case_table_names=1 no arquivo my.ini na instalação do MySQL em servidores Windows.
Nos nomes de colunas não é feita distinção, em todos os casos. 
2 Gramática dos principais comandos SQL, no MySQL:
2.1.1 Create Database
Cria um banco de dados com o nome especificado. Para executar este comando, você precisa ter o privilégio 
de criação (CREATE).
CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] nome_bd 
[especificação [, especificação] ...]
O parâmetro especificação pode ser:
[DEFAULT] CHARACTER SET conj_caracteres 
 | [DEFAULT] COLLATE comp_caracteres
conj_caracteres: Conjunto de caracteres (charset) usado no banco de dados (ex: latin1, utf8, etc...). Você pode 
usar o comando SHOW CHARACTER SET; para visualizar as opções disponíveis.
comp_caracteres: Conjunto de regras (collation) para comparação dos caracteres de um conjunto (charset). 
Você pode usar o comando SHOW COLLATION; para visualizar as opções disponíveis.
O que é Collation de uma Base de dados? 
Existem configurações para conjuntos de caracteres e Collations em quatro níveis: servidor, banco de dados, tabela e 
conexão.
Collation nada mais é que a codificação de caracteres existente no Banco de Dados.
Quando você realiza a migração do conteúdo de um banco de dados, algumas vezes, pode haver conflitos no collation 
do banco migrado.
O resultado deste conflito é a ausência de caracteres especiais quando informações são consultadas no banco.
Por exemplo: Você cadastrou a palavra “Chapéu” no seu banco de dados, mas quando a programação do seu site 
busca este item, retorna o resultado “Chap?u”.
“Ou seja, os caracteres com acentuação como (é, ã, õ, etc.) são substituídos pelo sinal ”?” (interrogação).
Fonte: http://ajuda.uolhost.com.br/index.php?p=resposta&res=891#rmcl
2.1.2 ALTER DATABASE
Permite alterar as características de um banco de dados. Essas características ficam armazenadas no arquivo 
“db.opt”, localizado no diretório do banco de dados. Para executar esse comando, você precisa ter o privilégio de 
alteração (ALTER).
ALTER {DATABASE | SHEMA} nome_bd acao [, acao] ...
O parâmetro acao pode ser:
[DEFAULT] CHARACTER SET conj_caracteres 
 | [DEFAULT] COLLATE comp_caracteres
2.1.3 DROP DATABASE
Exclui um banco de dados inteiro, com todas suas tabelas. Para usar este comando, você precisa ter privilégio 
DROP no banco de dados.
DROP {DATABASE | SCHEMA} [IF EXISTS] nome_bd;
2.2.1 CREATE TABLE
Cria uma tabela no banco de dados selecionado.
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tabela [(definição, …)] [opções] [comando_select];
definição:
{
declaração_coluna
| PRIMARY KEY [tipo_índice] (coluna_índice, …) 
| KEY [índice] [tipo_índice] (coluna_índice, …)
| INDEX [índice] [tipo_índice] (coluna_índice, …)
| [CONSTRAINT [símbolo]] UNIQUE [INDEX] [índice] [tipo_índice] (coluna_índice, …)
| [FULLTEXT |SPATIAL] [INDEX] [nome_índice] (coluna_índice, …)
| [CONSTRAINT [símbolo]] FOREIGN KEY [INDEX] [índice] (coluna_índice, …) [definição_referência]
| CHECK (expressão)
}
declaração_coluna:
coluna tipo 
[NOT NULL | NULL] 
[DEFAULT valor] 
[AUTO_INCREMENT] 
[[PRIMARY] KEY]
[COMMENT 'seu comentário aqui'] 
[definição_referência]
coluna_índice: 
nome_coluna [(tamanho)] [ASC | DESC]
definição_referência:
REFERENCES nome_tabela [(coluna_índice, …) ]
[MATCH FULL | MATCH PARTIAL | MATCH SIMPLE]
[ON DELETE opção_referencia] 
[ON UPDATE opção_referencia]
O parametro opção_referencia pode ser:
RESTRICT | CASCADE | SET NULL |NO ACTION
opções:
opção_tabela [opção_tabela] … 
opção_tabela: 
 {ENGINE | TYPE }= nome
| AUTO_INCREMENT = valor
| AVG_ROW_LENGTH = n
| CHECKSUM = {0 | 1}
| COMMENT = 'comentário da tabela aqui'
| DELAY_KEY_WRITE = {0 | 1}
| MAX_ROWS = n
| MIN_ROWS = n
| PACK_KEYS = {0 | 1}
| PASSWORD = “senha”
| ROW_FORMAT={DEFAULT | DYNAMIC | FIXED | COMPRESSED | REDUNDANT | COMPACT }
| UNION = (nome_tabela [, nome_tabela] … )
| INSERT_METHOD = {NO | FIRST | LAST}
| DATA DIRECTORY = 'caminho'
| INDEX DIRECTORY = 'caminho'
| [DEFAULT] CHARACTER SET = conj_caracteres [COLLATE comp_caracteres]
comando_select:
[IGNORE | REPLACE ] [AS] SELECT … (comando SELECT válido)
Parâmetro Significado
TEMPORARY Cria uma tabela temporária, visível somente para a conexão corrente, a qual será removida 
quando a conexão for finalizada.
IF NOT EXISTS Cria a tabela somente se não existir uma tabela com o mesmo nome.
tabela Nome da tabela a ser criada
definição Lista das colunas e índices a serem criados.
declaração_coluna Declaração da coluna. É opcional se a tabela for criada com o resultado de um comando 
select.
coluna Nome da coluna.
tipo Tipo da coluna
NOT NULL Não permite valores NULL na coluna
NULL Permite valores NULL na coluna. (É o padrão)
DEFAULT Atribui o valor DEFAULT à coluna, quando uma nova linha for criada sem especificar o 
valor da coluna.
AUTO_INCREMENT Tipo especial de coluna numérica que pode ser atualizada automaticamente. Quando um 
valor NULL (ou 0) for inserido na coluna, o MySQL o substituirá automaticamente pelo 
próximo número na sequencia da coluna. O primeiro valor da coluna pode ser atribuído na 
opção AUTO_INCREMENT, e o default é 1. É permitida apenas uma coluna 
AUTO_INCREMENT por tabela e a coluna deve ser UNIQUE ou PRIMARY KEY.
PRIMARY KEY Identifica a chave primária da tabela.
índice Nome do índice a ser criado.
tipo_índice O método de indexação utilizado (BTREE, FULLTEXT, HASH ou RTREE)
coluna_índice Coluna a ser utilizada no índice. Para colunas CHAR e VARCHAR pode ser especificado o 
número de caracteres da coluna, usando a sintaxe: coluna(tamanho). Para colunas BLOB e 
TEXT, o tamanho deve ser sempre especificado.
KEY O mesmo que INDEX
INDEX Cria um índice. Podem existir até 16 índices por tabela.
UNIQUE Cria um índice sem duplicidade. Ocorrerá um erro ao se adicionar uma nova linha que 
coincida com uma linha existente.
FULLTEXT Índice para colunas do tipo TEXT.
SPATIAL Índice para colunas do tipo espacial, como por exemplo, tipos geométricos.
comando_select Cria a tabela a partir dos registros retornados pelo comando SELECT
Significado das opções que podem ser informadas na tabela
ENGINE | TYPE Permite definir a ferramenta de armazenamento dos dados (storage engine). Recomendo usar 
InnoDB. Ver quadro abaixo.
AUTO_INCREMENT Valor inicial de AUTO_INCREMENTpara a tabela. (Somente para engine = MyISAM)
AVG_ROW_LENGTH Tamanho médio aproximado das linhas na tabela. Usado para determinar o tamanho máximo 
de arquivo para tabelas com ccolunas BLOB ou TEXT que podem ultrapassar o limite de 
4GB.
CHECKSUM Mantém (1) ou não (0) um checksum para cada linha da tabela. Torna a atualização da tabela 
um pouco mais lenta, mas facilita a procura por erros na tabela. (somente para MyISAM).
COMMENT Comentário da tabela até 60 caracteres.
DELAY_KEY_WRITE Atualiza o cache do índice da tabela ocasionalmente (1) ou a cada inserção (0). Somente 
para MyISAM.
MAX_ROWS Número máximo de linhas previsto para a tabela
MIN_ROWS Número mínimo de linhas previsto para a tabela
PACK_KEYS Se definida como 1, compacta os blocos de índices em uma porcentagem maior que a usual, 
tornando as operações de atualização mais demoradas e as de leitura mais rápidas. Se 
definida como 0, somente os índices com chaves CHAR e VARCHAR, com 8 ou mais 
caracteres, são compactados. Somente para MyISAM.
PASSWORD Especifica uma senha para a encriptação do arquivo de descrição da tabela (.frm). Somente 
para versões especiais do MySQL; não tem efeito na versão padrão.
ROW_FORMAT Define como as linhas deverão ser armazenadas.
UNION Permite o uso de várias tabelas idênticas como se fosse uma só.
INSERT_METHOD Define como as linhas serão inseridas em tabelas unidas (através de MERGE).
DATA DIRECTORY
INDEX DIRECTORY
Caminho absoluto para os diretórios onde devem ser armazenados os arquivos de dados e de 
índices, respectivamente.
CHARACTER SET São os mesmos usados na criação da base de dados. Comando CREATE DATABASE.
Principais opções de Engine no MySQL
Nem todas as engines estão disponíveis ou habilitadas, isso depende de como você compilou seu MySQL, mas vamos partir do princípio que temos 
as principais engines instaladas e habilitadas, e vamos descrever para que serve algumas delas:
MyISAM – Essa é a principal storage engine do MySQL, ela está habilitada em qualquer configuração do MySQL e é a engine default quando 
criamos as tabelas. Isso significa que quando criamos uma tabela sem especificar a engine, ela será uma tabela do tipo MyISAM.
Quando criamos uma tabela MyISAM ela é armazenada no disco em três arquivos. Os arquivos tem nomes que começam com o nome da tabela e 
tem uma extensão para indicar o tipo de arquivo. Arquivos do tipo .frm armazenam o formato da tabela, enquanto os dados ficam em um arquivo 
com a extensão .MYD, já os índices ficam no arquivo com extensão MYI.
Outra característica das tabelas MyISAM são os índices fulltext, que são usados para buscas de palavras em blocos de texto. Buscas com índices 
fulltext nos dão maior controle de resultados fazendo até mesmo um calculo de relevância.
InnoDB – O InnoDB é uma engine rápida e com transações seguras. O InnoDB armazena todas as suas tabelas e índices em um tablespace, o que 
significa que elas podem ser armazenadas em diversos arquivos, diferente das tabelas MyISAM que são armazenadas em arquivos separados. O 
mecanismo de armazenamento InnoDB é feito por uma empresa separada, a InnoBase Oy.
InnoDB nos oferecem além de transações seguras, lock de registro, Foreign Key e leituras consistentes sem lock nos select's.
Fonte: http://www.mamura.com.br/os-tipos-de-tabelas-do-mysql/
2.2.2 ALTER TABLE
Modifica os atributos de um campo ou adiciona um novo campo em uma determinada tabela em um banco de 
dados selecionado. A instrução IGNORE (opcional, e não recomendada) é utilizada para informar que somente a 
primeira linha deve ser usada quando encontrar duplicidade em uma chave UNIQUE. As demais serão eliminadas. Se a 
opção não for especificada, será emitida uma mensagem de erro e nenhuma alteração será feita. 
ALTER [IGNORE ] TABLE tabela ação [, ação … ]
ação:
 ADD [COLUMN] declaração_coluna [FIRST | AFTER nome_coluna]
FIRST= Adiciona a nova coluna na primeira posição da tabela.
AFTER= Adiciona a nova coluna após a coluna especificada no parametro nome_coluna
| ADD [COLUMN] declaração_coluna 
| ADD INDEX [índice] [tipo_índice] (coluna, …) 
| ADD [CONSTRAINT [símbolo]] PRIMARY KEY [tipo_índice] (coluna, … ) 
| ADD [CONSTRAINT [símbolo]] UNIQUE [índice] [tipo_índice] (coluna, … )
| ADD [FULLTEXT | SPATIAL] [índice] (coluna, … )
| ADD [CONSTRAINT [símbolo]] FOREIGN KEY [índice] (coluna, … ) [definição_referencia]
| ALTER [COLUMN] coluna {SET DEFAULT literal | DROP DEFAULT}
| CHANGE [COLUMN] coluna declaração_coluna [FIRST | AFTER nome_coluna]
| DISABLE KEYS /* Indicaque o MySQL deve parar de atualizar os índices que não são únicos(UNIQUE)*/ 
| DROP [COLUMN] coluna
| DROP INDEX índice
| DROP PRIMARY KEY
| DROP FOREIGN KEY símbolo
| ENABLE KEYS /* Usado para recriar os índices perdidos devido ao uso da opção DISABLE KEYS*/ 
| MODIFY [COLUMN] declaração_coluna [FIRST | AFTER nome_coluna] 
| ORDER BY coluna /* Permite colocar as linhas da tabela em uma ordem pré-estabelecida. */ 
| RENAME [TO] novo_nome_tabela
Observação: Ainda dentro do comando ALTER TABLE, existe outra sintaxe que permite a alteração de diversas 
opções da tabela. Para saber quais são as opções, consulte o comando CREATE TABLE.
ALTER [IGNORE] TABLE tabela opções_tabela
2.2.3 DROP TABLE 
Elimina uma tabela em um banco de dados selecionado.
DROP [TEMPORARY] TABLE [IF EXISTS] tabela [, tabela … ] 
Neste caso, além de eliminar a tabela do banco, apaga também todos os dados contidos nela.
2.3.1 INSERT
É utilizado para inserir valores dentro de uma determinada tabela em um banco de dados selecionado. Cada 
comando será utilizado para inserir somente um único registro na tabela.
FORMATO 1:
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE] [INTO] tabela [(coluna, … )]
VALUES ({expressao | DEFAULT}, … ), (…), … [ON DUPLICATE KEY UPDATE coluna=expressao, … ]
FORMATO 2:
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE] [INTO] tabela [(coluna, … )]
SELECT … /*Comando select válido*/
FORMATO 3:
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE] [INTO] tabela 
SET coluna={expressao | DEFAULT}, … 
[ON DUPLICATE KEY UPDATE coluna=expressao, … ]
Parâmetro Descrição
LOW_PRIORITY Retarda a execução do comando até que nenhum outro programa-cliente esteja lendo a tabela
DEFAULT Define uma coluna com o seu valor padrão.
DELAYED Coloca as linhas em uma fila para inserção posterior, quando nenhum outro cliente estiver 
acessando a tabela.
HIGH_PRIORITY Substitui o valor da opção –low-priority-updates, caso o servidor tenha sido iniciado com ele.
IGNORE Descarta linhas com valores duplicados para chaves UNIQUE. Se essa opção não for 
especificada, ocorrerá um erro se forem encontrados valores duplicados e nenhuma outra 
linha será inserida. 
[INTO] tabela Nome da tabela. INTO é opcional
VALUES Insere linhas baseado nos valores especificados. Múltiplas linhas de valores podem ser 
especificadas, permitindo a inserção de múltiplas linhas em um único INSERT.
SELECT Insere as linhas retornadas pelo comando SELECT
SET Atribui os valores das expressões às colunas. Colunas não especificadas terão seus valores 
default.
ON DUPLICATE KEY Caso a inserção gere duplicidade na chave primária ou em um índice UNIQUE, essa opção 
permite alterar o valor do registro antigo.
2.4.1 DELETE 
É utilizado para excluir um ou mais registros de uma determinada tabela em um banco de dados selecionado. 
Serão excluídos todos os registros que satisfazem a expressão de pesquisa ao registro.
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM tabela [WHERE condição] [ORDER BY … ] 
[LIMIT n]
Existe ainda uma sintaxe para múltiplas tabela:
 DELETE [LOW_PRIORITY] [QUICK] [IGNORE] tabela[.*] [, tabela[.*] …] FROM referencia_tabela 
[WHERE condição] 
Parâmetro Descrição
LOW_PRIORITY Retarda a execução do comando até que nenhum outro programa-cliente esteja lendo a tabela
QUICK Pode acelerar a execução de certos tipos de exclusão em tabelas MyISAM.
IGNORE Descarta linhas com valores duplicados para chaves UNIQUE. Se essa opção não for 
especificada, ocorrerá um erro se forem encontrados valores duplicados e nenhuma outra 
linha será apagada. 
WHERE Especifica a condição que determina quais linhas devem ser eliminadas. Se a cláusula 
WHERE não for especificada, todas as linhas da tabela serão eliminadas.
ORDER BY Permite definir a ordem de exclusão das linhas.
LIMIT Limita o número de linhas a serem eliminadas.
referencia_tabela Lista as tabelas envolvidas na junção (join).
2.5.1 UPDATE
Modifica campos em um registro em uma determinada tabela em um banco de dados selecionado. Serão 
alterados todos os registros que satisfizerem a expressão de pesquisa ao registro.
UPDATE [LOW_PRIORITY] [IGNORE] tabela SET coluna=expressao [, coluna=expressao] ... 
[WHERE condicao] [ORDER BY ... ] [LIMIT n] 
Para atualizar múltiplas tabelas, pode usar a seguinte sintaxe:
UPDATE [LOW_PRIORITY] [IGNORE] tabela [, tabela ... ] SET coluna=expressao [, coluna=expressao] ...
[WHERE condicao]
Parâmetro Descrição
LOW_PRIORITY Retarda a execução do comando até que nenhum outro programa-cliente esteja lendo a tabela
IGNORE Descarta linhas com valores duplicados para chaves UNIQUE. Se essa opção não for 
especificada, ocorrerá um erro se forem encontrados valores duplicados e nenhuma outra 
linha será atualizada. 
tabela Nome da tabela a ser atualizada.
SET Especifica as colunas a serem atualizadas e os respectivos valores a serem atribuídos.
WHERE Especifica a condição que determina quais linhas devem ser atualizadas. Se a cláusula 
WHERE não for especificada, todas as linhas da tabela serão atualizadas.
ORDER BY Permite definir a ordem de atualização das linhas.
LIMIT Limita o número de linhas a serem atualizadas.
2.6.1 SELECT
É um dos comandos mais utilizados da SQL, pois permite a realização de consultas nas tabelas de um banco de 
dados. As consultas retornam todos os registros que satisfizerem a condição especificada. O comando SELECT pode 
retornar também o resultado de expressões (ex.: 1+1).
SELECT [predicado] [opcoes_select] coluna [,...] 
[INTO OUTFILE 'nome_arquivo' delimitadores | INTO DUMPFILE 'nome_arquivo']
[FROM tabelas
[WHERE condicao]
[GROUP BY {coluna | expressao | posicao } [ASC | DESC] ,... [WITH ROLLUP]]
[HAVING condicao]
[ORDER BY {coluna | expressao | posicao } [ASC | DESC] ,...]
[LIMIT { [linha_inicial,] num_linhas | num_linhas OFFSET linha_inicial} ] 
[PROCEDURE nome (lista_argumentos)]
[FOR UPDATE | LOCK IN SHARE MODE]
]
predicado:
DISTINCT | DISTINCTROW | ALL
opcoes _select:
[HIGH_PRIORITY] [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] 
[SQL_BUFFER_RESULT] [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
delimitadores:
[FIELDS
[TERMINATED BY 'string' ]
[[OPTIONALLY] ENCLOSED BY 'char']
[ESCAPED BY 'char']
]
[LINES 
[STARTING BY 'string']
[TERMINATED BY 'string']
]
condicao:
 condicao OR condicao
| condicao || condicao
| condicao XOR condicao 
| condicao AND condicao
| condicao && condicao
| NOT condicao 
| ! condicao
| boolean_value IS [NOT] {TRUE | FALSE | UNKNOWN}
| boolean_value 
Parâmetro Descrição
DISTINCT Restringe as linhas a serem retornadas. Omite registros que contenham dados 
duplicados nos campos selecionados.
DISTINCTROW Sinônimo de DISTINCT.
ALL Seleciona todas as linhas que atendam às condições especificadas.
HIGH_PRIORITY Atribui ao comando SELECT prioridade maior que aos comandos que atualizam 
tabelas. Deve ser usada somente para consultas que são muito rápidas e que devam 
ser feitas uma única vez.
STRAIGHT_JOIN Força a junção das tabelas na ordem em que elas estão especificadas na cláusula 
FROM. Pode ser usada caso você ache que o MySQL não está fazendo a junção da 
melhor forma.
SQL_SMALL_RESULT Pode ser usado com GROUP BY ou DISTINCT para informar ao MySQL que o 
resultado do SELECT será pequeno. Nesse caso, o MySQL usa tabelas temporárias 
para armazenar os resultados, ao invés de ordená-los.
SQL_BIG_RESULT Pode ser usado com GROUP BY ou DISTINCT para informar ao MySQL que o 
resultado do SELECT será grande. Nesse caso, o MySQL ordena os resultados em 
vez de usar uma tabela temporária. No caso de falta de memória, tabelas temporárias 
em disco podem ser utilizadas pelo MySQL.
SQL_BUFFER_RESULT Força o armazenamento dos resultados das consultas em tabelas temporárias.
SQL_CACHE Indica que o resultado deve ser armazenado na memória cache de consultas (query 
cache).
SQL_NO_CACHE Indica que o resultado não deve ser armazenado na memória cachede consultas.
SQL_CALC_FOUND_ROWS Calcula quantas linhas deveriam ser retornadas pela consulta, desconsiderando a 
cláusula LIMIT. Esse valor pode ser retornado por SELECT FOUND_ROWS().
coluna Nome das colunas a serem retornadas pela consulta. Se for usado o asterisco (*), 
serão retornadas todas as colunas. Pode-se atribuir um alias a uma coluna usando a 
sintaxe: AS nome_alias. O alias pode ser utilizado no lugar do nome nas cláusulas 
GROUP BY, ORDER BY e HAVING.
INTO Redireciona a saída do comando SELECT para um arquivo. É necessário ter o 
privilégio FILE e o arquivo de saída não deve existir.
OUTFILE Redireciona a saída para um arquivo que é criado no servidor.
DUMPFILE Escreve apenas uma linha no arquivo, sem mudança de linha e sem modificar o 
conteúdo. Útil para armazenar o conteúdo de um campo BLOB em um arquivo.
FIELDS TERMINATED BY Especifica o caractere ou caracteres
 para delimitar valores na linha (default = '\t').
OPTIONALLY Somente colunas dos tipo CHAR e VARCHAR recebem o caractere especificado por 
ENCLOSED BY.
FIELDS ENCLOSED BY Especifica o caractere utilizado para delimitar o string de caracteres (defalt = ' ').
FIELDS ESCAPED BY Especifica o caractere utilizado para indicar que o próximo caractere não é um 
caractere especial (default = '\\')
LINES TERMINATED BY Especifica o caractere ou caracteres que indicam o final de uma linha (default='\n')
FROM ref_tabelas Especifica o nome das tabelas dos campos a serem utilizados no comando SELECT. 
Consulte a cláusula JOIN para saber como fazer junções de tabelas.
WHERE Especifica a condição que determina quais linhas serão retornadas.
GROUP BY Retorna um valor para cada grupo de registros. Cria um registro de resumo para cada 
registro definido.
WITH ROLLUP Opção usada em conjunto com GROUP BY para adicionar linhas ao resultado da 
consulta (ex: linha extra com valor referente aos registros que não foram agrupados).
HAVING Similar à cláusula WHERE, mas restringe somente os registros retornados pela 
cláusula GROUP BY.
ORDER BY Especifica as colunas a serem usadas como chave para ordenar os registros 
retornados.
DESC Ordem descendente.
ASC Ordem ascendente. (Padrão)
LIMIT Limita o número de linhas a serem retornadas pelo comando SELECT
linha_inicial Número da primeira linha a serr retornada. (Esta contagem inicia em zero)
num_linhas Número de linhas a serem retornadas.
PROCEDURE Especifica uma procedure para a qual os dados retornados serão enviados antes de 
serem retornados ao cliente.
FOR UPDATE Se o sistema de armazenamento usar páginas ou bloqueios de linha, as linhas 
examinadas pela consulta são bloqueadas para escrita (write-locked) até o fim da 
transação corrente.
LOCK IN SHARE MODE Define um bloqueio compartilhado (shared lock), para previnir que outras transações 
alterem ou excluam as linhas consultadas.
2.6.2 Cláusula JOIN
As seguintes sintaxes são permitidas para o uso da clásula JOIN em comandos SELECT:
ref_tabela1, ref_tabela2, ref_tabelaN
ref_tabela1 STRAIGHT_JOIN ref_tabela2
ref_tabela1 [ [RIGHT | LEFT] [OUTER] | INNER | CROSS] JOIN ref_tabela2 [condicao]
ref_tabela1 NATURAL [[LEFT | RIGHT] [OUTER]] JOIN ref_tabela2 { OJ ref_tabela1 LEFT OUTER 
JOIN ref_tabela2 ON condicao}
condicao:
ON expressao_condicional | USING (lista_colunas)
ref_tabela:
nome_tabela [[AS] alias] 
[[USE INDEX (chaves)] | [IGNORE INDEX (chaves)] | [FORCE INDEX (chaves)]]
Parâmetro Descrição
, (a vírgula) Retorna todas as combinações possíveis de linhas das tabelas. Normalmente a condição de 
junção é especificada na cláusula WHERE.
JOIN Equivale à utilização da vírgula.
CROSS JOIN O mesmo que JOIN.
INNER JOIN O mesmo que JOIN.
STRAIGHT_JOIN Similar a JOIN, exceto que a tabela da esquerda é sempre lida antes da tabela da direita. 
Utilizado quando o otimizador efetua a junção de forma errada.
LEFT JOIN Retorna todas as linhas da tabela da esquerda mesmo que não exista equivalência na tabela 
da direita (nesse caso, preenche com NULL). A condição para a junção é determinada pelas 
cláusulas ON ou USING.
RIGHT JOIN Retorna todas as linhas da tabela da direita mesmo que não exista equivalência na tabela da 
esquerda (nesse caso, preenche com NULL). A condição para a junção é determinada pelas 
cláusulas ON ou USING.
ON Especifica a condição para a junção das tabelas.
USING Especifica a lista de colunas que devem existir em ambas as tabelas. Exemplo: A left join B 
using (col1,col2,col3,...)
LEFT OUTER JOIN O mesmo que LEFT JOIN. Somente para compatibilidade com o ODBC.
RIGHT OUTER JOIN O mesmo que RIGHT JOIN. Somente para compatibilidade com o ODBC.
NATURAL LEFT JOIN Equivalente a LEFT JOIN USING.
2.7.1 Operadores 
2.7.2 Operador LIKE 
Retorna 1 (true) se uma expressão corresponder a um padrão. Permite a utilização de expressões numéricas. Se 
NOT for especificado, retornará 1 se não possuir correspondencia.
expressao [NOT] LIKE padrao [escape 'escape-char']
padrao: Sequência de caracteres com a qual a expressão é comparada. Não distingue minúsculas de maiúsculas. Os 
caracteres '%' e '_' (Underline) dentro do padrão tem a seguinte interpretação:
% = Equivale a qualquer sequencia de zero ou mais caracteres.
_ = Equivale a qualquer caractere.
 Escape = Especifica o caractere escape (o padrão é '\'). Um caractere escape remove o significado especial do 
caractere % ou \ que o segue.
2.7.3 Operadores Aritiméticos
Operador Sintaxe Significado
+ X + Y Soma dois valores numéricos
- X – Y Subtrai dois valores numéricos
* X * Y Multiplica dois valores numéricos
/ X \ Y Divide um valor numérico por outo. A divisão por zero produz um resultado null.
% X % Y Retorna o módulo aritimético de dois valores numéricos.
2.7.4 Operadores lógicos
Operador Sintaxe Significado
NOT ou ! NOT x Retornará 1 (True) se o argumento for 0 (False); caso contrário, retornará 0. Exceção: 
NOT NULL retornará NULL.
OR ou | | x OR y Retornará 1 (True) se um dos argumentos não for 0 (False) nem NULL.
AND ou && x AND y Retornará 0 (False) se um dos argumentos for 0 (False) ou NULL; caso contrário, 
retornará 1 (True).
2.7.5 Operadores de comparação
Operador Sintaxe Significado
= X = Y Igualdade
<> ou != X <> Y Diferente
<= X <= Y Menor que ou igual.
< X < Y Menor
>= X >= Y Maior que ou igual.
> X > Y Maior
<=> X <=> Y True se os dois operandos forem iguais, mesmo para comparações com NULL.
IS [NOT] NULL Retornará 1 (True) se um valor for NULL; caso contrário, retornará 0 (False). Se 
NOT for especificado, retornará 1 (True) se o valor não for NULL.
expr BETWEEN min AND max Determina se o valor de uma expressão está dentro de um intervalo de valores. A 
cláusula BETWEEN é inclusiva, isso significa que tanto min como max serão 
incluídos na comparação. Se expr for maior ou igual a min e expr for menor ou 
igual a max, BETWEEN retornará 1; caso contrário, retornará 0.
expr [NOT] IN (valor1, 
valor2, ...)
Retornará 1 se expr for um dos valores na lista IN; caso contrário, retornará 0. Se 
NOT for especificado, retornará 1 se não estiver na lista.
2.8.1 UNION
Union é usado para combinar o resultado de múltiplas declarações SELECT em um único resultado. Os nomes 
das colunas do primeiro SELECT são usados como nome de coluna do resultado retornado. Colunas selecionadas 
listadas em posições correspondentes de cada instrução SELECT devem ter o mesmo tipo de dados. Assim, se a 
primeira coluna do primeiro SELECT for um integer, a primeira coluna do segundo SELECT também deverá ser um 
integer. Caso esta recomendação não seja atendida, fica na responsabilidade do desenvolvedor tratar o retorno dos dados 
de tipos diferentes. Por padrão, no MySQL, não serão retornados valores duplicados.
SELECT …..
UNION [ALL | DISTINCT]
SELECT ….
[UNION [ALL | DISTINCT]
 SELECT ….]
2.9.1 Grant
Permite aos administradores a criação de contas no MySQL e a definição dos privilégios das mesmas.
GRANT privilégio [(lista_colunas)][, privilégio [(lista_colunas)]] …
ON [tipo_objeto] {tabela | * | *.* | nome_bd.*}
TO usuário [IDENTIFIED BY [PASSWORD] 'senha']
[, usuário [IDENTIFIED BY [PASSWORD] 'senha']] …
[REQUIRE {NONE | ssl_option [[AND] ssl_option] …}]
[WITH with_options …]
tipo_objeto:
{TABLE | FUNCTION | PROCEDURE}
ssl_option:
SSL | X509 | CIPHER 'cipher' | ISSUER 'issuer' | SUBJECT 'subject' 
with_options:
GRANT OPTION 
| MAX_QUERIES_PER_HOUR numero 
| MAX_UPDATES_PER_HOUR numero
| MAX_CONNECTIONS_PER_HOUR numero
| MAX_USER_CONNECTIONS numero
2.10.1 Revoke
Revoga os privilégios concedidos com o comando GRANT a determinadas contas no MySQL. 
REVOKE privilégio [(colunas)] [, privilégio [(colunas)]] …
ON [tipo_objeto] {tabela | * | *.* | nome_bd.*}
FROM usuário [, usuário] ...
REVOKE ALL PRIVILEGES, GRANT OPTION FROM usuário [, usuário] ...
O parâmetro “privilégio” indica quais são os privilégios a serem concedidos ou revogados. A tabela a seguir 
apresenta os valores possíveis:
Privilégio Descrição
ALL [PRIVILEGES] Todos os privilégios simples, exceto GRANT OPTIN
ALTER Permite o uso de ALTER TABLE
ALTER ROUTINE Altera ou exclui rotinas armazenadas.
CREATE Permite o uso do CREATE TABLE.
CREATE ROUTINE Cria rotinas armazenadas.
CREATE TEMPORARY 
TABLES 
Permite o uso de CREATE TEMPORARY TABLE.
CREATE USER Permite o uso de CREATE USER, DROP USER, RENAME USER e REVOKE ALL 
PRIVILEGES.
CREATE VIEW Permite o uso de CREATE VIEW
DELETE Permite o uso de DELETE.
DROP Permite o uso de DROP TABLE.
EXECUTE Permite a execução de Stored Procedure
FILE Permite o uso de SELECT ... INTO OUTFILE e LOAD DATA INFILE.
INDEX Permite o uso de CREATE INDEX e DROP INDEX.
INSERT Permite o uso de INSERT.
LOCK TABLES Permite o uso de LOCK TABLES em tabelas para as quais há o privilégio SELECT
PROCESS Permite o uso de SHOW FULL PROCESS-LIST.
RELOAD Permite o uso de FLUSH.
REPLICATION CLIENT Permite ao usuário consultar onde estão os servidores master e slave.
REPLICATION SLAVE Necessário para replicação de servidores slaves (para ler eventos do log do master).
SELECT Permite o uso de SELECT.
SHOW DATABASES Indica que o SHOW DATABASES deve mostrar todos os bancos de dados.
SHOW VIEW Permite o uso de SHOW CREATE VIEW.
SHUTDOWN Este privilégio permite o uso de @command{mysqladmin shutdown}
SUPER Permite o uso dos comandos CHANGE MASTER, KILL, PURGE MASTER LOGS, SET 
GLOBAL e @command{mysqladmin debug}; Permite conectar mesmo se o número 
máximo de conexões for atingido.
UPDATE Permite o uso de UPDATE
USAGE Sinônimo de “no privileges”.
GRANT OPTION Permite a definição de privilégios.
2.11.1 Create Procedure e Create Function
Estes comandos criam rotinas armazenadas, mas conhecidas como Stored Procedure e Stored Function. Por 
padrão, a rotina é associada com a base de dados corrente. Para associar a rotina a uma base de dados específica, deve 
ser indicado o nome da base, separado por um ponto, antes do nome da própria procedure. Ex.: base.nome_proc.
Para invocar uma Stored Procedure, use o comando CALL, (Ex.: call nome_pro(parametros...); ). Já a função, 
refira-se a ela em uma expressão. (Ex.: select nome_funcao(parametros); )
CREATE [DEFINER = { user | CURRENT_USER }]
PROCEDURE nome_proc ([proc_param[,...]])
[caracteristica …] corpo_rotina
CREATE [DEFINER = { user | CURRENT_USER }]
FUNCTION nome_proc ([function_param[,...]])
RETURNS tipo
[caracteristica …] corpo_rotina
user:
 Se especificado a cláusula DEFINER, o usuário informado deve ser no mesmo formato usado no GRANT, ou a 
expressão CURRENT_USER().
nome_proc: 
 Nome dado à Stored Procedure, ou Stored Function.
proc_param:
 [IN | OUT | INOUT] nome_parametro tipo
function_param:
 nome_parametro tipo
tipo:
 Qualquer tipo de dado válido no MySQL.
caracteristica:
 COMMENT 'string'
 | LANGUAGE SQL
 | [NOT] DETERMINISTIC
 | {CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA}
 | SQL SECURITY {DEFINER | INVOKER}
corpo_rotina:
 Comandos SQL válidos para procedimento.
2.11.2 Drop Procedure e Drop Function
Procedure's e Function's não podem ser alteradas, assim, caso haja necessidade de alterá-las, é preciso excluí-
las, e recriá-las.
Para excluir tanto uma procedure quanto uma function, a gramática é a seguinte:
DROP {PROCEDURE | FUNCTION} [IF EXISTS] sp_name
2.12.1 Triggers
Uma trigger, ou gatilho, é uma espécie de procedure vinculada a uma tabela. É disparada sempre que um 
determinado evento acontece. Evento este, especificado no ato da declaração desta trigger. Estes eventos são, DELETE, 
INSERT ou UPDATE. Pode haver apenas uma trigger para cada tabela/evento. Estas triggers são definidas para 
executar antes, ou depois dos eventos.
INSERT: Sempre que uma nova linha é inserida na tabela; Ex.: Através do comando INSERT, ou LOAD DATA
UPDATE: Sempre que uma linha é modificada; Ex.: Comando update
DELETE: Sempre que uma linha é apagada da tabela. Ex.: Comandos delete, replace. Mas não comandos drop table, ou 
truncate table, pois estes não executam o DELETE.
Dentro da trigger, ao inserir um novo registro, temos o operador NEW que permite acessar dados da linha 
sendo inserida. No evento DELETE, temos o operador OLD, que nos permite acessar os dados antigos. E no UPDATE, 
temos o NEW e o OLD a disposição.
create trigger nome_trigger tempo evento
on tabela 
for each row begin
 comandos sql válidos
end; 
2.12.2 Drop Trigger
Para excluir uma trigger, a gramática do comando é a seguinte:
DROP [IF EXISTS] [database.]nome_trigger;
2.13.1 Views
Uma view, ou visão, como também é chamada, é um objeto do banco de dados baseado em comandos 
SELECT's. A view, é uma espécie de tabela virtual baseada no SELECT que é usado para sua criação. Por padrão, a 
view é criada na base de dados corrente. Para especificar que a view deve ser criada em uma dada base de dados 
diferente da atual, deve ser informado o nome da base antes do nome da view, separada por um ponto. As vantagens são 
basicamente o fato da consulta ficar armazenada, e você não ter o retrabalho de criá-la novamente, e principalmente a 
performance.
CREATE [OR REPLACE] [ALGORITHM = {MERGE | TEMPTABLE}]
VIEW nome_view [(lista_colunas)]
AS comando_select 
[WITH [CASCADED | LOCAL] CHECK OPTION]
Parâmetro Descrição
ALGORITHM Indica como o MySQL deve processar a visão. Pode assumir os valores 
MERGE, TEMPTABLE ou UNDEFINED(padrão). Para o valor MERGE, o 
texto do comando é unido com a definição da visão, sendo que as partes da 
definição substituem as partes correspondentes do comando. Para o valor 
TEMPTABLE, os resultados da visão são retornados em uma tabela 
temporária, que é usada para execução do comando. Para o valor 
UNDEFINED, o MySQL escolhe o algoritmo a ser utilizado.
nome_view Nome que identificará a visão.
lista_colunas Lista com os nomes das colunas que farão parte da view. Substitui a 
necessidade de usar um alias para cada coluna no select.
comando_select Comando SELECT a partir do qual a visão será gerada.
WITH CHECK OPTION Esta cláusula pode ser dada por uma view atualizável para evitar inserções ou 
atualizações de linhas, exceto aquelas para os quais a cláusula WHERE no 
SELECT seja TRUE.
LOCAL | CASCADED Determinam o escopo em que a verificação de CHECK OPTION será 
realizada. LOCAL restringe a verificação somente para a view sendo 
definida. Já CASCADED, verifica nas views subjacentes também sendo 
executadas.
2.14.1 Transaction
Todos os comandos abaixo proveem controle sobre o uso de transações.
1 - START TRANSACTION [WITH CONSISTENT SNAPSHOT]
2 - BEGIN [WORK]
São sinonimos e ambos iniciam uma transação.
3 - COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
Encerra a transação corrente tornando todas as alterações realizadas permanentes.
4 - ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
Reverte e encerra a transação corrente, cancelando todas as alterações feitas desdo o seu início.
5 - SET autocommit = {0 | 1}
Disabilita ou habilita o modo padrão de autocommit para a sessão corrente.
Porpadrão, o MySQL executa com modo autocommit habilitado, então, toda declaração executada que 
modifica uma tabela, é armazenada no disco e feita de forma permanente, e a alteração não pode ser desfeita. Para 
disabilitar o modo autocommit implicitamente para uma série simples de declarações, deve ser usado o comando 
START TRANSACTION.
3 Funções do MySQL
Funções utilizadas dentro do comando SELECT.
3.1 Funções de agregação
Função Descrição
AVG([DISTINCT] expressao) Retorna a média de expressao, para valores não-nulos nas linhas selecionadas. 
A partir do MySQL 5.0.3 pode ser usada a opção DISTINCT para considerar 
apenas valores distintos da expressão.
BIT_AND(expressao) Retorna o resultado da operação lógica AND em todos os bits de expressao.
BIT_OR(expressao) Retorna o resultado da operação lógica OR em todos os bits de expressao.
COUNT(expressao) Retorna o número de valores não-nulos nas linhas retornadas pelo comando 
SELECT.
COUNT(*) Retorna o número de valores nas linhas retornadas pelo comando SELECT 
(inclusive valores nulos).
COUNT(DISTINCT expressao [,...]) Retorna o número de valores não-nulos nas linhas retornadas pelo comando 
SELECT excluindo os valores duplicados.
MAX([DISTINCT] expressao) Retorna o valor máximo de expressao, para valores não-nulos nas linhas 
selecionadas.
MIN([DISTINCT] expressao) Retorna o valor mínimo de expressao, para valores não-nulos nas linhas 
selecionadas.
STD(expressao) Retorna o desvio-padrão de expressao, para valores não-nulos nas linhas 
selecionadas.
STDDEV(expressao) O mesmo que STD().
SUM([DISTINCT] expressao) Retorna a soma de expressao, para valores não-nulos nas linhas selecionadas. A 
opção DISTINCT, disponível desde o MySQL 5.0, pode ser usada para somar 
apenas os valores distintos retornados na seleção.
3.2 Funções de comparação
Função Descrição
GREATEST(expr1,expr2,...) Retorna o maior valor dentre os argumentos fornececidos. 
IF(expr1,expr2,expr3) Retorna expr2 se expr1 for True (não 0 ou NULL); caso contrário, retorna 
expr3. IF() retorna um valor numérico ou string, dependendo do contexto em 
que for utilizado.
IFNULL(expr1,expr2) Retorna expr2 se expr1 for igual a NULL; caso contrário, retorna expr1.
INTERVAL(n,n1,n2,...) Retorna 0 se n < n1, 1 se n < n2 e assim por diante, ou -1 se n for NULL. Os 
valores n1, n2, ... devem estar em ordem crescente porque é feita uma pesquisa 
binária.
ISNULL(expr) Retorna 1 (True) se a expr for NULL; caso contrário, retorna 0 (False). Observe 
que uma comparção de valores NULL usando o caractere “=” será sempre False.
LEAST(expr1,expr2) Retorna o menor valor dentre os argumentos fornecidos. 
STRCMP(str1,str2) Retorna 0 se os Strings forem iguais, -1 se o primeiro argumento for menor que 
o segundo de acordo com a ordem de classificação corrente; e 1 caso contrário.
4 – Java Database Conectivity – JDBC
 A API JDBC é uma API Java que permite acessar qualquer tipo de dado tabular, especialmente dados 
armazenados em bancos de dados relacionais.
JDBC ajuda você a escrever aplicações em Java que gerenciam estas três atividades de programação:
• Conectar a uma fonte de dados, tipo um banco de dados
• Enviar consultas e comandos de atualização para o banco de dados
• Recuperar e processar os resultados recebidos de um banco de dados em resposta à sua consulta.
O seguinte fragmento simples de código dá um exemplo destas três atividades.
public void connectToAndQueryDatabase(String username, String password) {
 Connection con = DriverManager.getConnection(
 "jdbc:myDriver:myDatabase",username,password);
 Statement stmt = con.createStatement();
 ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table1");
 while (rs.next()) {
 int x = rs.getInt("a");
 String s = rs.getString("b");
 float f = rs.getFloat("c");
 }
}
Este curto fragmento de código instancia um objeto da classe DriverManager para conectar um driver de banco 
de dados e logar em uma base de dados, instanciar um objeto de Statement que transporta suas consultas em SQL para a 
base de dados; instanciar um objeto de ResultSet que recupera o resultado de suas consultas, e executa um simples laço 
while, que recupera e mostra estes resultados. É simples assim.
4.1 JDBC – Componentes do Produto
4.1.1 A API JDBC 
A API JDBC provê acesso programático para dados relacionais através da linguagem de programação Java. 
Usando a API JDBC, aplicações podem executar declarações SQL, recuperar resultados, e propagar as mudanças de 
volta para uma fonte de dados subjacente. A API JDBC pode também interagir com múltiplas fontes de dados (data 
sources) em um ambiente distribuído e heterogêneo.
 A API JDBC é parte da plataforma Java, que inclui o Java Standard Edition (JSE) e o Java Enterprise Edition 
(JEE). A API JDBC 4.0 é dividida em dois pacotes: java.sql e javax.sql. Ambos pacotes são incluídos na plataforma 
JSE e JEE.
4.1.2 JDBC Driver Manager
A classe DriverManager do JDBC define os objetos que podem conectar aplicações Java a driver's JDBC. A 
classe DriverManager tem sido tradicionalmente o suporte principal da arquitetura JDBC. É muito pequeno e simples.
Os pacotes de padrão de extensão javax.naming and javax.sql deixa você usar um objeto de DataSource 
registrado com um serviço de nomes (Java Naming and Directory Interface - JNDI) para estabelecer uma conexão com 
a fonte de dados. Você pode usar o mecanismo de conexão, mas usar um objeto de DataSource é recomendado sempre 
que possível.
4.1.3 Conjunto de Teste da JDBC
O conjunto de teste do driver JDBC ajuda você a determinar o driver JDBC que executará o programa. Estes 
testes não são abrangentes ou exaustivos, mas eles exercitam algumas das características importantes da API JDBC.
4.1.4 Ponte JDBC-ODBC
O Java fornece acesso JDBC via drivers ODBC. É importante ressaltar que você precisa carregar o código 
binário do ODBC em cada máquina cliente que usa este driver. Como resultado, o driver ODBC é mais apropriado em 
redes corporativas onde instalações clientes não são um grande problema, ou para códigos de aplicações servidoras 
escritas em Java em uma arquitetura de três camadas.
Esta trilha utiliza os dois primeiros destes quatro componentes para conectar no banco de dados e então 
construir um programa Java que usa comandos SQL para comunicar com uma base de dados relacional de teste. Os dois 
últimos componentes são usados em ambientes especializados para testar aplicações web, ou para comunicar com 
sistemas de gerenciamento de banco de dados (Database Management System - DBMS) via ODBC.
4.2 Arquitetura JDBC
4.2.1 Modelos de Processamento Two-tier e Three-tier
A API JDBC suporta ambos os modelos de processamento, two-tier (duas camadas) e three-tier (três camadas) 
para acesso a bancos de dados.
 Figura 1: Arquitetura duas camadas para acesso a dados.
No modelo de duas camadas, um applet ou uma aplicação Java fala diretamente para o banco de dados. Isto 
requer um driver JDBC que pode comunicar com uma fonte de dados particular sendo acessada. Assim, comandos são 
entregues para o banco de dados, ou outras fontes de dados, e os resultados destes comandos são enviados de volta para 
a aplicação que os enviou. O banco de dados pode estar alocado em outra máquina a que o usuário estará conectado via 
rede. Isto é referenciado como uma configuração cliente/servidor, tendo as máquinas dos usuários como cliente, e a 
máquina hospedando a fonte de dados como o servidor. A rede pode ser uma intranet, que, por exemplo, conecta 
funcionários com uma empresa, ou pela própria internet.
No modelo três camadas (three-tier), os comandos são enviados para uma camada intermediária de serviços, 
que então envia estes comandos para a fonte de dados. A fonte de dados processa, retorna o resultado para a camada 
intermediária, que devolve paraa aplicação. 
Gestores de sistemas de informação geralmente acham o modelo de três camadas mais atrativo pelo fato da 
camada intermediária possibilitar manter o controle sobre o acesso e os tipos de atualizações que podem ser feitas nos 
dados corporativos. Outra vantagem é que isso simplifica a construção de aplicativos. Finalmente, em muitos casos, a 
arquitetura de três camadas provê vantagens em relação à performance.
 Figura 2: Arquitetura três camadas para acesso a dados.
Até recentemente, a camada intermediária vinha sendo frequentemente escrita em linguagens como C ou C++, 
que ofereciam maior performance em termos de velocidade de resposta. Contudo, com a introdução de otimização de 
compiladores que transformam o bytecode Java em código eficiente para máquinas específicas e tecnologias tais como 
Enterprise JavaBeans, a plataforma Java está se tornando a plataforma padrão para desenvolvimento de camadas 
intermediárias. Isto é um grande avanço, tornando possível aproveitar toda a robustez de Java, multthreading, e das 
características de segurança.
Cada vez mais empresas usando a linguagem de programação Java para escrever aplicações servidoras, a API 
JDBC vem sendo usada mais e mais em camadas intermediárias da arquitetura de três camadas. Algumas das 
funcionalidades que fazem do JDBC uma tecnologia de servidor, são suporte a pool de conexões, transações 
distribuídas, e o uso de rowsets desconectados. A API JDBC é também o que permite o acesso a uma fonte de dados a 
partir de uma camada intermediária Java.
4.3 Tipos de Drivers JDBC
Há quatro tipos de driver JDBC que são:
• Driver Ponte JDBC-ODBC: Implementação nativa que conecta através de ODBC.
• Driver API-Nativa Parcialmente Java: Usa interfaces Java funcionando sobre ODBC.
• Driver Java c/ Net Protocol: Usa de um middleware p/ conectar-se ao banco.
• Driver Java Puro: Totalmente implementado em Java. Conhece todo o protocolo de comunicação com 
o BD e pode acessar diretamente o banco. É o mais recomendado.
4.4 A arquitetura de classes do JDBC
O JDBC possui um conjunto de interfaces que são implementadas por cada SGBD que desejar fornecer acesso 
a seu produto através de aplicativos Java.
A figura abaixo trás o pacote java.sql e o papel de cada interface.
Interface Descrição
DriverManager Responsável por gerenciar o driver e criar conexões com o banco
Connection Interface que representa a conexão com o bando de dados. 
Statement Controla e executa uma instrução SQL
PreparedStatement Controla e executa uma instrução SQL. O PreparedStatement é capaz de pré-compilar aquela 
query, antes de enviá-la ao banco. Isso quer dizer que, se você executar a query várias vezes 
seguidas, apenas alterando o valor dos parâmetros, a execução tende a ser mais rápida do que 
com um Statement.
CallableStatement Interface usada para chamar stored procedures
ResultSet Contém o conjunto de dados retornado por uma consulta SQL.
4.5.1 Executando comandos através da JDBC
Antes de executar qualquer comando usando a API JDBC, precisamos estabelecer uma conexão, que consiste 
basicamente em dois passos, (1) carregar o driver, e (2) criar a conexão com o SGBD. Assim, vejamos o exemplo 
abaixo:
Na linha 15, a String passada deve conter o nome completo da classe que implementa o Driver. Lembrando que 
cada driver possui um nome diferente. Em seguida, na linha 16, o objeto Connection retornado representa a conexão 
com o banco de dados. Na url é informada o IP, ou o nome do servidor, porta e nome da base de dados, mas isso varia 
de fabricante e a documentação do driver JDBC que você está usando deve ser consultada para maiores detalhes. Na 
linha 17 é declarado nossa instancia de Statement que é dada pela instancia de Connection. Na linha 23 é executada a 
instrução para criar nova tabela através do método executeUpdate(). Este método deve ser usado para executar 
comandos INSERT, DELETE e UPDATE, além dos comandos da DDL, e retorna um inteiro com o número de linhas 
afetadas pelas operações de DML, e retorna sempre 0 para comandos da DDL. Para executar uma consulta (SELECT), 
use o método executeQuery() que retornará uma instancia de ResultSet que permitirá obter os dados de acordo com a 
consulta. Mais abaixo, na linha 27, fazemos uma inserção no banco, concatenando nome e data de nascimento. E por 
último, na linha 29, fechamos através do método close() a conexão com o SGBD.
4.5.2 Usando o PreparedStatement
Assim como no exemplo anterior, carregamos o driver e conectamos no SGBD nas linhas 20 e 21. No entanto, 
agora temos uma diferença na forma de escrever as instruções que nos permite passar parâmetros usando o carácter ? 
(interrogação). Esta diferença não é apenas visual, mas o PreparedStatement tem a vantagem de pré-compilar a 
instrução SQL, e no caso de executá-la várias vezes, esta opção é mais rápida que o Statement, além de mais segura, 
pois não está suscetível ao ataque de Injeção de SQL (SQL Injection). Na linha 23 obtemos uma instancia do 
PreparedStatement através do método prepareStatement(sql) onde devemos informar a instrução SQL a ser executada 
por esta instancia. Logo em seguida, nas linhas 24, 25 e 26, informamos os parâmetros. Observe que na linha 24 
estamos passando null para o primeiro parâmetro por se tratar da primary key, assim, o SGBD irá inserir seu valor 
automaticamente. Na sequencia, o comando da linha 27 (pst.executeUpdate()) executa a inserção. 
Mais abaixo, temos um exemplo de uso do ResultSet para obter dados, observe que agora vamos montar uma 
consulta que espera receber um parâmetro. Tanto neste exemplo, como no exemplo anterior, não foi necessário 
concatenar valores para montar as instruções SQL, e nem usar as aspas simples para tratar String's. Na linha 31 setamos 
o parâmetro para executar o filtro por todas as pessoas cujo nome começa com a letra A, por isso, a única coisa que 
informamos foi o carácter especial %. Na linha 33 usamos o método next() de ResultSet para verificar se há um novo 
registro. Neste momento, a implementação posiciona-se na próxima linha retornada pelo SGBD. Caso não haja mais 
registros para serem lidos, é retornado false, e o laço termina. Dentro do while, usamos os métodos no padrão: 
• get<TipoDoDado>(“String com nome do campo ou seu alias”);
• get<TipoDoDado>(<posicao da coluna no registro retornado>);
No primeiro formato, passamos o nome da coluna ou o alias usado no SELECT que foi usado para criar o 
PreparedStatement que estamos usando, no segundo formato, indicamos a posição da colunas que queremos receber de 
volta. OBSERVE QUE ESTE ÍNDICE COMEÇA NO 1 (UM), e não no 0 (zero) como o caso de alguns índices Java.
Abaixo segue uma lista dos métodos disponíveis para obter seus respectivos tipos de dados.
4.5.3 Controle de Transações
Para abrir uma transação via JDBC basta configurar o autoCommit para false. A partir deste momento, tudo 
que for enviado ao SGBD estará pendente de confirmação através da execução do método commit() da interface 
Connection, ou passível de ser cancelado através do método rollback() da mesma interface. Veja o exemplo abaixo:
Observe que na linha 21 passamos o autoCommit para false, o que fará com que o SGBD não persista as 
alterações feitas em tabelas da base de dados selecionada, esperando assim, uma instrução para confirmar (commit), ou 
para cancelar (rollback) estas alterações que podem ser tanto nos dados das tabelas quanto nas estruturas das mesmas.
Neste exemplo, na linha 30, executamos o método commit(), no entanto, se desejássemos cancelar, bastaria 
executar conn.rollback(); e estaria desfeito o INSERT executado na linha 28. Logo em seguida (linhas 32 e 33), apenas 
fechamos os recursos abertos anteriormente.
4.5.4 Tratamento de Exceções
O tratamento de exceções é possível através do uso da classe SQLException que possui os seguintes métodos:
• getMessage() - retornaa mensagem de erro enviada pelo SGBD.
• getSQLState() - retorna um dos códigos de estado do padrão ANSI-92 SQL.
• getErrorCode() - retorna o código de erro específico do fornecedor.
• getNextException() - retorna a exceção aninhada (encadeada), se houver.
try {
//simula um erro de SQL mal formado
String sql = "INSERT PESSOA (ID,NOME) VALUES (?,?)";
PreparedStatement ps = conn.prepareStatement( sql );
ps.executeUpdate();
} catch( SQLException ex ) {
System.out.println("\n--- SQLException ---\n");
while( ex != null ) {
System.out.println("Mensagem: " + ex.getMessage());
System.out.println("SQLState: " + ex.getSQLState());
System.out.println("ErrorCode: " + ex.getErrorCode());
ex = ex.getNextException();
System.out.println("");
}
}
No exemplo acima, tentamos inserir um registro na tabela pessoa, mas não informamos os valores esperados 
como parâmetros. Assim, ao executar o método executeUpdate() será lançada uma exceção SQLException, que será 
tratada imprimindo a mensagem de erro, bem como os códigos de erros retornados.
4.6 Desenvolvendo nossa primeira aplicação
Agora que vimos os principais recursos do JDBC, está na hora de juntar tudo e colocar o aprendizado em 
prática. Mas antes uma pergunta: É correto colocar código SQL misturado com regras de negócio da aplicação dentro da 
interface gráfica com o usuário (GUI – Graphic User Interface)? Pois lhes garanto que não, não é. Isso trás como 
desvantagens além da desorganização, a baixa coesão das suas classes, o alto acoplamento, a impossibilidade de 
reaproveitamento de código, a má qualidade do seu código, que também acarreta a baixa manutenibilidade do mesmo. 
Bom, com todas estas desvantagens, a orientação a objetos (O.O) foi evoluindo, e os chamados design patterns 
(Padrões de Projeto) foram sendo criados com o objetivo de fornecer soluções padronizadas para problemas recorrentes 
de programação O.O. Assim, existe design pattern para diversas finalidades, e um dos mais conhecidos se refere ao 
manuseio de operações com SGBD's o DAO (Data Access Object).
4.6.1 Padrão de Projeto DAO 
O propósito é retirar todo o código referente a acesso ao banco de dados de suas classes de lógica e GUI, e 
colocá-lo em uma classe que seja responsável apenas pelo acesso aos dados. Assim, teremos uma classe de propósito 
bem definido, coesa, com menor volume de código, o que a tornará mais fácil de manter mesmo por outros 
programadores.
Então, seria muito bom se pudéssemos fazer assim:
MeuDAO dao = new MeuDAO();
dao.adiciona(pessoa)
Bem mais elegante e fácil de ler, quem executa este código, não precisa se preocupar por exemplo, com 
detalhes de acesso ao banco, nem com usuário, senha, se a aplicação já está conectada no SGBD, etc... 
Então vamos chegar neste código. Mas para isso, precisamos de uma classe no estilo Javabeans que retrate 
nossa tabela no SGBD. Para quem não se lembra, Javabeans são classes que possuem o construtor sem argumentos e 
métodos de acesso do tipo get e set. Simples assim! Então segue abaixo o Javabean da tabela Pessoa.
public class Pessoa {
 private Integer id;
 private String nome;
 private String cpf;
 
 public Pessoa(){ 
 }
 /*
 * GETTERS & SETTERS
 */ 
}
E então, nossa classe DAO, ou pessoaDAO com todos os métodos que precisamos para este exemplo, 
adicionando, removendo, alterando, e consultando uma pessoa. Caso fosse necessário mais alguma operação com o 
SGBD relativa à pessoa, esta operação se tornaria um método dentro desta classe.
public class PessoaDAO {
 private Connection connection; 
 public PessoaDAO(){
 this.connection = new ConnectionFactory().getConnection();
 }
 
 public void adiciona(Pessoa pessoa){
 String sql = "insert into pessoa (nome, cpf) values (?,?)"; 
 try{
 // prepared statement para inserção
 PreparedStatement pst = connection.prepareStatement(sql); 
 //seta os valores
 pst.setString(1,pessoa.getNome());
 pst.setString(2, pessoa.getCpf()); 
 pst.executeUpdate();
 pst.close();
 }
 catch (SQLException ex) {
 throw new RuntimeException(ex);
 } 
 }
 
 public void atualiza(Pessoa pessoa){
 String sql = "update pessoa set nome = ?, cpf = ? where id = ?"; 
 try{
 PreparedStatement pst = connection.prepareStatement(sql); 
 //seta os valores
 pst.setString(1,pessoa.getNome());
 pst.setString(2, pessoa.getCpf());
 pst.setInt(3, pessoa.getId());
 
 pst.executeUpdate();
 pst.close();
 }
 catch (SQLException ex) {
 throw new RuntimeException(ex);
 } 
 }
 
 public void remove(Pessoa pessoa){ 
 String sql = "delete from pessoa where id = ?";
 try{
 PreparedStatement pst = connection.prepareStatement(sql); 
 //seta os valores
 pst.setInt(1,pessoa.getId()); 
 pst.executeUpdate();
 pst.close();
 }
 catch (SQLException ex) {
 throw new RuntimeException(ex);
 }
 }
 
 public Pessoa pesquisa(Pessoa pessoa) {
 String sql = "select * from pessoa where id = ?";
 try {
 PreparedStatement pst = connection.prepareStatement(sql);
 //seta os valores
 pst.setInt(1, pessoa.getId());
 ResultSet rs = pst.executeQuery();
 if (rs.next()) {
 pessoa.setNome(rs.getString("nome"));
 pessoa.setCpf(rs.getString("cpf"));
 } else {
 pessoa = null;
 }
 rs.close();
 pst.close();
 return pessoa;
 } catch (SQLException ex) {
 throw new RuntimeException(ex);
 }
 }
}
Observe que em todos os métodos, usamos o PreparedStatement, pois como já foi falado, é o mais 
recomendável por uma série de razões. Mas está faltando um detalhe, de onde tiramos a conexão com o banco? Para 
este propósito, usamos outro padrão de projeto (design pattern) chamado Factory (fábrica). O objetivo do factory que 
criaremos a seguir é fornecer acessos ao banco de dados, não ficando assim, sob responsabilidade do DAO conectar-se 
ao banco quando precisar executar suas operações, este será o papel da nossa Factory, ou ConnectionFactory.
public class ConnectionFactory {
 private static Connection connection;
 
 public Connection getConnection(){
 try{
 Class.forName("com.mysql.jdbc.Driver");
 if(ConnectionFactory.connection == null) {
 connection = DriverManager.getConnection("jdbc:mysql://localhost/aula14", "root", "1234");
 } 
 return ConnectionFactory.connection;
 
 } catch (ClassNotFoundException ex) {
 throw new RuntimeException(ex);
 }catch(SQLException ex){
 throw new RuntimeException(ex);
 }
 }
}
Assim, sempre que uma classe DAO precisar de uma conexão com o SGBD, pedirá à nossa factory acima. 
Observe que ela cria apenas uma conexão e o devolve para qualquer classe que invocar o método getConnection().
Agora que criamos nosso Javabean, DAO, e a fábrica de conexões, veremos como ficou a GUI que executará a 
aplicação.
Vejamos o código do botão Remover:
 try{ //instanciamos o Javabean e atribuimos o id informado na tela para o atributo id 
 Pessoa pessoa = new Pessoa(); 
 pessoa.setId(Integer.parseInt(jTFCodigo.getText().trim()));
 pessoaDAO.remove(pessoa); //usando uma instancia de PessoaDAO já declarada, 
 //executamos o método 'remove' 
 habilitarCampos(false);
 limparCampos();JOptionPane.showMessageDialog(this, "Concluído com sucesso!", "Sucesso", 
JOptionPane.INFORMATION_MESSAGE);
 }catch(RuntimeException ex){
 JOptionPane.showMessageDialog(this, "Erro ao remover.\n"+ex.getMessage(), "Erro...", 
JOptionPane.ERROR_MESSAGE);
 }
Como podem perceber, ficou bem simples e limpo o tratamento dos dados na GUI. Vejamos agora o botão 
Gravar:
 try {//instancia o javabean e alimenta seus atributos com dados da GUI
 Pessoa pessoa = new Pessoa();
 pessoa.setId(Integer.parseInt(jTFCodigo.getText().trim()));
 pessoa.setNome(jTFNome.getText());
 pessoa.setCpf(jTFCpf.getText()); 
 if (novo) {//ao clicar no botao adicionar, o flag 'novo' recebe true, indicando que operação 
 pessoaDAO.adiciona(pessoa); //executar neste momento, uma adição, ou uma alteração
 } else {
 pessoaDAO.atualiza(pessoa);
 }
 habilitarCampos(false);
 limparCampos();
 JOptionPane.showMessageDialog(this, "Concluído com sucesso!", "Sucesso", 
JOptionPane.INFORMATION_MESSAGE);
 }catch (RuntimeException ex) {
 JOptionPane.showMessageDialog(this, "Erro ao gravar.\n" + ex.getMessage(), "Erro...", 
JOptionPane.ERROR_MESSAGE);
 }
E finalmente, o botão pesquisar:
 novo = false;//seta o flag indicando que ao gravar deve ser executado uma alteração
 try {
 Pessoa pessoa = new Pessoa();//instancia o javabean, e seta seu Id
 pessoa.setId(Integer.parseInt(jTFCodigo.getText().trim()));
 pessoa = pessoaDAO.pesquisa(pessoa);//executa a busca procurando pelo id informado
 if(pessoa == null){//se retornou null, é porque não encontrou nenhum registro com o Id dado.
 JOptionPane.showMessageDialog(this, "Pessoa não encontrada.", "erro...", 
JOptionPane.ERROR_MESSAGE);
 }else{
 carregar(pessoa);//apenas pega os dados do Javabean, e joga nos componentes da GUI
 }
 } catch (RuntimeException ex) {
 JOptionPane.showMessageDialog(this, "Erro ao gravar.\n" + ex.getMessage(), "Erro...", 
JOptionPane.ERROR_MESSAGE);
 }
Como pode ser observado, com o uso do padrão DAO, e da O.O, nosso aplicativo ficou simples e organizado, 
todas as classes coesas, e com um baixo acoplamento, haja vista, que a GUI, não depende do JDBC, se futuramente 
migrarmos para o Hibernate, será necessário apenas alterar nossa Factory, e nosso DAO. Ou se optarmos pelo contrário, 
migrarmos nosso aplicativo para uma WebApp, basta migrar a GUI, e poderemos reaproveitar o DAO, a factory e 
também nosso Javabean. Este é um dos grandes benefícios da O.O.
5 Hibernate
O Hibernate é um framework de mapeamento objeto-relacional que surgiu para ser uma ponte entre a 
orientação a objetos e a persistência de dados em bancos de dados relacionais, assim, tudo o que o desenvolvedor 
precisa fazer é descrever suas classes com alguns metadados para poder se focar no desenvolvimento da aplicação.
O que é Mapeamento Objeto-relacional?
 Mapeamento objeto-relacional (MOR ou ORM do inglês Object-Relational Mapping) é uma técnica utilizada para 
diminuir o tempo que um desenvolvedor leva para persistir objetos em bancos de dados relacionais. As tabelas do 
banco de dados são representadas através de classes e os registros das tabelas são objetos (instancias de classes).
 Utilizando essa técnica o desenvolvedor não precisa se preocupar tanto com os comandos SQL para as operações 
CRUD (Create, Read, Update and Delete), pois a própria ferramenta que implementa essa técnica deverá se preocupar 
com tais comandos. 
 Para aplicar a técnica de MOR, os atributos da classe devem representar colunas na tabela do banco de dados, 
porém as tabelas e classes não precisam ser idênticas, pode existir um atributo na classe que não esteja diretamente 
relacionado com a tabela do banco de dados. Exemplo: em uma tabela de aluguel de carros pode existir a data do 
aluguel e a data da devolução. A classe que representará a tabela pode ter o atributo dias que indica a quantidade de 
dias que o carro ficou alugado. Este atributo não tem qualquer relação com uma coluna do banco de dados e não há 
problema algum em sua existência. A relação entre as tabelas e ass classes é definida pelo próprio desenvolvedor. Tal 
processo é mais conhecido como “mapeamento”.
 A maneira como o desenvolvedor mapeia a relação entre tabelas e classes varia de acordo com o framework utilizado 
(cada um tem suas particularidades). O Hibernate, por exemplo, propicia duas formas: descrever os metadados 
necessários em um XML ou então descrever os metadados na própria classe utilizando anotações.
Fonte: Java Magazine Ano VII Edição 90 Artigo: “Hibernate Annotations: Mapeamento Objeto-Relacional através de Annotations”
5.1 Hibernate e JPA
Segundo SAAB (2011), algum tempo depois do Hibernate fazer sucesso entre os desenvolvedores, a Sun 
reconheceu que o mapeamento objeto-relacional era algo necessário no desenvolvimento de aplicações e criou a 
especificação JPA (Java Persistence API) baseando-se nas funcionalidades que o Hibernate já havia implementado.
Como a Sun tinha maior alcance e influência sobre os desenvolvedores do que os criadores do Hibernate, foi 
natural que a JPA ficasse conhecida rapidamente forçando que o Hibernate se adequasse a este novo padrão.
Esta é uma situação que gera grandes confusões e dúvidas nos desenvolvedores: apesar do Hibernate ter 
surgido antes da JPA e ter sido utilizado como referência para a sua especificação, ele também a implementa, ou seja, 
pode ser utilizado como um framework independente ou como uma implementação da JPA.
Para empregar o Hibernate como implementação da JPA deve-se utilizar as anotações e classes que se 
encontram no pacote javax.persistence.*.
5.2 Anotações
 
A JPA possui várias anotações para o mapeamento de classes em tabelas. A seguir veremos as anotações mais 
comuns e um pequeno comentário sobre cada uma delas:
– @Entity – toda classe que represente uma tabela no banco de dados deve ser anotada com essa anotação;
– @Table(name) – anotação responsável por dizer qual tabela no banco de dados a classe irá representar. O 
atributo name deve é do tipo String, e deve conter o nome da tabela que a classe representa.
– @Column(name,nullable,length) – cada atributo da classe que represente uma coluna da tabela no banco 
de dados deve ser anotado com essa anotação. Caso esta anotação não esteja presente, o Hibernate irá 
interpretar que há uma coluna na tabela que esta classe representa com o mesmo nome do atributo da 
classe. 
– Name – nome da coluna do tipo String;
– nullable – valor booleano que indica se esta coluna pode ser nula;
– Length – Tamanho máximo do atributo. Tipo Integer.
– @Enumerated(EnumType) – utilizada para atributos que serão representados por enumeradores (ex: 
Sexo.M e Sexo.F). O atributo EnumType indica a forma como a enumeração será persistida no banco:
– EnumType.STRING – o valor textual da opção será armazenado no banco (Caso a opção escolhida 
seja Sexo.M será armazenada a String “M”);
– EnumType.ORDINAL – o número que representa a posição da opção será armazenado no banco. 
(Caso a opção escolhida seja Sexo.M será armazenada o Integer 0, se Sexo.F será 1)
– @Temporal(TemporalType) – utilizada para atributos que representam data.
– TemporalType.DATE – armazena somente a data (dia, mês e ano) do atributo no banco;
– TemporalType.TIME – armazena somente o horário (hora, minuto, segundo) do atributo no banco;
– TemporalType.TIMESTAMP – armazena data e horário do atributo no banco.
– @Id – informa qual atributo é a chave primária da tabela. Só um atributo da classe pode estar anotado com 
essa anotação.
– @SequenceGenerator(name,sequenceName) – pode anotar tanto um atributo quantoa classe. É utilizado 
para mapear um gerador de sequência do banco. Seus atributos:
– name – nome que as outras anotações deverão utilizar para referenciar o gerador;
– sequenceName – nome do gerador no banco de dados. (O PostgreSql é um exemplo de SGBD que 
utiliza esta anotação).
– @GeneratedValue(strategy,generator) – utilizada para anotar atributos cujo valor seja gerado por um 
gerador de sequência (id, por exemplo). 
– Strategy – uma opção do enumerador GenerationType (GenerationType.TABLE ou 
GenerationType.IDENTITY ou GenerationType.SEQUENCE ou GenerationType.AUTO) que 
informa qual algoritmo será utilizado para gerar o próximo número da sequência. Como varia muito 
de SGBD para SGBD é uma boa prática utilizar GenerationType.AUTO;
– Generator – nome do gerador (anteriormente especificado pela anotação @SequenceGenerator).
– @OneToMany(fetch, mappedBy) – utilizada para relacionamentos 1:N (um para muitos). Anota uma lista 
de objetos que referenciam a classe atual. Ex: Venda tem uma lista de ItemVenda. Tal lista deve ser 
anotada com @OneToMany. Seus atributos são:
– fetch – informa o modo de carregar os objetos dessa lista. Se a opção selecionada for 
FetchType.EAGER, todos os objetos da lista são carregados no momento em que o objeto pai é 
carregado. Se a opção selecionada for FetchType.LAZY, a lista não vai ser carregada junto com o 
objeto pai. Ela será carregada do banco de dados na sua primeira utilização. (ex: na primeira vez que o 
método getItemVendaList() for chamado);
– mappedBy – nome do atributo na classe filha que representa a classe pai. (Ex: na classe ItemVenda 
tem um atributo da classe Venda, chamado vd, então, o mappedBy receberia “vd”).
– @ManyToOne(fetch) – também utilizada para relacionamentos 1:N. Anota o atributo que representa a 
classe pai. O parâmetro fetch é igual ao descrito acima;
– @JoinColumn(name, referencedColumnName, nullable) – utilizado em atributos anotados com 
@ManyToOne. Descreve quais colunas serão utilizadas para fazer um JOIN entre as tabelas do 
relacionamento. 
– name – nome da coluna da tabela atual que será utilizada no JOIN;
– referencedColumnName – nome da coluna da outra tabela que será utilizada no JOIN. Apenas o nome 
da coluna deve ser informado. Mesmo que outras tabelas tenham colunas com o mesmo nome o 
Hibernate irá saber com qual tabela fazer o JOIN, pois o atributo anotado com essa anotação está 
sendo referenciado através do atributo mappedBy da anotação @OneToMany no seu pai;
– nullable – mesmo comportamento deste atributo na anotação @Column.
– @ManyToMany – utilizada para mapear relacionamentos N:N. Assim como a anotação @OneToMany 
anota uma lista, com a diferença de que um relacionamento N:N não tem entidades filhas, cada entidade 
do relacionamento possui uma lista da outra entidade;
– @JoinTable(name, joinColumns, inverseJoinColumns) – utilizada para anotar uma lista que já esteja 
anotada com @ManyToMany. Especifica qual tabela será utilizada para recuperar os dados do 
relacionamento N:N. 
– name – nome da tabela que representa o relacionamento;
– joinColumns – recebe um vetor de @JoinColumns(name) que representa as colunas da classe atual 
que serão utilizadas no JOIN;
– inverseJoinColumns – recebe um vetor de @JoinColumn(name) que representa as colunas da outra 
classe do relacionamento que serão utilizadas no JOIN.
5.3 Mapeando classes
Considere a tabela no banco de dados como especificado abaixo:
create table produto(
id bigint not null auto_increment primary key,
desc_pro varchar(100) not null,
dt_validade date,
preco double,
garantia_maxima int,
ativo boolean
)engine=InnoDB;
Nem todas as anotações são obrigatórias, e nem todos seus atributos também o são, assim, há um valor padrão 
para cada atributo omitido, bem como, um comportamento padrão para cada situação em que não for informado a 
anotação. Para mais detalhes sobre estes valores padrões, consulte a documentação da respectiva anotação.
Vejamos como fica o mapeamento da tabela produto, para a classe Produto abaixo:
@Entity //OBRIGATÓRIO PARA INDICAR QUE ESTA É UMA ENTIDADE QUE REPRESENTA UMA TABELA
@Table(name="produto") //nome da tabela no SGBD. Necessário apenas se o nome for diferente do nome da classe
public class Produto {
@Id //indica que este atributo é chave primária
@GeneratedValue(strategy= GenerationType.AUTO) //indica como deve ser incrementado o id
@Column(name="id",nullable=false) // usado quando o nome do atributo na classe é diferente na tabela, e 
//quando os atributos da anotação não devam seguir o valor padrão. Caso do nullable que é true por padrão. 
private Long codigo;
@Column(name="desc_pro", length=100)//aqui é indicado o tamanho de 100 caracteres para a String
private String descricao;
@Column(name="dt_validade")
@Temporal(TemporalType.DATE) //indicando que deve armazenar no banco apenas a hora
 private Date dataValidade; 
//não precisa de anotação porque seguirá os padrões de valor e comportamento de um @Column
 private Double preco; 
 @Column(name="garantia_maxima") //nome diferente no SGBD
 private Integer garantiaEmAnos; 
 @Column(name="ativo")
 private Boolean ativo; 
 @Transient //esta anotação indica que este atributo existe apenas na classe, e nunca na tabela do SGBD
 private Boolean esgotado;
}
Vamos enriquecer nosso modelo e acrescentar as tabelas como definido abaixo:
create table cidade(
id bigint not null auto_increment primary key,
nome varchar(50) not null,
estado varchar(2)
)engine=InnoDB;
create table cliente(
id bigint not null auto_increment primary key,
nome varchar(50) not null,
dt_nascimento date,
telefone bigint,
email varchar(100),
data_hora_ultimo_acesso timestamp,
limite_credito float,
bloqueado boolean,
sexo varchar(1),
cidade_id bigint, 
foreign key (cidade_id) references cidade(id)
)engine=InnoDB;
create table cliente_produto(
cliente_id bigint not null, 
produto_id bigint not null,
foreign key (cliente_id) references cliente (id), 
foreign key (produto_id) references produto(id) 
)engine=InnoDB;
Vejamos como ficaram suas respectivas classes mapeadas:
@Entity // Neste caso, nenhuma novidade em relação à classe produto.
@Table(name="cidade")
public class Cidade {
 @Id @GeneratedValue(strategy= GenerationType.AUTO)
 @Column(name="id",nullable=false)
 private Long codigo;
 
 @Column(name="nome",length=50,nullable=false)
 private String nome;
 
 @Column(name="estado",length=2)
 private String estado;
}
@Entity
@Table(name="cliente")
public class Cliente {
 @Id @GeneratedValue(strategy= GenerationType.AUTO)
 @Column(name="id",nullable=false)
 private Long codigo;
 
 @Column(name="nome",length=50)
 private String nome;
 
 private Long telefone;
 
 @Column(name="email",length=100)
 private String email;
 
 @Column(name="dt_nascimento")
 @Temporal(TemporalType.DATE)
 private Date dataNascimento;
 
 @Column(name="data_hora_ultimo_acesso")
 @Temporal(TemporalType.TIMESTAMP) //Observe que agora armazenaremos a data e a hora
 private Date ultimoAcesso;
 
 @Column(name="limite_credito")
 private Float limiteCredito;
 
 private Boolean bloqueado;
 //De acordo com a anotação, há um atributo chamado cidade_id na tabela cliente no SGBD que faz 
 //referência ao atributo id da tabela cidade 
 @JoinColumn(name="cidade_id",referencedColumnName="id")
 @ManyToOne(fetch= FetchType.LAZY) //usando o LAZY, os valores do atributo cidade não 
 private Cidade cidade; //serão carregados ao carregar os outros atributos desta classe
 
 @Enumerated(EnumType.STRING) //EnumType.STRING indica que será gravado o valor textual 
 @Column(name="sexo") //da enumeração no SGBD. Neste caso, a string 'M' ou 'F'.
 private Sexo sexo;
 
 @JoinTable(name="cliente_produto", //mapeando a tabela N:N.
//Abaixo

Outros materiais