Buscar

POO3_ebook

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 153 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 153 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 153 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

PROGRAMAÇÃO 
ORIENTADA A OBJETOS III
PROGRAMAÇÃO 
ORIENTADA A OBJETOS III
Copyright © UVA 2020
Nenhuma parte desta publicação pode ser reproduzida por qualquer 
meio sem a prévia autorização desta instituição.
Texto de acordo com as normas do Novo Acordo Ortográfico 
da Língua Portuguesa.
AUTORIA DO CONTEÚDO
Carlos Frederico Motta Vasconcelos
REVISÃO
Janaina Vieira
Theo Cavalcanti
PROJETO GRÁFICO
UVA
DIAGRAMAÇÃO
UVA
V331 Vasconcelos, Carlos Frederico Motta.
 Programação orientada a objetos III [recurso eletrônico] / Carlos Frederico 
 Motta Vasconcelos. – Rio de Janeiro: UVA, 2021. 
 
 1 recurso digital (6474 KB)
 Formato: PDF
 ISBN 978-65-5700-091-5
 
 1. Programação orientada a objetos (Computação). 2. Banco de dados 
 relacionais. 3. Java (Linguagem de programação de computador). I. Universidade 
 Veiga de Almeida. II. Título. 
 
 
 CDD – 005.11
