• Nenhum resultado encontrado

Programação para Internet II

N/A
N/A
Protected

Academic year: 2021

Share "Programação para Internet II"

Copied!
38
0
0

Texto

(1)

Programação para Internet II

Aulas 07 e 08

Fernando F. Costa

professor.fimes.edu.br/fernando

nando@fimes.edu.br

(2)

Como tratar de grandes conjuntos de

resultados

Quando temos uma grande quantidade de registros a ser

exibida para um usuário, provavelmente não vamos querer

que todos eles sejam carregados e exibidos de uma única

vez.

Uma alternativa seria filtrar a consulta para reduzir os dados a

serem exibidos. Contudo paginar os resultados em pequenas

quantidades também pode ser uma boa solução.

(3)

A interface RowSet

Uma boa alternativa para trabalhar com a paginação de

resultados é fazer uso da interface RowSet que foi introduzida

na especificação JDBC 2.0 para definir um meio padrão para

acessar dados armazenados em cache através de um

componente JavaBeans ou através de sistemas distribuídos.

(4)

O Bean CachedRowSet

Portanto, para tratar consultas que são maiores que uma tela

inteira e não tão grande para serem verdadeiras devoradoras

de memória, o Bean CachedRowSet se mostra como boa

opção. Ele faz parte da interface RowSet contida na

implementação JDBC 2.0 fornecida pela Sun.

(5)

O Bean CachedRowSet

Diferente de ResultSet, CachedRowSet é uma conexão offline

que armazena em cache todas as linhas de sua consulta no

objeto. Nenhuma conexão ativa é necessária porque todos os

dados foram pegos do banco de dados. Para fazer uso deste

Bean, basta configurar suas propriedades de acesso ao

Banco, sua consulta SQL e pronto. A partir deste ponto é só

navegar pelos resultados obtidos.

(6)

Exemplo Prático

Vejamos como trabalhar com a paginação de resultados em

JSP utilizando o Bean CachedRowSet. Para isto, crie um novo

projeto web chamado Conferencia.

No MySQL crie uma base de dados chamada conf para

ilustrar nosso exemplo.

(7)

Exemplo Prático

No MySQL, digite os seguintes comandos para criar o banco e

as tabelas.

create database conf; create table conference(

id integer not null auto_increment, cidade varchar(80),

aeroporto char(3), assentos integer, primary key (id) );

create table shuttles(

id integer not null auto_increment, aeroporto char(3),

hora time,

assentos integer, primary key (id) );

(8)

Exemplo Prático

Digite os seguintes comandos para preencher as tabelas criadas:

INSERT INTO conference (cidade, aeroporto, assentos) VALUES ('Austin', 'AUS', 45);

INSERT INTO conference (cidade, aeroporto, assentos) VALUES ('Las Angeles', 'LAX', 37);

INSERT INTO conference (cidade, aeroporto, assentos) VALUES ('New York', 'JFK', 0);

INSERT INTO conference (cidade, aeroporto, assentos) VALUES ('Houston', 'IAH', 11);

INSERT INTO conference (cidade, aeroporto, assentos) VALUES ('Boston', 'BOS', 0);

INSERT INTO conference (cidade, aeroporto, assentos) VALUES ('San Francisco', 'SFO', 12);

INSERT INTO shuttles (aeroporto, hora, assentos) VALUES ('AUS', '9:40', 10); INSERT INTO shuttles (aeroporto, hora, assentos) VALUES ('AUS', '12:00', 12); INSERT INTO shuttles (aeroporto, hora, assentos) VALUES ('AUS', '14:15', 0); INSERT INTO shuttles (aeroporto, hora, assentos) VALUES ('LAX', '12:15', 10); INSERT INTO shuttles (aeroporto, hora, assentos) VALUES ('LAX', '16:35', 10); INSERT INTO shuttles (aeroporto, hora, assentos) VALUES ('IAH', '9:30', 0); INSERT INTO shuttles (aeroporto, hora, assentos) VALUES ('JFK', '12:15', 10); INSERT INTO shuttles (aeroporto, hora, assentos) VALUES ('BOS', '16:35', 10); INSERT INTO shuttles (aeroporto, hora, assentos) VALUES ('SFO', '9:30', 10);

(9)

Exemplo Prático

Concluído a parte de criação e preenchimento do banco, é

hora de criarmos nosso arquivo JSP que fará a paginação

dos resultados obtidos.