Bibliotecária Adriana R. C. de Sá CRB 7 – 4049.
Ficha Catalográfica elaborada pelo Sistema de Bibliotecas da UVA.
SUMÁRIO
Apresentação
Autor
6
7
Acesso a bancos de dados relacionais via JDBC 
utilizando diferentes padrões de projeto 
37
• Acesso remoto a gerenciadores de bancos de dados relacionais com 
uso do JDBC 
• Técnicas de acesso concorrente a bancos de dados cliente-servidor
• Tratamento de erros em bancos de dados
UNIDADE 2
8
• Padrões de arquitetura para desenvolvimento de sistemas Orientados 
a Objetos – OO
• Padrões de projeto de sistemas OO: Modelo-Visão-Controle – MVC, 
DAO, Factory e Singleton
• Acesso e conexão a gerenciadores de banco de dados com uso do JDBC
Padrões de arquitetura e padrões de projetos Orientados 
a Objetos para desenvolvimento de sistemas Java
UNIDADE 1
SUMÁRIO
JavaServer Faces 120
• Visão geral do JavaServer Faces – JSF
• Managed Beans, requisições e navegação
• Componentes básicos, validação de campos, PrimeFaces e Ajax JSF
UNIDADE 4
81
• Ferramentas de mapeamento objeto-relacional – MOR (JPA e Hibernate)
• Pool de Conexões, Lazy Load e Relacionamentos
• Gerenciador de Estados, Caching e consultas JPQL
Persistência de dados via JPA e Hibernate 
(MOR automático)
UNIDADE 3
6
Nesta disciplina, serão abordadas técnicas para o desenvolvimento de sistemas compu-
tacionais Web usando a linguagem de programação Java e para realizar conexão com 
gerenciadores de banco de dados relacionais via Java DataBase Connectivity – JDBC. 
Além da biblioteca JBDC para armazenamento (persistência) em bancos de dados re-
lacionais, nesta disciplina serão apresentadas ferramentas do tipo object relational ma-
pping – ORM, que facilitam o uso do JDBC para acesso a bancos de dados relacionais. 
Além disso, serão abordadas ferramentas (frameworks) para facilitar o desenvolvimento 
e a manutenção de aplicações Web.
Para auxiliar o desenvolvimento de sistemas com maior complexidade, também será ne-
cessário conhecer alguns padrões de projeto de Orientação a Objeto específicos. Serão 
apresentados padrões de projeto que possuem caraterísticas próprias que podem faci-
litar a implementação e a manutenção de sistemas de informação, tais como: padrões 
de projeto de arquitetura em multicamadas, Model-View-Controller – MVC, Data Access 
Objects – DAO, Construtor Virtual – Factory Method, e Singleton.
Por fim, apresentaremos ferramentas de desenvolvimento de sistemas computacionais 
orientados a objetos com persistência de dados via Hibernate (ORM Automático) e tam-
bém será abordada a utilização do framework JavaServer Faces – JSF para adicionar 
comportamento dinâmico às páginas das aplicações Web.
Atualmente o mercado apresenta inúmeras oportunidades aos profissionais de Tecnolo-
gia da Informação que possuem conhecimentos sobre o desenvolvimento de sistemas 
Web com a utilização da tecnologia Java e seus respectivos componentes. Por sua vez, o 
Java possui inúmeras vantagens, como maior liberdade de desenvolvimento de sistemas 
de forma independente de fabricantes de softwares, sistemas operacionais, banco de 
dados, servidores de aplicação e containers.
APRESENTAÇÃO
7
CARLOS FREDERICO MOTTA VASCONCELOS
Possui graduação em Engenharia Eletrônica pela Universidade Federal do Rio de Janei-
ro – UFRJ e mestrado em Engenharia Biomédica pelo Instituto Alberto Luiz Coimbra de 
Pós-Graduação e Pesquisa de Engenharia – COPPE/UFRJ na área de Processamento de 
Sinais. Possui MBA em Sistemas de Telecomunicações pelo IBMEC-RJ. 
Experiência de 17 anos como professor do curso de Ciência da Computação na Univer-
sidade Veiga de Almeida – UVA nas áreas de Computação Gráfica, Processamento de 
Sinais e Imagens, Interfaces Homem-Máquina, Multimídia e Programação de Disposi-
tivos Móveis.
Possui experiência de 18 anos no planejamento e otimização de sistemas usados em 
redes celulares de telecomunicações com tecnologias LTE, UMTS, GSM e CDMA. Expe-
riência no desenvolvimento de sistemas de geoprocessamento (GIS) e de simulação de 
sinais de radiofrequência.
Atualmente trabalha como analista em Ciência e Tecnologia na área de Engenharia Clíni-
ca do Instituto Nacional do Câncer, do Ministério da Saúde, exercendo atividades técnicas 
especializadas na área de gerenciamento do parque de equipamentos médico-hospita-
lares de média e alta complexidades, além da fiscalização dos contratos de manutenção 
dos equipamentos e sistemas de informação. Experiência em elaboração de especifica-
ções e documentação técnicas necessárias aos processos de aquisição, recebimento e 
aceitação de novos equipamentos e sistemas de informação.
AUTOR
Padrões de arquitetura e
padrões de projetos Orientados
a Objetos para desenvolvimento
de sistemas Java
UNIDADE 1
9
Para o desenvolvimento de sistemas computacionais de maior complexidade torna-se 
necessário conhecer e aplicar padrões de projeto específicos para auxiliar as etapas ini-
ciais de especificação, análise e design de tais sistemas, com o objetivo de organizar as 
etapas seguintes de implementação do código. Nesta unidade serão abordados alguns 
exemplos de padrões de projeto e de arquitetura bastante utilizados no desenvolvimento 
de sistemas Orientados a Objetos – OO envolvendo armazenamento em banco de dados 
e aplicações Web.
INTRODUÇÃO
Nesta unidade você será capaz de:
• Compreender diferentes padrões de arquitetura e projeto (MVC, DAO, Factory e 
Singleton) para desenvolvimento de sistemas OO com acesso a bancos de dados 
e aplicações Web.
OBJETIVO
10
Padrões de arquitetura para desenvolvimen-
to de sistemas Orientados a Objetos – OO
A construção de sistemas computacionais complexos exige a implementação de uma 
quantidade muito grande de componentes. Antes de iniciar as etapas de programação 
desses componentes é necessário definir as fases iniciais para descrição dos requisitos 
do cliente, especificações do sistema, juntamente com a definição dos modelos de pro-
jeto e arquitetura a serem usados no desenvolvimento do sistema computacional. 
Observe a figura a seguir. A imagem mostra um exemplo de um modelo básico de proje-
to de um sistema computacional até a etapa de implementação de código: 
Figura: Modelo básico de projeto de um sistema computacional.
Fonte: O autor (2020).
Um dos desafios das equipes de projeto de sistemas computacionais complexos é con-
seguir uma forma de organizar os diversos componentes paraque seja possível:
• Atender aos requisitos funcionais e não funcionais definidos na especificação.
• Reusar componentes de forma a não implementar o mesmo serviço mais de uma vez.
Mundo real Mundo computacional
Requisitos do sistemaRequisitos do cliente
Especificação técnica
Modelos de arquitetura
Modelos de projeto
Modelos de design
Implementação de código
11
• Facilitar a manutenção do sistema (troca de componentes, mudança de regras, 
entre outros).
• Trazer portabilidade para o sistema (execução em plataformas de hardware/
software distintas).
Nesse contexto, a elaboração de sistemas de informação passa pela compreensão e 
pela aplicação adequada de modelos de arquitetura e padrões de projeto. O domínio des-
ses conceitos e de sua aplicação desempenha um papel fundamental no gerenciamento 
da complexidade inerente ao software a ser desenvolvido.
Podemos exemplificar o ciclo de vida de um sistema por meio do modelo em cascata, 
inicialmente proposto por W. W. Royce em 1970. As etapas do modelo em cascata são 
mostradas na figura a seguir.
Figura: Etapas do modelo em cascata. 
Fonte: O autor (2020).
Definição dos requisitos
Análise
Implementação
Implantação
Projeto
Teste/Avaliação
Manutenção
12
Apesar de simplificado, o modelo em cascata nos mostra que, antes da etapa de im-
plementação do código do sistema, é necessário que as etapas iniciais de definição de 
requisitos, análise e design do projeto sejam cuidadosamente elaboradas. Dessa forma: 
A escolha de padrões de arquitetura e de design de projeto adequados facilitará as 
etapas seguintes de implementação da programação, testes, alterações e manuten-
ções necessárias no sistema durante sua implantação.
Existem diferentes modelos propostos para auxiliar as etapas de análise e projeto, como 
modelos em cascata, modelos incrementais, prototipagem, entre outros. Atualmente um 
dos modelos mais difundidos para desenvolvimento de sistemas OO é o Processo Unifi-
cado (Unified Process – UP).
O Processo Unificado define as atividades específicas voltadas para análise, 
arquitetura e design de sistemas.
Agora, antes de continuarmos, vamos refletir: 
Por que devemos nos preocupar em definir um modelo de arquitetura 
adequado?
A definição do modelo de arquitetura é importante para:
APOIAR o 
planejamento do 
desenvolvimento
do sistema.
PERMITIR melhor 
tratamento dos 
atributos de 
qualidade de software 
(requisitos não 
funcionais).
AJUDAR no 
gerenciamento dos 
riscos técnicos e da 
complexidade da 
solução.
APOIAR a análise 
de impacto 
de mudanças 
tecnológicas e 
de negócio.
ORIENTAR as 
atividades de projeto 
e implementação.
13
O que são componentes arquiteturais?
São elementos que executam ou apoiam a execução das funcionalidades do sistema 
computacional, ou seja, são responsáveis pela execução dos serviços propriamente ditos. 
Componentes também podem ser definidos como abstrações que representam o 
hardware e o software (desenvolvido pela equipe ou por terceiros), que fazem parte de 
um sistema computacional.
Outra definição importante são os Conectores Arquiteturais, que definem a interação 
entre os componentes da arquitetura, permitindo representar a comunicação, coordena-
ção e cooperação entre eles. Conectores podem representar a conexão entre componen-
tes de hardware (equipamentos) ou entre componentes de software. 
Os conectores podem ser usados para representar:
• Comunicação de dados (HTTP, HTTPS, TCP/IP, SSL etc.).
• Chamada de funções, procedimentos ou métodos.
Exemplos de componentes de software:
• Desenvolvidos pela equipe (aplicativos, pacotes, módulos, bibliotecas,
web services etc.).
• Sistemas Gerenciadores de Banco de Dados – SGBD (SQL Server, MySQL,
Oracle etc.).
• Servidores de aplicação (Apache Tomcat, Zend Server, IIS etc.).
• Containers (Docker, Kubernetes, Google Cloud, Microsoft Azure etc.).
• Sistemas operacionais (Windows, Linux, Android, iOS etc.).
• Bibliotecas de terceiros (JQuery, Apache Commons, OpenGL etc.).
Exemplos de componentes de hardware:
• Servidores.
• Computadores pessoais (desktop, notebook etc.).
• Dispositivos móveis (smartphone, tablet, smartwatch etc.).
• Sensores/Leitores.
• Atuadores (equipamentos diversos controlados por software).
Exemplo
14
• Invocação de serviços.
• Acesso a dados.
• Conexão com banco de dados (ODBC, JDBC, ADO.NET etc.).
• Conexão com arquivos (file input/output).
• Streamings, eventos etc.
Existem diversos modelos arquiteturais propostos na literatura. Contudo, nesta disci-
plina vamos apresentar os modelos de camadas (layers), cliente-servidor (2-tier) e de 
multicamadas N-Tier.
Modelo em camadas
O modelo de arquitetura em camadas caracteriza-se pela organização do sistema em 
um conjunto de camadas lógicas, em que cada camada (“layer”) oferece um conjunto 
de serviços e possui uma função bem definida no sistema. Outro conceito importante é 
que uma camada somente solicita serviços da camada inferior e fornece serviços para 
a camada superior.
Figura: Exemplo de modelo em camadas de um sistema computacional de vendas 
com persistência de dados.
Fonte: O autor (2020).
Apresentação
Controle
Negócio ou
Domínio
Persistência
de dados
Formulário 
de Pedido
Controle 
do Pedido
PedidoDAO
Pedido
ClienteDAO
Cliente
BD
15
O modelo em camadas oferece vantagens como:
• Possibilidade de desenvolver cada camada de forma independente (paralelismo).
• As camadas podem ser facilmente substituídas por equivalentes.
• Mudanças em uma camada só impactam a camada imediatamente superior.
Por outro lado, o modelo em camadas possui as seguintes desvantagens:
• Cuidados extras devem ser tomados para garantir a integridade entre as cama-
das; por exemplo, o estado de um objeto na camada de persistência deve ser refleti-
do na camada de domínio e também na camada de apresentação.
• Muitas camadas podem comprometer o desempenho do sistema, pois a requisi-
ção precisa trafegar pelas várias camadas até ser atendida.
Modelo cliente-servidor (2-tier)
O modelo arquitetural cliente-servidor possui as seguintes características:
• Ser organizado como um conjunto de serviços (servidores e clientes dos serviços).
• Cliente e servidor rodam em máquinas distintas. 
• Requer uma estrutura de rede para clientes acessarem os servidores remotamente.
• Clientes devem saber quais serviços e servidores estão disponíveis, mas os servi-
dores não conhecem seus clientes. 
• Baseado no protocolo “pergunta-resposta” (request-reply), quando um cliente faz 
um pedido ao servidor e espera pela resposta. O servidor executa o serviço e res-
ponde ao cliente.
É importante destacar que “tiers” se referem a camadas físicas.
E oferece vantagens como:
• A distribuição de dados é fácil e direta.
• Possibilita hardware mais barato (clientes leves).
• Facilidade de adicionar novos servidores ou atualizar servidores existentes. 
16
E possui as seguintes desvantagens:
• Pode haver redundância de serviços em diferentes servidores.
• Não prevê um registro central de serviços, ou seja, os clientes devem saber onde 
estão os servidores e quais serviços eles disponibilizam.
• Precisa organizar três camadas lógicas (apresentação, negócio e dados) em duas 
camadas físicas (cliente e servidor).
Modelo multicamadas (N-tier)
O modelo multicamadas (N-tier) pode ser considerado uma evolução da arquitetura 
cliente-servidor porque consegue separar as lógicas de apresentação, negócio e dados 
em máquinas distintas.
E oferece vantagens como:
• Melhor balanceamento de carga entre as diversas camadas.
• Aumenta a escalabilidade: é fácil adicionar novos servidores de aplicação quando 
o número de usuários aumenta. 
E possui as seguintes desvantagens:
• Maior complexidade no desenvolvimento para um número maior de camadas 
(quatro ou mais).
• Quanto maior o número de camadas, maior o overhead de comunicação entre elas.
Figura: Exemplos de modelo de arquitetura 3-Tier.
Fonte: O autor (2020).
Servidor
Processamento de Aplicações
Servidor
Gerenciamentode dados
Servidor Web
Processamento de Aplicações
Servidor de BD
Gerenciamento de dados
Apresentação
HTTP
Cliente
Cliente
Cliente
Cliente
17
Figura: Exemplo de modelo de arquitetura 4-Tier.
Fonte: O autor (2020).
Arquitetura de Microsserviços
O conceito de Arquitetura de Microsserviços surgiu há poucos anos como uma forma 
de desenvolver aplicações de software. Apesar de não existir ainda uma definição clara 
do padrão de Microsserviços, existem algumas características comuns em torno da ca-
pacidade de negócio, distribuição automatizada, inteligência nos pontos de integração e 
controle descentralizado das linguagens e dados.
Segundo Martin Fowler (2015), o padrão arquitetural baseado em Microsserviços corres-
ponde ao modo de desenvolver uma única aplicação como um conjunto de pequenas 
aplicações, cada uma em seu próprio contexto e com processos independentes que se 
comunicam por meio de mecanismos simples, tradicionalmente por requisições a uma 
API utilizando o protocolo HTTP.
Uma das principais razões para utilizar serviços como componentes é que serviços po-
dem ser implantados independentemente uns dos outros. Assim, a partir do baixo aco-
Camada do cliente
(browser)
Camada da aplicação
(Servlet/JSP)
Camada do negócio
(Casses Java/Java Beans)
Camada de dados
(SGBD)
18
plamento e da decomposição da aplicação em vários serviços, a manutenção ou alte-
ração de um serviço não atinge outras partes da aplicação no que em geral ocupa um 
tempo de indisponibilidade menor.
19
Padrões de projeto de sistemas OO: Modelo-
-Visão-Controle – MVC, DAO, Factory e 
Singleton
Neste tópico serão abordados alguns padrões de projeto (ou padrões de design) para 
orientar o desenvolvimento de sistemas computacionais Orientados a Objetos – OO 
complexos com acesso a banco de dados e aplicações Web.
O paradigma da Programação Orientada a Objetos tenta resolver alguns dos problemas 
existentes na programação procedural, como permitir maior reutilização de código e fa-
cilitar a manutenção, a modificação e a evolução dos sistemas.
Como definir as responsabilidades de cada componente ou classe de um 
sistema OO para alcançar uma alta coesão? 
É necessário definir componentes com atribuições bem delimitadas a fim de facilitar seu 
gerenciamento. Caso contrário, as classes serão difíceis de compreender, reutilizar e rea-
lizar manutenções ou modificações durante o ciclo de vida do sistema.
Vamos pensar!
Como implementar os diversos componentes do sistema OO para que se 
tenha baixo acoplamento? Como projetar componentes, classes e sub-
sistemas para que as variações nesses elementos não tenham um im-
pacto indesejável no restante do sistema?
O conceito de coesão está relacionado ao princípio da Responsabilidade Única 
usado em projeto de sistema OO, em que idealmente uma classe deve ter ape-
nas uma responsabilidade e realizá-la de maneira adequada. Uma classe com 
baixa coesão assume muitas responsabilidades, realiza muitas coisas não re-
lacionadas e trabalha demais. Como consequência, classes com baixa coesão 
apresentam maior dificuldade de manutenção, modificação e reúso. 
Importante
20
De forma geral, a área de Projeto de Sistemas OO possui alguns princípios e recomen-
dações para a organização de componentes, suas responsabilidades e relacionamentos, 
de forma que tais componentes sejam mais flexíveis e que as mudanças em um deles 
tenham menor impacto possível nos demais. Além disso, que sejam mais fáceis de en-
tender e à base de componentes que possam ser usados em vários sistemas, facilitando 
o reúso do código.
Padrão Model-View-Controller – MVC
O padrão MVC pode ser considerado tanto um padrão de arquitetura como de projeto. Ele 
possui como características a divisão da aplicação interativa em três partes:
• Model: encapsula os dados e as funcionalidades do negócio e é independente de 
uma apresentação específica.
• View: apresenta informações do Model ao usuário.
• Controller: trata a entrada do usuário.
Além disso, no padrão MVC podem existir múltiplas Views para um mesmo Model e cada 
View está associada a um único Controller. Contudo, os dois juntos, Views e Controllers, 
formam a interface com o usuário.
O padrão MVC é normalmente utilizado em sistemas interativos quando existem várias 
maneiras de visualizar e interagir com os dados. Outro uso importante do MVC é quando 
os requisitos de interação com os usuários são voláteis ou em aplicações que requerem 
interfaces em diversas plataformas distintas de hardware/software.
O MVC estabelece um mecanismo para propagação das mudanças do projeto de forma 
a manter a consistência entre Model e View. A saber:
• Os Controllers recebem a entrada do usuário (geralmente eventos).
O termo “acoplamento” é uma medida de quanto um elemento está conectado 
a ou depende de outros elementos. Um componente com acoplamento forte 
depende de muitos outros componentes, o que dificulta a reutilização, a manu-
tenção e as modificações no código.
Ampliando o foco
21
• Eventos são traduzidos em requisições de serviço que são enviadas para o Model 
ou para a View.
• Após receber a requisição e alterar seu estado interno o Model notifica todas as 
Views a ele conectadas.
• As Views notificadas recuperam os dados do Model e atualizam as informações 
para o usuário.
Figura: Modelo MVC para desenvolvimento de aplicações Web.
Fonte: O autor (2020).
Podemos citar como vantagens do padrão MVC: 
• Permite diferentes padrões/estilos de interação sem alterar o núcleo da aplicação.
• Permite a visualização da mesma informação em formatos distintos, porém sin-
cronizados.
• Permite a alteração de Views/Controllers em “tempo de execução”.
E como desvantagens:
• Maior complexidade quando o modelo de dados e de interações é muito simples. 
• Views e Controllers fortemente interconectados.
Model
Enviar requisição
Apresentar dados
forward
model.alterarEstado()
model.getDados()
1 2a
2b
4 3
View
Controller
22
Figura: Exemplo do MVC usado no desenvolvimento de aplicações Web com JSP/Servlet/EJB/JPA.
Fonte: O autor (2020).
Padrão Factory Method
Muitas vezes o processo de criação de um objeto exige condições específicas que não 
são apropriadas para serem incluídas dentro do método construtor do objeto. Pode ocor-
rer que para a criação de um objeto sejam necessárias informações externas, respon-
sabilidades adicionais, duplicação indesejada de código, gerando maior acoplamento e 
menor coesão na classe.
O padrão Factory Method pode definir uma interface para criação de um objeto, mas 
deixar que as subclasses decidam qual classe instanciar.
Esse padrão permite que uma classe delegue a responsabilidade de instan-
ciação às subclasses.
Dada uma hierarquia de classe, temos um ponto do código em que gostaríamos de cons-
truir um objeto dessa hierarquia. Entretanto, o objeto a ser construído dependerá de algu-
ma condição. 
Model
Sessions Beans
(EJB)
Entity Classes
(JPA)
Request
Response
Database
Controller
(servlet)Client
(browser)
View
(JSP pages)
23
Figura: Exemplo do padrão Factory Method.
Fonte: O autor (2020).
Padrão de projeto Data Access Objects – DAO
Grandes sistemas computacionais normalmente precisam armazenar suas informações 
de trabalho de forma organizada para permitir consultas, alterações de registros ou 
geração de relatórios de maneira eficiente. Dessa forma, geralmente é necessário usar 
uma solução de banco de dados, que armazena as informações de forma organizada e 
prontas para consultas.
Grande parte dos bancos de dados comerciais são relacionais, compostos por uma es-
trutura de tabelas e atributos que possuem relacionamentos entre si. 
Exemplo 1
Precisamos criar um objeto que armazene a forma de pagamento de um pedi-
do, que pode ser cartão de crédito, débito, boleto ou PayPal, a depender do tipo 
desejado pelo cliente.
Exemplo 2
Precisamos criar um objeto que armazene a forma de conexão em um banco 
de dados, que pode ser MySQL, SQLServer, Oracle.
Exemplo
24
O modelo debanco de dados relacionais possui um padrão de trabalho bem 
diferente do paradigma da Orientação a Objetos.
Por exemplo, para começar a trabalhar com banco de dados relacionais é necessário 
conhecer a linguagem SQL (Structured Query Language), que é usada para a criação de 
tabelas, conexões aos bancos, realização de consultas, entre outras ações. 
Dessa maneira será necessário: 
Desenvolver classes para trocar informações com os Sistemas Gerenciadores dos 
Bancos de Dados – SGBD e implementar operações CRUD (Create, Read, Update e 
Delete).
Essas classes devem ser capazes de: 
• Ler e escrever nas tabelas do banco de dados.
• Transformar esses dados em objetos ou lista de objetos.
• Realizar operações usando instruções SQL e outras funcionalidades. 
Porém, teremos um problema. Quando é preciso colocar código SQL dentro das classes 
Java para incluir funcionalidades de acesso e consulta aos bancos de dados, as reco-
mendações de alta coesão e baixo acoplamento não são mais respeitadas. O código fica 
menos legível, mais confuso e apresenta maior dificuldade para alterações e manutenção. 
Como podemos solucionar esse problema?
A solução para esse problema é tentar separar o código SQL de acesso ao banco de 
dados das demais classes de lógica e colocá-lo em uma classe responsável apenas pelo 
acesso aos dados. Dessa forma, o código de acesso ao banco de dados fica concentra-
do em apenas um local, tornando mais fácil a manutenção, além de tornar as classes 
mais legíveis.
Dessa forma, o padrão de projeto Data Access Object – DAO permite que, por meio de 
uma única classe, seja realizada toda a lógica de controle de acesso ao banco de dados, 
separando a lógica de negócio das outras classes. 
25
Somente a partir das classes DAO é que será possível: 
1. Conectar e acessar o banco de dados. 
2. Manter os princípios de alta coesão e baixo acoplamento do código. 
O padrão DAO permite que seja possível alterar a forma de persistência de dados sem in-
fluenciar a lógica de negócio. Nas próximas unidades serão abordados maiores detalhes 
sobre a implementação das classes DAO.
Figura: Exemplo de Diagrama de Classes sem DAO – Objeto está com responsabilidades demais.
Fonte: O autor (2020).
Figura: Exemplo de Diagrama de Classes com DAO – Agora apenas o ObjetoDAO possui responsabilida-
des CRUD – Maior coesão e menor acoplamento.
Fonte: O autor (2020).
26
Padrão Singleton
Em diversas situações é necessário que apenas uma instância de uma classe seja cria-
da, independentemente de quantas requisições de criação possam ser feitas. 
Veja alguns exemplos.
O padrão Singleton é definido de forma a garantir que uma classe só tenha uma única 
instância e prover um ponto de acesso global a ela.
Figura: Exemplo de Diagrama de classe do Padrão Singleton.
Fonte: O autor (2020).
Observe o exemplo a seguir de implementação Java do padrão Singleton com instancia-
mento direto. 
• Uma única conexão com o banco de dados.
• Um único arquivo de log de erros.
• Uma única fila de impressão.
• Um único arquivo de configuração.
Exemplos
27
No exemplo anterior o construtor é definido como “private” para impedir que a classe 
Singleton seja instanciada fora dela. Foi criado um atributo público e estático (da classe) 
que retorna a partir de um método estático (getInstancia), uma única instância dessa 
classe. Como o método “getInstancia()” é estático ele pode ser chamado de outra classe 
sem precisar instanciar a classe Singleton. É importante notar que neste exemplo a ins-
tância da classe será sempre criada mesmo antes de chamar o método “getInstancia()”.
public class Singleton {
 private static Singleton instancia = new Singleton();
 private Singleton() { 
 }
 