No exemplo a seguir, os resultados serão paginados de 5

em 5 registros. Você pode definir a quantidade que desejar,

basta definir no loop quantos registros serão exibidos por

vez.

(10)

Exemplo Prático

<%@page import="java.sql.*" %> <%@page import="javax.sql.*" %>

<%@page import="com.sun.rowset.*" %>

<jsp:useBean id="crs" class="com.sun.rowset.CachedRowSetImpl" scope="session"> <% try { Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException e) { System.err.println("Error" + e); } %>

<jsp:setProperty name="crs" property="url" value="jdbc:mysql://localhost:3306/conf" />

<jsp:setProperty name="crs" property="username" value="root" />

<jsp:setProperty name="crs" property="password" value="adminadmin" />

<jsp:setProperty name="crs" property="command" value="select * from shuttles order by id" />

<% try { crs.execute(); }

catch (SQLException e) { out.println("SQL Error: " + e); } %>

</jsp:useBean>

(11)

Exemplo Prático

<html> <body> <center>

<h2>Resultados da Consulta em Cache</h2> <P> <table border="2"> <tr bgcolor="tan"> <th>ID</th><th>Aeroporto</th><th>Hora de Partida </th><th>Assentos</th></tr> <% try { if ("first".equals(request.getParameter("action"))) crs.beforeFirst();

for (int i=0; (i < 5) && crs.next(); i++) { %> <tr> <td><%= crs.getString("id") %></td> <td><%= crs.getString("aeroporto") %></td> <td><%= crs.getString("hora") %></td> <td><%= crs.getString("assentos") %></td> </tr> <% } %> </table>

CachedResults.jsp (parte 2/3)

(12)

Exemplo Prático

<br>

<% if (crs.isAfterLast()) { crs.beforeFirst(); %> Fim dos registros<br><br> <% } }

catch (SQLException e) { out.println("SQL Error" + e); } %>

<a href="<%= HttpUtils.getRequestURL(request) %>?action=first"> [In&iacute;cio]</a>&nbsp;

<a href="<%= HttpUtils.getRequestURL(request) %>?action=next"> [Pr&oacute;ximo]</a>&nbsp;

</center> </body> </html>

(13)
(14)

Trabalho em Grupo (3 pessoas)

Valor: 2,0 pontos

Data apresentação: 11/04/2011

Descrição: Utilizando os conceitos já apresentados, e enfatizando o conceito de Beans e

Rowset, crie uma aplicação web para fazer o controle de produtos de uma empresa. A aplicação web deve conter uma parte administrativa na qual deverá ser possível:

● Cadastrar, Alterar e Remover um produto

Na parte de usuário, deve existir apenas uma lista dos produtos cadastrados com as respectivas informações:

● Nome (String) ● Preço (Double)

● Quantidade (Integer)

Quando o usuário clicar em comprar um produto, ele deve informar a quantidade. Após confirmar a quantidade, a aplicação deve remover esta quantidade do estoque.

Observações:

● A área administrativa só pode ser acessada mediante login.

● Não deve ser permitido a compra de uma quantidade superior a quantidade em estoque.

● Se um produto estiver esgotado (quantidade = 0) deve aparecer a mensagem esgotado no

(15)

Como manter conexões persistentes

A conexão com o BD normalmente é a parte mais lenta de

uma aplicação web. Contudo, manter várias conexões em

aberto pode ser inviável, uma vez que o banco de dados pode

suportar uma quantidade limitada de conexões.

Desta forma, uma boa alternativa para solucionar este

impasse é fazer uso dos Pools de Conexões que são

implementados pelo driver do banco de dados, ou por classes

de Pool de Conexões.

(16)

Pool de Conexões

Os pools de conexões mantêm um número fixo de conexões

ativas e as empresta quando solicitado pelas suas páginas

JSP ou Beans.

Logo se tornam uma boa alternativa entre ter muitas conexões

abertas e pagar o preço por conexões e desconexões

frequentes.

(17)

Pool de Conexões

A seguir veremos o código que cria um Bean responsável por

encapsular uma conexão de banco de dados. Isto permite

isolar nossas páginas JSP dos detalhes de conexão com o

BD, assim como permite manter nossa conexão através de

diversas páginas ao armazená-la na sessão. Desta maneira

não precisamos sempre nos reconectar no banco de dados.

(18)