 public static synchronized Singleton getInstancia() {
 return instancia;
 }
}
Exemplos
28
Acesso e conexão a gerenciadores de banco 
de dados com uso do JDBC
O desenvolvimento de sistemas de informação para empresas exige funcionalidades de 
armazenamento de dados, também conhecidas como persistência de dados. Em geral, 
as atividades de controle e gestão de um sistema empresarial necessitam de acesso às 
informações armazenadas para geração de relatórios e gráficos, histórico de problemas, 
análise de tendências, planejamento, tomada de decisões, entre outras diversas atividades.
Dessa forma, uma aplicação Java precisa realizar uma conexão com um Sistema Geren-
ciador de Banco de Dados – SGBD para poder implementar as operações necessárias 
para a manutenção de informações, tais como: inclusão, leitura, alteração e exclusão 
de dados. Essas operações também são conhecidas pelo acrônimo: 
C reate
R ead
U pdate
D elete
Para realizar a conexão devemos inicialmente identificar o gerenciador de banco de da-
dos que será utilizado pelo projeto, já que para cada tipo de gerenciador existe um driver 
(modo de acesso próprio). Logo, para cada gerenciador de banco de dados devemos 
utilizar uma classe específica para esse fim.
Conexão a banco de dados em Java
A biblioteca de persistência em banco de dados relacionais do Java é chamada 
Java DataBase Connectivity – JDBC e fica dentro do pacote java.sql.
A biblioteca JDBC consiste em um único conjunto de interfaces muito bem 
definidas e cujos métodos e classes devem ser implementados para permitir
a conexão e o acesso ao banco de dados.
Essa configuração com uma API única padroniza a forma de acesso aos dados armaze-
nados, evitando que cada banco de dados tenha sua própria interface.
29
Entre as diversas interfaces do JDBC, podemos citar a interface Connection, na qual são 
definidos métodos padrões para trabalhar com banco de dados, tais como:
• Executar consultas. 
• Inserir dados.
• “Comitar” uma transação.
• Fechar a conexão, entre outros. 
Caso seja necessário trabalhar com algum banco de dados específico, como o MySQL, 
precisaremos de classes concretas que implementem essas interfaces do pacote java.sql. 
Esse conjunto de classes concretas recebe o nome de driver e fará a ligação entre a apli-
cação que usa a interface JDBC e o banco de dados. Esse conjunto de classes é o que 
implementa a comunicação a partir do protocolo proprietário do banco de dados.
Vamos entender melhor o assunto! Veja o exemplo a seguir.
Para abrir uma conexão com um determinado banco de dados precisamos utilizar sem-
pre o driver apropriado. A classe DriverManager do JDBC é a responsável por comunicar-
-se com os drivers disponíveis para conexão, como mostrado na figura a seguir:
Todos os principais bancos de dados possuem drivers JDBC para utilização 
com Java. O nome “driver” é análogo ao utilizado para periféricos em geral. 
Como um sistema operacional poderia comunicar-se com as diversas impresso-
ras disponíveis no mercado, cada uma com características específicas? 
Neste caso, é necessário que cada impressora disponibilize um driver com as 
interfaces necessárias para realizar a comunicação com o sistema operacional.
Exemplo
30
Figura: Modelo de conexão a diferentes banco de dados com JDBC API e Driver Manager.
Fonte: tutorialspoint.com. Adaptado.
Conexão implementada por meio do método estático getConnection com uma String 
que indica a qual banco desejamos nos conectar. Essa String é chamada de string de 
conexão JDBC, conforme mostra o exemplo a seguir:
DriverManager.getConnection(string_de_conexao); 
Para conexão ao banco de dados MySQL a string de conexão tem o seguinte formato:
jdbc:mysql://ip/nome_do_banco
MySQL SQL
Server
Oracle
Java Application
JDBC API
JDBC Driver
Manager
Drivers
específicos
JDBC DriverJDBC Driver JDBC Driver
https://www.tutorialspoint.com/jdbc/jdbc-introduction.htm
31
Devemos substituir: 
• “ip” pelo código IP da máquina do servidor. 
• “nome_do_banco” pelo nome do banco de dados a ser utilizado. 
Na string de conexão também podem ser incluídos o login e a senha do usuário.
Agora, veja um exemplo prático. Preste atenção!
Utilizando as informações anteriores podemos usar o código a seguir para implemen-
tar a conexão paraum banco de teste MySQL (“BD_teste”), caso ele esteja rodando na 
mesma máquina:
public class JDBCExemplo {
 public static void main(String[] args) throws SQLException {
 Connection conexao = 
 DriverManager.getConnection(“jdbc:mysql://localhost/BD_teste”);
 System.out.println(“Conectado!”);
 conexao.close();
 }
}
No exemplo anterior o tratamento de exceções não está sendo realizado de forma ade-
quada. Estamos deixando passar a SQLException, uma “exception checked”, que pode 
ser lançada por muitos dos métodos da API de JDBC. 
Em uma aplicação real é necessário fazer um tratamento de exceções mais específico 
utilizando a estrutura “try/catch” nos lugares em que há possibilidade de recuperação 
de alguma falha com o banco de dados. Vale lembrar também que é necessário fechar 
todas as conexões que foram abertas. 
32
Ao testar esse código, será recebida uma “exception” informando que a conexão não
pôde ser aberta, de acordo com a mensagem a seguir:
java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost/BD_teste
Esse problema ocorreu porque o sistema ainda não achou uma implementa-
ção de driver JDBC que possa ser usada para abrir a conexão indicada pela URL 
jdbc:mysql://localhost/BD_teste.
O próximo passo é adicionar o driver do MySQL ao “classpath”, ou seja, o arquivo “.jar” 
contendo a implementação JDBC do MySQL (MySQL Connector) precisa ser colocado 
em um lugar visível pelo seu projeto ou adicionado à variável de ambiente CLASSPATH.
Class.forName
Até a versão 3 do JDBC, antes de chamar o DriverManager.getConnection() era necessá-
rio registrar o driver JDBC que iria ser utilizado a partir do método:
Class.forName(“com.mysql.jdbc.Driver”)
No caso do MySQL, que carregava essa classe e se comunicava com o DriverManager, 
a partir do JDBC 4 (presente no Java 6) esse registro passou a não ser mais necessário.
Vale lembrar que, se o JDBC for usado em um projeto com Java 5 ou anterior, será ne-
cessário fazer o registro do driver JDBC carregando sua classe, que se registrará no 
DriverManager.
Alterando o banco de dados
Inicialmente, para trocar de um banco de dados para outro, bastaria modificar a string de 
conexão e a string de registro do driver JDBC. O problema é que os códigos implementa-
dos das classes JDBC utilizam código SQL para acesso aos bancos de dados. 
33
Um banco de dados diferente pode utilizar uma implementação da linguagem SQL não 
totalmente compatível com o padrão ANSI SQL. Dessa forma, apenas alterar as strings 
de conexão não garante o total funcionamento das classes no novo banco de dados. Nas 
próximas unidades serão abordadas soluções para esse problema, como é o caso do 
Hibernate (www.hibernate.org) e da especificação Java Persistence API – JPA.
Para ampliar o seu conhecimento veja o material complementar da Unidade 1, 
disponível na midiateca.
MIDIATECA
Algumas vezes é necessário realizar conexões com diferentes bancos de dados, 
cada um com seu driver específico. Segue exemplo de método com uma confi-
guração básica para a conexão com um servidor de banco de dados MySQL. O 
método retornará a conexão com o banco MySQL por meio do objeto con:
• Biblioteca: mysql-connector-java-5.1.6-bin.jar.
NA PRÁTICA
Os drivers de outros bancos de dados podem ser baixados normalmente 
nos sites dos respectivos fabricantes. Em alguns casos, como no Microsoft 
SQL Server, existem grupos alternativos que desenvolvem o driver em 
http://jtds.sourceforge.net. O driver do MySQL (chamado de MySQL Connector)
pode ser baixado no site http://www.mysql.org.
Ampliando o foco
http://www.hibernate.org
http://jtds.sourceforge.net
http://www.mysql.org
34
public static Connection acessoMySQL() { 
 
 Connection con = null; // definição do objeto de conexão com o banco 
 
 try { 
 // definição do driver de conexão para o MySQL 
 String driver = "com.mysql.jdbc.Driver"; 
 // registro da classe de acesso ao banco não é necessário a partir 
 // do JDBC 4, presente na versão Java 6, versões anteriores poderão 
 // exigir esse registro 
 Class.forName(driver); 
 // determinar o caminho de acesso ao servidor 
 // para acesso local, ou seja, a própria máquina, você pode usar 
 // localhost ou 127.0.0.1 
 // ou você pode indicar o endereço IP do servidor 
 String nomeServidor = "localhost"; 
 // nome do banco de dados que será aberto 
 // um servidor pode ter mais de um banco de dados registrado 
 String nomeBanco = "BD_teste"; 
 // definição da configuração de acesso ao servidor 
 String url = "jdbc:mysql://" + nomeServidor + "/" + nomeBanco; 
 // executa a conexão com o banco de dados 
 // caso não consiga realizar a conexão, uma exceção será lançada 
 con = DriverManager.getConnection(url); 
 // testa se sua conexão foi realizada// 
 if (con != null) { 
 System.out.println("Banco conectado com sucesso!"); 
 } else { 
 System.out.println("Banco não conectado!"); 
 } 
 } 
 // caso seja lançada uma exceção de driver não encontrado, 
 // provavelmente a biblioteca de acesso do driver 
 // não foi incluída no projeto 
 catch (Exception e) { 
 e.printStackTrace(); 
 } 
 return con; 
} 
 
• Driver: com.mysql.jdbc.Driver.
• Exemplo de método de conexão.
35
Resumo da Unidade 1
Nesta unidade foram abordados conceitos de diferentes modelos de arquitetura de sis-
temas computacionais (modelo em camadas, cliente-servidor e multicamadas), além de 
alguns padrões de projeto (MVC, DAO, Factory e Singleton) para desenvolvimento de sis-
temas OO com acesso a bancos de dados e aplicações Web. Também foram apresenta-
das técnicas de acesso e conexão a sistemas gerenciadores de banco de dados – SGBD 
com uso da biblioteca JDBC.
36
Referências 
DEITEL, P.; DEITEL, H. Java: como programar. 10. ed. São Paulo: Pearson Education do 
Brasil, 2017. Cap. 24, p. 13-860. Biblioteca Virtual.
FOWLER, M. Analysis Patterns: Reusable Object Models. Londres: Addison-Wesley 
Reading, 1996.
FREEMAN, E.; FREEMAN, E.; SIERRA, K.; BATES, B. Use a cabeça: padrões e projetos. 2. 
ed. rev. Rio de Janeiro: Alta Books, 2009. xxiv, 478 p. ISBN 9788576081746.
FURGERI, S. Java 8 – Ensino didático: desenvolvimento e implementação de aplicações.
São Paulo: Érica, 2015. Cap. 12, p. 232-256. Minha Biblioteca
GAMMA, E. et al. Padrões de projeto: soluções reutilizáveis de software orientado a ob-
jetos. Porto Alegre: Bookman, 2000. xii, 364 p. ISBN 9788573076103.
LARMAN, C. Utilizando UML e padrões: uma introdução à análise e ao projeto orienta-
dos a objetos e ao desenvolvimento iterativo. Porto Alegre: Bookman, 2000. 492 p.
Acesso a bancos de dados 
relacionais via JDBC utilizando 
diferentes padrões de projeto 
UNIDADE 2
38
Nesta unidade serão abordadas técnicas para desenvolver aplicações Java com persis-
tência de dados com uso da biblioteca JDBC por meio de mapeamento objeto-relacio-
nal. O aluno terá oportunidade de aprender com exemplos de acesso a banco de dados 
utilizando os modelos de projeto DAO e “Factory” para implementar operações CRUD e 
mapeamento objeto-relacional não automático.
Como estamos tratando de sistemas computacionais multiusuários com acessos con-
correntes ao mesmo banco de dados, é necessário que o SGBD implemente algum tipo 
de controle de acesso para que cada transação seja atendida de forma justa e eficiente. 
Assim, serão abordadas diferentes técnicas de controle concorrente de transações em 
banco de dados. Caso haja falha em uma transação, seus efeitos deverão ser revertidos 
para garantir a integridade e a consistência do banco de dados. 
Também serão abordadas recomendações para o tratamento adequado de erros e exce-
ções em sistemas Java com acesso a banco de dados.
INTRODUÇÃO
Nesta unidade você será capaz de:
• Desenvolver aplicações em Java com persistência de dados por meio de 
mapeamento objeto-relacional manual. 
OBJETIVO
39
Acesso remoto a gerenciadores de bancos 
de dados relacionais com usodo JDBC 
Neste tópico serão abordados alguns exemplos práticos de programação Java para uti-
lização das classes da biblioteca JDBC para conexão e implementação das operações 
CRUD em banco de dados. 
Utilizaremos como SGBD o MySQL Server, que é mantido pela Oracle e amplamente uti-
lizado em aplicações comerciais. Em seguida, apresentaremos o modelo de conexão ao 
MySQL usando JDBC API e Driver Manager, como mostra a figura a seguir.
Figura: Modelo de conexão ao MySQL usando JDBC API e Driver Manager.
Fonte: Notas de aula do professor (2020).
Fábrica de Conexões (“Connection Factory”)
Como já vimos muitas vezes, o processo de criação de um objeto pode exigir critérios 
específicos que não são adequados para incluir dentro de seu próprio método construtor. 
No caso específico de criação de uma conexão ao banco de dados, são necessárias in-
MySQL
Java Application
JDBC API
JDBC Driver
Manager
JDBC Driver
40
formações específicas dos SGBD, diferentes strings de conexão, o que pode gerar maior 
acoplamento e menor coesão na classe que está sendo desenvolvida. 
Dessa forma, o padrão “Factory Method” pode ser usado para definir uma interface para 
a criação das conexões do banco de dados a fim de controlar melhor esse processo 
repetitivo e trabalhoso, que consome muitos recursos do SGBD.
Veja um exemplo de classe responsável por criar uma nova conexão com o banco de dados. 
No exemplo anterior, o tratamento das exceções não está sendo realizado de forma ade-
quada, pois a SQLException é uma “exception checked”, que pode ser lançada por muitos 
dos métodos da API de JDBC. É necessário fazer um tratamento de exceções específico, 
usando a estrutura “try/catch”, quando há possibilidade de recuperação do sistema caso 
ocorra alguma falha. 
Dessa forma, para obter uma nova conexão com o banco de dados basta usar o seguinte 
comando:
Para criar uma conexão JDBC, é necessário usar a classe DriverManager pre-
sente no pacote java.sql. A string de conexão contendo o endereço URL do 
banco de dados, o usuário e a senha deve ser repassada ao método estáti-
co getConnection() da classe DriverManager para que ela possa criar uma 
conexão JDBC:
Exemplo
public class ConnectionFactory { 
 public Connection criaConexao() throws SQLException{ 
 return 
DriverManager.getConnection("jdbc:mysql://localhost/BD_teste,"ro
ot","senha"); 
 } 
} 
 
Connection conexao = ConnectionFactory.criaConexao(); 
 
41
O método “criaConexao()” pode ser considerado uma fábrica de conexões, pois, ao ser 
executado, retorna um objeto “Connection” representando a criação de uma nova cone-
xão pronta para uso, independentemente de detalhes da codificação. 
Apagando uma base de dados 
Depois de implementar uma conexão JDBC, podemos começar a executar opera-
ções no banco de dados. O primeiro exemplo de operação será apagar uma base de 
dados “bdteste”. Inicialmente, para executar uma operação deve-se definir o código 
SQL correspondente. 
O código SQL que corresponde à operação a ser executada deve ser usado como parâ-
metro para a interface “prepareStatement()” de uma conexão JDBC. Essa interface cria 
um objeto do tipo “PreparedStatement”, que representa a operação que será executada. 
Em seguida, a operação SQL poderá ser realizada por meio do método “execute()”. No 
final, deve-se chamar o método “close()” do objeto “PrepareStatment” para liberação de 
recursos de memória.
String sql = "DROP DATABASE IF EXISTS bdteste"; 
PreparedStatement stm = conexao.prepareStatement(sql); 
 stm.execute(); 
 stm.close(); 
 
Uma mesma conexão pode ser reaproveitada para executar outras operações 
do banco de dados. A conexão JDBC deverá ser finalizada a partir do método 
“close()” quando não houver mais operações a serem executadas, a fim de libe-
rar recursos no SGBD:
Importante
conexao.close(); 
42
Criando uma base de dados 
O procedimento de criação de uma base de dados é similar ao procedimento anterior 
para apagar uma base de dados:
Criando uma tabela de dados 
O código a seguir mostra o procedimento de criação de uma tabela a partir de uma 
conexão JDBC.
JavaBeans
JavaBeans são classes que possuem o construtor “default” sem argumentos e apenas 
os métodos básicos de acesso “get” e “set”, cuja especificação é a base dos componen-
tes escritos em Java. 
Neste tópico usaremos o conceito JavaBeans nas classes que representam nosso 
modelo de dados.
String sql = "CREATE DATABASE dbpoo3" 
 PreparedStatement stm = conexao.prepareStatement(sql); 
 stm.execute(); 
 stm.close(); 
 
String sql = "CREATE TABLE alunos (" + ; 
 " idaluno INT NOT NULL AUTO_INCREMENT ," + 
 " matricula INT NOT NULL" + 
 " nome VARCHAR(45) NOT NULL ," + 
 " PRIMARY KEY (idaluno))" ; 
 PreparedStatement stm = conexao.prepareStatement(sql); 
 stm.execute(); 
 stm.close(); 
 
43
Veja um exemplo de uma classe “Aluno” no padrão “JavaBeans”, que seria equivalente ao
nosso modelo de entidade do banco de dados da tabela “Alunos”:
Exemplo
public class Aluno { 
 private int idaluno; 
 private int matricula; 
 private String nome; 
 // métodos get e set da classe Aluno 
 public String getNome() { 
 return this.nome; 
 } 
 public void setNome(String novo_nome) { 
 this.nome = novo_nome; 
 } 
 public int getId() { 
 return this.idaluno; 
 } 
 public void setId(int novo_id) { 
 this.idaluno = novo_id; 
 } 
 public int getMatricula() { 
 return this.matricula; 
 } 
 public void setMatricula(int novo_mat) { 
 this.matricula = novo_mat; 
 } 
 } 
 
A especificação JavaBeans é a base dos componentes escritos em Java e sua 
documentação completa pode ser encontrada em http://docs.oracle.com/java-
se/tutorial/javabeans/. 
Ampliando o foco
http://docs.oracle.com/javase/tutorial/javabeans/
http://docs.oracle.com/javase/tutorial/javabeans/
44
Inserindo dados em uma tabela
Agora, veremos um exemplo de como adicionar dados nas tabelas utilizando conexões 
JDBC. 
Normalmente, as chaves primárias dos registros inseridos em uma tabela são geradas 
pelos SGBDs. Caso necessário os valores da chave primária podem ser obtidos a partir 
dos métodos definidos pela especificação JDBC. 
O exemplo anterior possui alguns problemas. São eles:
• A mistura das sintaxes das linguagens Java e SQL torna o código confuso e 
de difícil entendimento, especialmente para operações de inserção e atualização 
de dados.
• A necessidade de concatenação de strings longas para implementar os 
comandos SQL, principalmente com tabelas de dados grandes com várias colunas.
• O tratamento de caracteres especiais nas strings e o risco de alteração do código 
SQL por usuários mal-intencionados (SQL Injection).
Não confunda JavaBeans com outro componente chamado de Enterprise 
JavaBeans – EJB. Os EJBs são componentes da plataforma Java Enterprise 
Edition – JEE, que roda em um “container” de um servidor de aplicação. Seu 
objetivo é fornecer um desenvolvimento de aplicações Java de forma mais 
simples e rápida, baseado em componentes distribuídos, transacionais, segu-
ros e com portabilidade.
Importante
 String sql = "INSERT INTO alunos (matricula , nome)” + 
 “VALUES ( ’202001’,’João da Silva’)"; 
 PreparedStatement stm = conexao.prepareStatement(sql); 
 stm.execute(); 
 stm.close(); 
 
45
Por esses motivos a forma de entrada do código SQL será atualizada da seguinte maneira:
Nesta sintaxe, o comando SQL será executado, mas não sabemos os parâmetros que 
utilizaremos no código SQL. As cláusulas são executadas em um banco de dados por 
meio da interface PreparedStatement. Para receber uma PreparedStatement relativa à 
conexão, basta chamar o método prepareStatement, passando como argumento o co-
mando SQL com os valores oriundos de variáveis preenchidos com uma interrogação.
Logo, chamamos os métodos setLong e setString do PreparedStatementpara preen-
cher os valores, que são do tipo “int” e “String”, passando a posição (começando em 1) da 
interrogação no SQL e o valor que deve ser colocado:
Por fim, uma chamada ao método “execute()”para executar o comando SQL:
String sql = "INSERT INTO alunos (matricula, nome) VALUES (?,?)"; 
 
 String sql = "INSERT INTO alunos (matricula, nome) VALUES (?,?)"; 
 PreparedStatement stm = conexao.prepareStatement(sql); 
 
 // preenche os valores 
 stm.setInt(1, 202001); 
 stm.setString(2, "João da Silva"); 
 
stm.execute(); 
46
O exemplo a seguir abre uma conexão e adiciona um aluno ao banco de dados:
 public class JDBCadiciona { 
 public static void main(String[] args) throws SQLException { 
 // conectando 
 Connection conexao = ConnectionFactory.criaConexao(); 
 // cria um preparedStatement 
 String sql = "INSERT INTO alunos (matricula,nome) VALUES (?,?)"; 
 PreparedStatement stm = conexao.prepareStatement(sql); 
 // preenche os valores 
 stm.setInt(1, 202001); 
 stm.setString(2, "João da Silva"); 
 // executa 
 stmt.execute(); 
 stmt.close(); 
 System.out.println("Gravado!"); 
 conexao.close(); 
 } 
 
Sobre a interface Statement, em vez de se usar o PreparedStatement é possível 
utilizar uma interface mais simples chamada Statement, que simplesmente 
executa uma cláusula SQL no método “execute”:
O problema é que, apesar de ser mais simples, a interface Statment é mais len-
ta e será necessário implementar muitas concatenações de strings, tornando o 
código mais difícil de entender. Dessa forma, é recomendável utilizar apenas a 
classe PreparedStatement.
 Statement stm = conexao.createStatement(); 
 stm.execute("INSERT INTO ..."); 
 stm.close(); 
 
Importante
47
Classe Data Access Object – DAO
A separação do código de acesso ao banco de dados em uma classe DAO, com apenas
essa responsabilidade, aumenta a coesão e diminui o acoplamento do código, facilitan-
do sua manutenção e sua atualização. Da responsabilidade desse objeto surgiu o nome
Data Access Object, ou simplesmente DAO, um dos mais utilizados padrões de projeto
(design patterns).
Podemos implementar a classe “AlunoDAO” com um método construtor, que cria uma 
conexão com banco de dados por meio de uma chamada ao método “criaConexao()” da 
classe ConnectionFactory. 
Então, uma instância de AlunoDAO já possui uma conexão com o banco de dados e 
podemos implementar o método “adicionaAluno”, que recebe um objeto “Aluno” como 
argumento e é responsável por adicioná-lo a partir de código SQL:
 public class AlunoDAO { 
 // abre uma conexão com o banco de dados 
 private Connection conexao; 
 public AlunoDAO() { 
 this.conexao = ConnectionFactory.criaConexao(); 
 } 
 } 
 
 
 public void adicionaAluno(Aluno aluno) throws SQLException{ 
 String sql = "INSERT INTO alunos (matricula,nome) VALUES (?,?)"; 
 // comando prepared statement para inserção de dados 
 PreparedStatement stm = conexao.prepareStatement(sql); 
 // entra com os valores de inserção 
 stm.setInt(1,aluno.getMatricula()); 
 stm.setString(2,aluno.getNome()); 
 // executa 
 stm.execute(); 
 stm.close(); 
 } 
 
48
Fazendo pesquisas no banco de dados
A implementação de pesquisas no banco de dados também utiliza a interface 
“preparedStatement” para montar o comando SQL. Entretanto, como uma pesquisa no 
banco possui valores de retorno (diferentemente do comando de inserção), será utilizado 
o método “executeQuery”, que retorna todos os registros de uma determinada consulta.
O objeto retornado é do tipo “ResultSet” do JDBC, que possibilita navegar por seus re-
gistros por meio do método “next”. Quando chega ao fim da pesquisa, o método “next” 
retorna um valor “false” e dessa forma pode ser utilizado para fazer um laço (“loop”) nos 
registros. Para retornar o valor de uma coluna no banco de dados, basta chamar os mé-
todos “get” do “ResultSet”, como “getString”, “getInt”, “getLong”, entre outros.
Aplicando o conceito DAO, podemos criar um método “getListaAlunos()” na nossa classe 
AlunoDAO retornando uma lista de objetos “Aluno”:
 // exemplo de consulta simples 
 // inicia o prepareStatement 
 PreparedStatement stm = conexao.prepareStatement("SELECT * FROM alunos"); 
 // executa uma consulta select 
 ResultSet rs = stm.executeQuery(); 
 // iteração no ResultSet 
 while (rs.next()) { 
 int matricula = rs.getInt("matricula"); 
 String nome = rs.getString("nome"); 
 System.out.println(nome + " - " + matricula); 
 } 
 rs.close(); 
 stm.close(); 
 conexao.close(); 
 
public List<aluno> getListaAlunos() throws SQLException { 
 String sql = "SELECT * FROM alunos" 
 PreparedStatement stm = this.conexao.prepareStatement(sql); 
 ResultSet rs = stm.executeQuery(); 
 List<Aluno> alunos = new ArrayList<Aluno>(); 
 while (rs.next()) { 
 // criando o objeto Aluno 
 Aluno aluno = new Aluno(); 
 aluno.setMatricula(rs.getInt("matricula")); 
 aluno.setNome(rs.getString("nome")); 
 // adicionando o objeto à lista 
 alunos.add(aluno); 
 } 
 rs.close(); 
 stm.close(); 
 return alunos; 
} 
 
49
Métodos para alteração e remoção de registros
Nos métodos que apresentaremos a seguir também vamos utilizar a interface 
“preparedStatement” para executar os códigos SQL de alteração (“update”) e remo-
ção (“delete”). O método “ResultSet” será usado para receber os dados retornados de 
cada pesquisa.
A seguir é mostrado o método “modificaAluno”, que recebe um objeto do tipo “Aluno”, 
cujos valores serão alterados na tabela do banco de dados:
O código seguinte implementa a remoção de um registro de aluno com uma consulta 
baseada na chave primária “idaluno” a fim de executar o comando SQL para deleção do 
registro na tabela “Alunos”:
public List<aluno> getListaAlunos() throws SQLException { 
 String sql = "SELECT * FROM alunos" 
 PreparedStatement stm = this.conexao.prepareStatement(sql); 
 ResultSet rs = stm.executeQuery(); 
 List<Aluno> alunos = new ArrayList<Aluno>(); 
 while (rs.next()) { 
 // criando o objeto Aluno 
 Aluno aluno = new Aluno(); 
 aluno.setMatricula(rs.getInt("matricula")); 
 aluno.setNome(rs.getString("nome")); 
 // adicionando o objeto à lista 
 alunos.add(aluno); 
 } 
 rs.close(); 
 stm.close(); 
 return alunos; 
} 
 