public class ConnectionBean implements HttpSessionBindingListener { private Connection connection;

private Statement statement;

private static final String driver="com.mysql.jdbc.Driver";

private static final String dbURL="jdbc:mysql://localhost:3306/conf";

private static final String login="root";

private static final String password="adminadmin"; public ConnectionBean() { try { Class.forName(driver); connection=DriverManager.getConnection(dbURL,login,password); statement=connection.createStatement(); } catch (ClassNotFoundException e) {

System.err.println("ConnectionBean: driver unavailable"); connection = null;

}

catch (SQLException e) {

System.err.println("ConnectionBean: driver not loaded"); connection = null;

} }

(19)

public void valueBound(HttpSessionBindingEvent event) {

System.err.println("ConnectionBean: in the valueBound method"); try {

if (connection == null || connection.isClosed()) { connection =

DriverManager.getConnection(dbURL,login,password); statement = connection.createStatement();

} }

catch (SQLException e) { connection = null; } }

public void valueUnbound(HttpSessionBindingEvent event) { try { connection.close(); } catch (SQLException e) { } finally { connection = null; } }

protected void finalize() { try { connection.close(); } catch (SQLException e) { } } }

ConnectionBean

(20)

Processamento de Transações

As operações efetuadas em um BD nem sempre são

atômicas, ou seja, na maioria das vezes ela envolve duas ou

mais operações que precisam acontecer com sucesso para

garantir a integridade do banco de dados. Ex: transação

bancária.

(21)

Processamento de Transações

Os Bancos de Dados fornecem um mecanismo conhecido

como transações para tratar deste assunto. Em JSP devemos

efetuar um commit() no objeto Connection para concluir uma

operação que ocorreu sem erros, ou efetuar um rollback() do

objeto Connection para retornar o banco ao estado em que ele

se encontrava no inicio da transação.

(22)

Processamento de Transações

Como padrão o JDBC assume que cada instrução SQL é uma

transação, e portanto, efetua um autocommit a cada instrução

que é emitida. Para que esse controle seja feito

“manualmente”, devemos desativar o recurso autocommit. A

seguir temos um exemplo desta situação em uma operação

de transação bancária entre as contas de Bob e Sue.

(23)

Desativando o recurso autocommit