 public void modificaAluno(Aluno aluno) throws SQLException{ 
 String sql = "UPDATE alunos SET matricula=?, nome=? WHERE id=?"; 
 PreparedStatement stm = conexao.prepareStatement(sql); 
 stm.setInt(1, aluno.getMatricula()); 
 stm.setString(2, aluno.getNome()); 
 stm.setInt(3, aluno.getIdaluno()); 
 stm.execute(); 
 stm.close(); 
} 
 
public void removeAluno(Aluno aluno) throws SQLException{ 
 String sql = "DELETE FROM alunos WHERE idaluno=?"; 
 PreparedStatement stm = conexao.prepareStatement(sql); 
 stm.setLong(1, aluno.getIdaluno()); 
 stm.execute(); 
 stm.close(); 
} 
 
50
Técnicas de acesso concorrente a bancos 
de dados cliente-servidor
Quando o acesso a um determinado item do banco de dados é realizado por apenas um 
usuário de cada vez, o funcionamento do Sistema Gerenciador do Banco de Dados é 
bem simples, sem a necessidade de métodos complexos de controle de acesso.
O problema começa quando existem acessos concorrentes a um mesmo item do banco 
de dados por mais de um usuário e de forma simultânea. Nestes casos, é necessário que 
o SGBD implemente algum tipo de controle de acesso para que cada transação concor-
rente seja atendida de forma justa e eficiente.
Para a implementação de um sistema computacional multiusuárioscom acesso concor-
rente às informações do banco de dados é necessário que o SGBD controle a execução 
das transações de cada usuário. Se houver algum problema ou falha em uma transação, 
seus efeitos deverão ser revertidos (“rollout”) para manter a integridade e a consistência 
do banco de dados. 
O que é uma transação em um banco de dados?
É qualquer conjunto de operações de acesso a uma base de dados, formando uma uni-
dade lógica de processamento. Pode incluir uma ou mais operações de acesso, criação, 
consulta, atualização ou remoção de itens em uma base de dados.
Transações concorrentes em bancos de dados
Quando diferentes usuários tentam acessar um mesmo item de base de dados de forma 
concorrente é necessário que o sistema computacional realize um controle de acesso 
entre essas transações. 
O Sistema Gerenciador de Banco de Dados – SGBD deve garantir que todas as operações 
completadas com sucesso em uma transação sejam gravadas de forma permanente no 
banco de dados. Por outro lado, se houver alguma falha durante a execução de uma 
transação, ela não deverá alterar o banco de dados ou outras transações concorrentes.
Existem várias técnicas de controle de concorrência para garantir que não haja interfe-
rência e se mantenha o isolamento entre as transações concorrentes na base de dados. 
51
Algumas dessas técnicas, como controle por escalonamento e controle por bloqueio, 
serão mostradas neste tópico.
A finalização de uma transação pode ocorrer de duas formas:
• Committ Transaction: a transação terminou com sucesso e será gravada de for-
ma permanente na base de dados.
• Rollback Transaction: houve erro durante a transação e a base de dados deve 
retornar ao estado anterior à transação.
Dessa forma, para evitar falhas catastróficas na base de dados com perda de informa-
ções é necessário desenvolver planos de contingência. Conheça alguns:
• Verificação de falhas durante e após as transações.
• Procedimentos de restauração após as falhas (“abort”). 
• Retorno do histórico de transações (“rollback ”).
• Realização de backups de acordo com estratégias de armazenamento (periodici-
dade de backups totais, incrementais etc.). 
• Planos de recuperação e verificação de backups. 
Veja alguns exemplos de falhas que podem acontecer durante uma transação.
• Falha durante a execução da transação.
• Condições de exceção detectadas pela transação.
• Problemas de infraestrutura: queda de energia, rede, falhas de componentes 
de hardware.
• Erros humanos, sabotagem.
Exemplo
52
Figura: Estados de uma transação em banco de dados.
Fonte: Notas de aula do professor (2020).
Propriedades de uma transação 
Para conseguir gerenciar as transações de forma adequada é necessário entender suas 
propriedades conhecidas pelo acrônimo Acid (atomicidade, consistência, isolamento e 
durabilidade). Os métodos de controle de concorrência das transações e recuperação do 
SGBD devem utilizar essas propriedades para manter a integridade dos dados.
Vamos conhecer com mais detalhes cada uma delas.
 
1. Atomicidade
O conceito de atomicidade considera cada transação como uma unidade de proces-
samento individual, sem separações. A transação somente será considerada realizada 
quando todas as operações da unidade lógica de processamento forem executadas sem 
erros. Caso contrário, toda a transação deverá ser cancelada, retornando ao estado ante-
rior dos dados (“rollback”) para garantir a consistência e a integridade do banco. Apenas 
no caso de todas as operações serem executadas de forma adequada é que a transação 
será persistida no banco de dados (“commit”).
2. Consistência
A propriedade consistência considera que uma transação somente poderá ser efetivada 
no banco de dados quando todas as suas regras, condições e restrições predefinidas 
forem atendidas. Por exemplo, devem ser atendidas as regras de relacionamento por 
chaves estrangeiras e verificação de valores permitidos para campos restritos. Essa pro-
priedade garante a execução de uma transação sem a interferência de outras, mantendo 
a consistência do banco de dados. 
Transação ativa 
em execução
read, write,...
begin end
abort
abort
commit
rollback
Efetivação
parcial
Transação
efetivada
Operação
abortada
Falha
53
3. Isolamento
Devido à propriedade de isolamento, mesmo que existam transações concorrentes e si-
multâneas, cada uma delas deverá funcionar de modo independente. Durante a execução 
de uma transação, nenhuma outra transação concorrente poderá interferir no funciona-
mento da primeira. Essa propriedade também garante que os resultados parciais de uma 
transação em execução não possam ser acessados por outras transações concorrentes.
4. Durabilidade
A propriedade durabilidade garante que somente uma nova transação pode alterar os 
resultados de uma transação anterior que foram armazenados de forma permanente no 
banco de dados. Mesmo em caso de alguma falha no sistema, todas as operações de 
uma transação finalizada devem ser armazenadas no banco de dados.
Figura: Propriedades de uma Transação em banco de dados.
Fonte: Notas de aula do professor (2020).
É importante notar que o SGBD geralmente armazena um registro das transações exe-
cutadas pelo usuário (arquivo de “log”) para que essas ações possam ser desfeitas caso 
ocorra alguma falha. Esse arquivo de registros também pode ser usado para garantir a 
durabilidade. Assim, no caso de falhas no sistema antes da execução de alguma transa-
ção, o arquivo de “log” pode ser usado para restaurar (“rollback”) o estado do banco de 
dados quando o sistema for reiniciado.
Propriedades
de uma transação
ATOMICIDADE
CONSISTÊNCIA
ISOLAMENTO
DURABILIDADE
54
Técnicas de controle de concorrência
É comum que existam acessos simultâneos a um mesmo banco de dados em siste-
mas multiusuários. Dessa forma, é necessário que os SGBDs implementem técnicas de 
controle de concorrência entre as transações no banco de dados que estiverem sendo 
executadas de forma simultânea. O controle de concorrência é necessário para manter 
a integridade e a consistência das informações e pode ser utilizado para garantir as pro-
priedades Acid de uma transação.
As técnicas de controle de concorrência precisam detalhar todas as operações execu-
tadas no banco de dados entre o início e o fim de cada transação. Para que transações 
concorrentes mantenham a consistência e a integridade dos dados, é necessário ga-
rantir que a sequência de operações dessas transações tenha o mesmo resultado de 
outra transação qualquer que foi executada sem nenhuma concorrência. 
Este é o conceito da serialização, quando a ordem de execução das operações das tran-
sações concorrentes deve ser equivalente a uma transação sequencial sem concorrên-
cia. A serialização visa garantir que as transações concorrentes sejam executadas de 
forma adequada e que o estado final do banco de dados mantenha sua consistência.
Controle por escalonamento (“scheduler”)
Este método de controle de concorrência utiliza um escalonador (“Scheduler”), que visa 
ordenar de forma sequencial as ações que seriam executadas por uma ou mais transa-
ções em um banco dados. 
 
• Escalonamento serial: as transações concorrentes são executadas no banco de 
dados de forma sequencial, isto é, uma após a outra.
• Escalonamento não serial: transações executadas de forma simultânea.
- Escalonamento serializável: as ações de transações concorrentes simultâ-
neas podem ser executadas de forma serial ou sequencial, atingindo o mesmo 
resultado final.
- Escalonamento não serializável: o resultado da execução das transações de 
forma concorrente é diferente da execução serial. Neste caso, não há garantia de 
que o estado final do banco de dados seja consistente.
55
Figura: Tipos de Escalonamento.
Fonte: Notas de aula do professor (2020).
Controle por bloqueios
A implementação de bloqueios sobre elementos do banco de dados é uma técnica para 
evitar comportamento não serializável das transações. As técnicas de bloqueio para 
controle de concorrênciasão baseadas em mecanismos que permitem a uma transação 
impedir que outras acessem ou atualizem registros do banco de dados. Dessa forma, é 
possível evitar problemas de concorrência e inconsistência nos dados.
O bloqueio pode ser implementado por meio de uma variável que fica atrelada ao item de 
dados envolvido na transação que está sendo realizada. Esse método de bloqueio pode 
ser implementado de forma binária (“booleana”) com dois estados possíveis determina-
dos pela variável: 
• Estado “bloqueado” com valor “1” ou “True”. 
• Estado “desbloqueado” com valor “0” ou “False”. 
Assim, se o item do banco de dados for acessado por alguma transação, o item estará 
bloqueado, pois a variável possuirá valor “1” (“True”). Caso contrário, se o item estiver 
desbloqueado, terá valor “0” ou “False”.
Normalmente, são usadas as operações “lock” e “unlock” para o bloqueio binário. A ope-
ração “lock” configura a variável de bloqueio (“True”) quando o item de dados está sendo 
acessado por alguma transação. Logo que a transação encerra a utilização do item, é lan-
çada a operação “unlock” para “resetar” a variável (“False”), e o item já estará desbloqueado.
Serializável Não Serializável
Serial Não Serial
Escalonamento
56
Existem duas formas de bloquear os dados:
• Bloqueio Compartilhado: nesse tipo de bloqueio, somente quando a transação 
possui operações de apenas leitura, outras transações concorrentes podem aces-
sar o mesmo dado. Se a transação possuir operações de gravação, não poderá 
realizar bloqueio compartilhado.
• Bloqueio Exclusivo: para esse tipo de bloqueio, o item do banco fica reservado 
para a operação que compõe a transação. Assim, outras transações concorrentes 
não poderão acessar o item do banco de dados que está sendo utilizado. Geral-
mente, se um item do banco está sofrendo uma operação de gravação, a transação 
corrente deve receber um bloqueio exclusivo para evitar que outras transações si-
multâneas causem falhas ou interferências no item.
É comum que uma transação mantenha o bloqueio ao item durante todo o tempo em 
que estiver realizando o acesso ao banco de dados. Em alguns casos, o desbloqueio 
imediato após terminar um acesso ao item do banco não é recomendado, uma vez que 
pode prejudicar o processo de serialização das transações concorrentes.
Bloqueio em duas fases
Esse tipo de bloqueio pode ser usado para manter um escalonamento de forma serial. 
Para isso, antes de poder liberar qualquer bloqueio, cada transação deve primeiro realizar 
todos os seus bloqueios. Dessa forma, uma transação não pode liberar o bloqueio de um 
item e em seguida realizar bloqueio de outro. 
O bloqueio em duas fases é composto pelas seguintes fases: 
• Fase de crescimento, em que todos os bloqueios necessários são realizados.
• Fase de encolhimento, em que há a liberação dos bloqueios.
Existe uma variante dessa técnica de bloqueio em duas fases denominada “Strict”, em 
que a fase de encolhimento é iniciada apenas quando toda a transação termina. A van-
tagem da técnica “Strict” é que uma transação sempre lê valores escritos por uma outra 
transação já executada e finalizada. Por exemplo, se houve necessidade de recuperação 
de dados (“rollback”) durante uma transação, não haverá inconsistência de dados propa-
gando-se para uma transação concorrente. 
57
Problemas de concorrência entre transações
Caso as propriedades Acid não sejam respeitadas pelos SGBDs, podem acontecer al-
guns problemas durante a execução de transações concorrentes. Vejamos alguns deles:
 
• Atualização perdida (“lost update”)
Esse problema pode ocorrer quando duas transações concorrentes T1 e T2 leem os 
mesmos dados do banco e tentam atualizar os dados com base no que foi lido antes que 
uma das atualizações seja realizada com sucesso.
Figura: Exemplo de atualização perdida.
Tempo T1 T2 Descrição
t0 Início: registro A = 10
t1 read (A,x) leitura do registro A na variável x
t2 read (A, y) leitura do registro A na variável y
t3 x = x + 1 x = 11
t4 y = y + 5 y = 15
t5 write (A, x) escrita da variável x = 11 no registro A
t6 write (A, y) escrita da variável y = 15 no registro A
Resultado: A = 15 (atualização da transação T1 é perdida devido à T2).
Fonte: Notas de aula do professor (2020).
• Leitura suja (“dirty read”)
Ocorre quando uma transação está tentando atualizar um item do banco de dados e ou-
tra transação concorrente lê esse item que ainda não foi atualizado.
58
Figura: Exemplo de leitura suja.
Tempo T1 T2 Descrição
t0 Início: registro A = 10
t1 read (A, x) leitura do registro A na variável x
t2 x = x + 1 x = 10 + 1 = 11
t3 write (A, x) escrita da variável x = 11 no registro A
t4 read (A, y) leitura do registro A = 11 na variável y
t5 rollback T1 ocorreu uma falha. desfaz T1 e retoma a = 10
t6 y = y + 5 y = 11 + 5 = 16
t7 write (A, y) escrita da variável y no registro A
Resultado: A = 16 (T2 fez uma leitura “suja” do registro A porque depois foi alterado).
Fonte: Notas de aula do professor (2020).
• Leitura fantasma (“ghost read”)
Uma transação está realizando uma segunda consulta consecutiva ao banco, que re-
torna um resultado que atende a uma certa condição de procura. O problema é que o 
segundo resultado é diferente da primeira consulta, pois no intervalo entre as consultas 
houve a execução de uma transação concorrente. 
Figura: Exemplo de leitura fantasma.
Tempo T1 T2 Descrição
t0 Início: tabela A com 2 registros (a, b)
t1 select * from A Retorna 2 registros
t2 insert intoA valeus (“c”) tabela A com 3 registros (a, b, c)
t3 select * from A Retorna 3 registros
Resultado: Leituras repetidas de T1 na tabela A retornam diferentes registros.
Fonte: Notas de aula do professor (2020).
59
Problemas com as técnicas de bloqueio 
Sempre haverá necessidade de bloqueio e desbloqueio dos itens de dados com acesso 
compartilhado, mas existem algumas situações em que a combinação desses estados 
pode gerar problemas no banco dados. Veremos alguns desses problemas a seguir:
• Impasse (“deadlock”) 
O impasse (“deadlock”) pode ocorrer se não for realizado o desbloqueio do item do banco 
antes da solicitação de um bloqueio a outro item. Por exemplo, existem duas transações 
concorrentes T1 e T2. A primeira transação, T1, está esperando por um item de dados 
que está bloqueado pela transação T2. Simultaneamente, a transação T2 está esperando 
por outro item, que está bloqueado por T1. Neste caso, as duas transações ficam conge-
ladas, esperando indefinidamente que algum dos itens bloqueados seja liberado. Como 
isso não ocorre, as duas transações não conseguem ser concluídas. 
Existem algumas formas de tratar o problema de impasse. Por exemplo, alguns sistemas 
conseguem detectar um “deadlock” e podem escolher uma transação do conjunto para 
abortar a operação (“rollback”), eliminando o ciclo de espera. O problema de “deadlock” 
pode ser resolvido pela técnica de controle por rótulo de tempo, que será vista a seguir.
Figura: Deadlock.
Transação T1 Transação T2
Tabela A Tabela B
Fonte: Notas de aula do professor (2020).
T1 quer acesso em B mas 
T2 está bloqueando B
T2 quer acesso em A mas 
T1 está bloqueando A
Deadlock
60
• Estagnação (“starvation”) 
O problema de estagnação pode ocorrer quando uma transação de alteração a um de-
terminado item não consegue ser executada devido a outras transações concorrentes de 
leitura ao mesmo item do banco de dados.
Por exemplo, uma transação de leitura de um item está sendo executada e faz uma re-
quisição de bloqueio compartilhado. Se uma transação concorrente de alteração tentar 
acesso ao mesmo item não conseguirá obter a requisição de bloqueio exclusivo e ficará 
aguardando o término da primeira transação.
Se outras transações concorrentes de leitura ao mesmo item do banco chegarem ao 
SGBD e não houver um escalonador com controle de tempo, a transação de alteração 
nunca será executada, pois não conseguirá implementar o bloqueio exclusivo. Como as 
transações de leitura mantêm o bloqueio compartilhado do item,a transação de altera-
ção fica em “estagnação”, pois não consegue obter o acesso e fica esperando a liberação 
indefinidamente. 
Controle por rótulo de tempo (“TimeStamp”)
Nesse tipo de controle de concorrência, para cada transação iniciada é associado 
um rótulo de tempo (“TimeStamp”) fixo e exclusivo. Assim, antes que uma transação 
inicie sua execução, o SGBD fornecerá um rótulo de tempo exclusivo para identificar 
essa transação.
Por exemplo, temos duas transações, T1 e T2; a transação T1 iniciou-se no tempo “n”, e
a transação T2 teve início no tempo “n+1”. Logo, a transação T1 será executada primeiro
do que a transação T2, pois seu tempo de início é mais antigo.
Existem duas formas para implementação desse controle, usando como rótulo de tempo:
• Hora do relógio do sistema computacional: neste caso, o horário de início da 
transação será igual à hora em que a transação entrar no sistema.
• Contador lógico incrementado sempre que houver um novo “TimeStamp”: o 
rótulo de tempo da transação é igual ao valor do contador quando a transação entra 
no sistema.
61
Esse controle precisa garantir que a ordem em que o item do banco de dados está sendo 
acessado não viola a ordem do “TimeStamp”. Dessa forma, o controle associa a cada 
item “X” do banco de dados dois valores de rótulo de tempo (“TimeStamp” — TS):
• read_TS(X) - “TimeStamp” de leitura do item “X”.
• write_TS(X) - “TimeStamp” de gravação do item “X”.
Esses rótulos de tempo devem ser atualizados sempre que uma nova instrução de leitura 
ou escrita é executada. A todo momento em que uma transação de leitura ou escrita é 
desfeita pelo esquema de controle de concorrência, essa transação é reiniciada com um 
novo “TimeStamp”. 
Tal controle de concorrência garante que, se houver operações de leitura ou escrita em 
conflito, essas operações serão executadas por ordem de “TimeStamp”.
O controle de “TimeStamp” pode prevenir o problema de impasse (“deadlock”) visto an-
teriormente. Caso duas transações estejam envolvidas em um “deadlock”, a transação 
mais nova será abortada pela transação mais antiga (a que entrou primeiro). 
Nesse tipo de controle também existe a possibilidade de paralisação de transações lon-
gas, caso uma série de transações curtas causem o reinício da transação longa. Nesse 
caso, as transações curtas podem ser suspensas temporariamente para permitir que a 
transação longa seja concluída.
Como é possível ver, existem várias técnicas que os SGBDs devem implementar para 
evitar os problemas de acesso concorrente e manter a integridade dos bancos de da-
dos multiusuários. 
62
Tratamento de erros em bancos de dados
Neste tópico abordaremos as diferentes formas de tratamento de erros em aplicativos 
de bancos de dados e também como tratar, em Java, algumas situações. Conheça 
algumas delas: 
• Divisão por zero.
• Erro na conversão de tipos (ex.: converter uma string de letras em um número inteiro).
• Erro na abertura ou na transmissão de um arquivo.
• Erro de impressão.
• Acesso a um vetor com índice inválido.
• Erro de conexão a um banco de dados, entre outros.
Todas as situações listadas acima em Java são chamadas de exceções e existe um me-
canismo específico para tratá-las, que chamamos de tratamento de exceções.
As exceções em Java estão organizadas em uma hierarquia de classes, como mostra a 
figura a seguir.
Figura: Hierarquia de classes em Java.
Fonte: Notas de aula do professor (2020).
63
Um “Error” pode ocorrer devido a problemas no sistema operacional, na Java Virtual 
Machine – JVM ou mesmo no hardware. Nesse caso, o melhor a fazer é deixar a JVM 
encerrar o programa.
A classe “Exception” é a classe-mãe de todas as exceções que nossos programas po-
dem tratar.
Ela está subdividida em dois ramos:
RuntimeException
Ocorrem devido a um erro de programação, como divisão por 
zero, índice inválido do vetor, acesso a objeto nulo etc. Também 
são chamadas de exceções não verificadas (unchecked).
Demais exceções
Ocorrem devido a um erro no programa causado por fatores 
externos, como erro na abertura de um arquivo, erro na impres-
são, erro na conexão a um banco de dados etc. Também são 
chamadas de exceções verificadas (checked).
Quando executamos o programa abaixo:
Podemos observar a seguinte mensagem:
 public class DividePorZero { 
 public static void main(String args[]) { 
 System.out.println(3/0); 
 System.out.println("imprime"); 
 } 
 } 
 