connection.setAutoCommit(false); try {

Statement st = connection.createStatement(); st.executeUpdate(

"UPDATE ACCTS SET BALANCE=(BALANCE-100) WHERE OWNER = "Bob"); st.executeUpdate(

"UPDATE ACCTS SET BALANCE=(BALANCE + 100) WHERE OWNER = "Sue"); connection.commit(); } catch (SQLException e) { connection.rollback(); } finally { connection.setAutoCommit(true); }

Observação:

(24)

Exemplo Prático

A seguir criaremos um exemplo para trabalhar com os

assuntos tratados na aula de hoje. O objetivo do exemplo que

será criado é permitir que sejam feitas reservas de vagas em

conferências de computação que ocorrerão em todo o mundo.

Contudo, o sistema deve garantir que além de reservar uma

vaga na conferência, também seja possível reservar uma vaga

na ponte aérea com destino a conferência selecionada.

(25)

Exemplo Prático

Neste exemplo utilizaremos o projeto Conferencia criado

anteriormente, juntamente com a base de dados conf que foi

criada.

(26)

import java.sql.*;

import javax.servlet.http.*;

public class ConnectionBean implements HttpSessionBindingListener { private Connection connection;

private Statement statement;

private static final String driver="com.mysql.jdbc.Driver";

private static final String dbURL="jdbc:mysql://localhost:3307/conf";

private static final String login="root";

private static final String password="adminadmin"; public ConnectionBean() { try { Class.forName(driver); connection=DriverManager.getConnection(dbURL,login,password); statement=connection.createStatement(); } catch (ClassNotFoundException e) {

System.err.println("ConnectionBean: driver unavailable"); connection = null;

}

catch (SQLException e) {

System.err.println("ConnectionBean: driver not loaded"); connection = null;

} }

ConnectionBean.java (parte 1 de 3)

(27)

public Connection getConnection() { return connection;

}

public void commit() throws SQLException { connection.commit();

}

public void rollback() throws SQLException { connection.rollback();

}

public void setAutoCommit(boolean autoCommit) throws SQLException {

connection.setAutoCommit(autoCommit ); }

public void valueBound(HttpSessionBindingEvent event) {

System.err.println("ConnectionBean: in the valueBound method"); try {

if (connection == null || connection.isClosed()) { connection =

DriverManager.getConnection(dbURL,login,password); statement = connection.createStatement();

} }

catch (SQLException e) { connection = null; } }

ConnectionBean.java (parte 2 de 3)

(28)

public ResultSet executeQuery(String sql) throws SQLException { return statement.executeQuery(sql);

}

public int executeUpdate(String sql) throws SQLException { return statement.executeUpdate(sql);

}

public void valueUnbound(HttpSessionBindingEvent event) { try { connection.close(); } catch (SQLException e) { } finally { connection = null; } }

protected void finalize() { try { connection.close(); } catch (SQLException e) { } } }

ConnectionBean.java (parte 3 de 3)

Exemplo Prático

(29)

<%@page contentType="text/html" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>JSP Page</title> </head> <body> <center> <h1>Confer&ecirc;ncia Mundial de Computa&ccedil;&atilde;o</h1>

<a href="CachedResults.jsp" target="_self">Vagas Disponíveis</a><br><br>

<a href="conference.jsp" target="_self">Fazer minha inscri&ccedil;&atilde;o</a> </center> </body> </html>

index.jsp

Exemplo Prático

(30)

<%@page import="java.sql.*" errorPage="error.jsp" %> <jsp:useBean id="connection" class="com.taglib.wdjsp.databases.ConnectionBean" scope="session"/> <html> <body> <center>

<font size="+2" face="arial"><b>Confer&ecirc;ncia - Registros</b></font>

<form action="shuttle.jsp" method="post">

<table border=1 bgcolor="tan" width="50%" align="center"> <tr>

<td>

<table border="0" bgcolor="white" cellspacing=0 width="100%"> <tr bgcolor="tan">

<th>&nbsp;</th><th>Cidade</th><th>Vagas Restantes</th></tr> <tr><% String sql = "select * from conference";

ResultSet results = connection.executeQuery(sql); while (results.next()) {

if (results.getInt("assentos") > 0) { %>

<td>

<input type="radio" name="show" value="<%= results.getString("id") %>">

</td> <% }

conference.jsp (parte 1 de 2)

(31)

else { %> <td>&nbsp;</td> <% } %> <td><%= results.getString("cidade") %></td> <td align="center"><%= results.getString("assentos") %></td> </tr> <% } %> </table> </td> </tr> </table> <p>

<input type="submit" value="Proximo (Escolher Ponte Aerea)"> </form> </center> </body> </html>

conference.jsp (parte 2 de 2)

Exemplo Prático

(32)

<%@ page import="java.sql.*" errorPage="error.jsp" %> <jsp:useBean id="connection"

class="com.taglib.wdjsp.databases.ConnectionBean" scope="session"/> <%

String showID = request.getParameter("show"); connection.setAutoCommit(false);

String sql;

sql = "UPDATE conference set assentos=assentos-1 where id=" + showID; connection.executeUpdate(sql); %> <html> <body> <center>

<font size="+2" face="arial"><b>Reservar Ponte A&eacute;rea</b></font>

<form action="confirm.jsp" method="post">

<table border=1 bgcolor="tan" width="50%" align="center"> <tr><td>

<table border="0" bgcolor="white" cellspacing=0 width="100%"> <tr bgcolor="tan"><th>&nbsp;</th>

<th>Aeroporto</th><th>Hora</th><th>Lugares Vagos</th></tr>

shuttle.jsp (parte 1 de 2)

(33)

<tr> <%

sql = "SELECT s.* from shuttles s, conference c where c.id=" + showID + " and s.aeroporto = c.aeroporto";

ResultSet results = connection.executeQuery(sql); while (results.next()) {

if (results.getInt("assentos") > 0) { %>

<td>

<input type="radio" name="shuttle"

value="<%= results.getString("id") %>"> </td> <% } else { %> <td>&nbsp;</td> <% } %> <td><%= results.getString("aeroporto") %></td> <td><%= results.getTime("hora") %></td> <td align="center"><%= results.getString("assentos") %></td> </tr> <% } %> </table> </td></tr></table>

<input type="hidden" name="show" value="<%= showID %>"> <input type="submit" value="Proximo (Revisar Reservas)"> </form>

</center></body></html>

shuttle.jsp (parte 2 de 2)

(34)

<%@ page import="java.sql.*" errorPage="error.jsp" %> <jsp:useBean id="connection"

class="com.taglib.wdjsp.databases.ConnectionBean" scope="session"/> <%

String sql;

String shuttleID = request.getParameter("shuttle"); String showID = request.getParameter("show");

sql = "UPDATE shuttles set assentos=assentos-1 where id=" + shuttleID;

connection.executeUpdate(sql);

sql = "SELECT c.cidade, c.aeroporto, s.hora from conference c, " + "shuttles s where c.id=" + showID + " and s.id=" + shuttleID; ResultSet results = connection.executeQuery(sql);

results.next(); %>

<html><body><center>

<font size="+2" face="arial"><B>Confirma&ccedil;&atilde;o de Reservas</b></font>

<form action="finish.jsp" method=post>

<table border=1 bgcolor="tan" width="50%" align="center"> <tr><td>

confirm.jsp (parte 1 de 2)

(35)

<table border="0" bgcolor="white" cellspacing=0 width="100%"> <tr bgcolor="tan"><th>Resumo</th></tr>

<tr><td>

Reserva requisitada para a confer&ecirc;ncia na cidade de

<b><%= results.getString("cidade") %></b>,

com ponte a&eacute;rea partindo do aeroporto de

<b><%= results.getString("aeroporto") %></b> &agrave;s

<b><%= results.getTime("hora") %></b>.

<p>

Para confirmar suas reservas, selecione Confirmar Reservas.

</td></tr>

</table>

</td></tr></table>

<p>

<input type="submit" name="commit" value="Confirmar Reservas">

<input type="submit" name="rollback" value="Cancelar Reservas">

</body>

</html>

confirm.jsp (parte 2 de 2)

(36)

<%@ page import="java.sql.*,com.taglib.wdjsp.databases.*" errorPage="error.jsp" %> <html><body> <% ConnectionBean connection = (ConnectionBean)session.getAttribute("connection"); if (request.getParameter("commit") != null) connection.commit(); else connection.rollback(); session.removeAttribute("connection"); %> <center> <% if (request.getParameter("commit") != null) { %>

<font size="+2" face="arial"><b>Confirma&ccedil;&atilde;o de Reservas</b></font>

<p>

Sua reserva foi confirmada, obrigado... <% } else { %>

<font size="+2" face="arial"><b>Cancelamento de Reservas</b></font> <p> Suas reservas foram canceladas.

<% } %>

<a href="conference.jsp">Outra Reserva</a> </body></html>

finish.jsp

(37)

<%@ page import="java.sql.*,com.taglib.wdjsp.databases.*" isErrorPage="true" %>

<html> <body> <%

if (exception instanceof SQLException) { try { ConnectionBean connection = (ConnectionBean)session.getAttribute("connection"); connection.getConnection().rollback(); session.removeAttribute("connection"); } catch (SQLException e) { } } %> <center>

<font size="+2" face="arial"><b>Erro na Aplica&ccedil;&atilde;</b></font>

<p>

Um erro ocorreu: <tt><%= exception %></tt> <p>

<a href="conference.jsp">Outra Reserva</a> </center></body></html>

error.jsp

(38)

Referências

Documentos relacionados

O termo extrusão do núcleo pulposo aguda e não compressiva (Enpanc) é usado aqui, pois descreve as principais características da doença e ajuda a

Principais mudanças na PNAB 2017  Estratégia Saúde da Família/Equipe de Atenção Básica  Agentes Comunitários de Saúde  Integração da AB e Vigilância 

A assistência da equipe de enfermagem para a pessoa portadora de Diabetes Mellitus deve ser desenvolvida para um processo de educação em saúde que contribua para que a

Por vezes, o localizador necessita de alterar não só o texto como também possíveis imagens ou a forma como estas são apresentadas, sendo o exemplo mais óbvio o caso de

É perceptível, desta forma, o constante aumento do aprofundamento dos personagens: os “príncipes” têm agora não só nome e falas, mas personalidades bem desenvolvidas,

Devido às características do Sistema Brasileiro, o Planejamento da Operação de Sistemas Hidrotérmicos de Potência (POSHP) pode ser clas- sicado como um problema de

Deste modo, o adequado zoneamento e sua observância são fundamentais para a conciliação da preservação ou conservação de espécies, hábitats e paisagens dentre outras e

Estas tiveram (e têm) predominância do minifúndio, cidades de pequeno e médio porte, forte presença de imigrantes europeus, pequena propriedade mercantil, mão de obra