 Exception in thread "main" java.lang.ArithmeticException: / by zero 
 at DividePorZero.main(DividePorZero.java:3) 
 
64
Como o nosso programa não está tratando dessa exceção (divisão por zero), o tratador 
padrão do Java executa as seguintes tarefas:
• Imprime o nome da exceção e a mensagem de erro.
• Imprime a pilha de execução (sequência de chamadas dos métodos).
• Termina o programa.
O tratamento de exceções é um mecanismo que permite que o programa defina como 
as situações inesperadas serão tratadas.
Existem três comandos relacionados ao tratamento de exceções. São eles:
1. Blocos try...catch...finally.
2. Comando throws.
3. Comando throw.
E alguns métodos que a classe Exception pode implementar: 
Exception(String 
mensagemErro) getMessage() printStackTrace()
Construtor que permite 
criar uma exceção e 
armazenar nesse objeto 
uma mensagem de erro.
Retorna a mensagem de 
erro armazenada 
na exceção.
Imprime a pilha de execu-
ção no mesmo formato 
da JVM.
É possível tratar várias exceções associando vários catchs ao mesmo try. Nesse caso, a 
ordem dos tratadores é importante: eles devem estar ordenados das subclasses para 
a superclasse.
try { 
 // Código a ser tratado 
} catch (ArithmeticException e3){ //Primeiro o catch da exceção mais específica. 
 System.out.printf("Erro de aritmetica: %s\n",e3.getMessage()); 
} catch(IOException e2) { 
 System.out.printf("Erro de E/S: %s\n", e2.getMessage()); 
} catch(Exception e1) { //Por último o catch da exceção mais geral. 
 System.out.printf("Erro desconhecido: %s\n", e1.getMessage()); 
} 
 
65
Quando ocorre uma exceção o método cria um objeto do tipo “Exception” e o “dispara” 
(throw) para a JVM. O objeto “Exception” criado contém todas as informações sobre o 
erro: seu tipo, o local onde ocorreu, uma mensagem de descrição, a pilha de chamadas, 
entre outros.
Em seguida a JVM procura um bloco “try...catch” para tratar a exceção no método que 
a gerou. 
• Encontrou: desvia a execução para o bloco “catch”. 
• Não encontrou: procura outro bloco “try...catch” para tratar a exceção na pilha de 
execução, ou seja, nos métodos que chamaram o método que gerou a exceção. 
- Encontrou: desvia a execução para o primeiro “catch” que encontrar.
- Não encontrou: nenhum tratador na pilha de execução, desvia para o tratador 
padrão da JVM, que interrompe a execução do programa.
O tratamento de exceções também pode ser implementado por um bloco 
“try…catch...finally”. O bloco “finally” indica um trecho de código que sempre será execu-
tado se uma exceção ocorrer ou não. O bloco “finally” é muito utilizado quando é neces-
sário liberar algum recurso importante do sistema, como uma conexão com o banco de 
dados, um arquivo de dados ou memória. Em seguida, veremos exemplos de código com 
uso do bloco “finally” para este objetivo.
Figura: Bloco “try … catch … finally”.
Fonte: Notas de aula do professor (2020).
66
As exceções do Java são classificadas como “checked” ou “unchecked”. Para as exce-
ções “checked” (verificadas), o Java nos obriga a usar uma das soluções a seguir. 
1. Tratar as exceções no método em que elas podem ocorrer, implementando o blo-
co “try...catch” visto anteriormente.
2. Utilizar o comando “throws” para avisar que estamos cientes de que aquela exce-
ção pode ocorrer, mas não desejamos tratá-la.
3. Utilizar o comando “throw” para disparar uma exceção customizada, ou seja, que 
nós mesmos criamos. 
- Neste caso, criamos um objeto da classe “Exception” ou de uma de suas subclas-
ses com o operador

Continue navegando