Beruflich Dokumente
Kultur Dokumente
Programao WEB
Lio 5
Conexo com Banco de Dados: SQL e JDBC
JEDITM
Sistemas Operacionais Suportados NetBeans IDE 5.5 para os seguintes sistemas operacionais: Microsoft Windows XP Profissional SP2 ou superior Mac OS X 10.4.5 ou superior Red Hat Fedora Core 3 Solaris 10 Operating System (SPARC e x86/x64 Platform Edition) NetBeans Enterprise Pack, poder ser executado nas seguintes plataformas: Microsoft Windows 2000 Profissional SP4 Solaris 8 OS (SPARC e x86/x64 Platform Edition) e Solaris 9 OS (SPARC e x86/x64 Platform Edition) Vrias outras distribuies Linux Configurao Mnima de Hardware Nota: IDE NetBeans com resoluo de tela em 1024x768 pixel Sistema Operacional Microsoft Windows Linux Solaris OS (SPARC) Solaris OS (x86/x64 Platform Edition) Mac OS X Processador 500 MHz Intel Pentium III workstation ou equivalente 500 MHz Intel Pentium III workstation ou equivalente UltraSPARC II 450 MHz AMD Opteron 100 Srie 1.8 GHz PowerPC G4 Memria 512 MB 512 MB 512 MB 512 MB 512 MB HD Livre 850 MB 450 MB 450 MB 450 MB 450 MB
Configurao Recomendada de Hardware Sistema Operacional Microsoft Windows Linux Solaris OS (SPARC) Solaris OS (x86/x64 Platform Edition) Mac OS X Processador 1.4 GHz Intel Pentium III workstation ou equivalente 1.4 GHz Intel Pentium III workstation ou equivalente UltraSPARC IIIi 1 GHz AMD Opteron 100 Series 1.8 GHz PowerPC G5 Memria 1 GB 1 GB 1 GB 1 GB 1 GB HD Livre 1 GB 850 MB 850 MB 850 MB 850 MB
Requerimentos de Software NetBeans Enterprise Pack 5.5 executando sobre Java 2 Platform Standard Edition Development Kit 5.0 ou superior (JDK 5.0, verso 1.5.0_01 ou superior), contemplando a Java Runtime Environment, ferramentas de desenvolvimento para compilar, depurar, e executar aplicaes escritas em linguagem Java. Sun Java System Application Server Platform Edition 9. Para Solaris, Windows, e Linux, os arquivos da JDK podem ser obtidos para sua plataforma em http://java.sun.com/j2se/1.5.0/download.html Para Mac OS X, Java 2 Plataform Standard Edition (J2SE) 5.0 Release 4, pode ser obtida diretamente da Apple's Developer Connection, no endereo: http:// developer.apple.com/java ( necessrio registrar o download da JDK). Para mais informaes: http://www.netbeans.org/community/releases/55/relnotes.html
Programao WEB
JEDITM
Auxiliadores especiais
Reviso Geral do texto para os seguintes Pases:
Brasil Tiago Flach Guin Bissau Alfredo C, Bunene Sisse e Buon Olossato Quebi ONG Asas de Socorro
Coordenao do DFJUG
Daniel deOliveira JUGLeader responsvel pelos acordos de parcerias Luci Campos - Idealizadora do DFJUG responsvel pelo apoio social Fernando Anselmo - Coordenador responsvel pelo processo de traduo e reviso, disponibilizao dos materiais e insero de novos mdulos Rodrigo Nunes - Coordenador responsvel pela parte multimdia Srgio Gomes Veloso - Coordenador responsvel pelo ambiente JEDITM (Moodle)
Agradecimento Especial
John Paul Petines Criador da Iniciativa JEDITM Rommel Feria Criador da Iniciativa JEDITM
Programao WEB
JEDITM
1. Objetivos
A maioria das aplicaes WEB utiliza algum tipo de armazenamento externo para gerar seu contedo dinamicamente. Esse meio de de armazenamento externo, na maioria das vezes, encontrado na forma de um banco de dados relacional, devido a sua simplicidade e facilidade para se extrair dados. Essa extrao de dados de um banco relacional realizado com o uso do SQL Structure Query Language (Linguagem de Pesquisa Estruturada). Esta linguagem define uma sintaxe e vrias palavras chaves que podem ser entendidas por sistemas de bancos de dados. A grande maioria dos bancos relacionais prov um programa cliente que permite a entrada de comandos em SQL em que o resultado exibido na tela. Entretanto, aplicaes WEB no podem utilizar esta interface em seus programas. A API JDBC, que faz parte da plataforma J2EE, prov aos desenvolvedores um padro, uma maneira programtica de relacionamento com os bancos de dados relacionais. Fazendo uso desta API, os desenvolvedores podem executar consultas SQL e fazer uso de seus resultados para gerar contedo dinmico para seu cliente. Ao final desta lio, o estudante ser capaz de:
Construir um objeto da classe Connection utilizando a classe DriverManager ou DataSource Construir um objeto da classe Statement usando o mtodo createStatement() disponvel na classe Connection Executar consultas SQL usando um objeto da classe Statement e recuperar os resultados Encerrar os objetos do banco de dados
Programao WEB
JEDITM
Neste exemplo, vemos uma tabela que utilizada para armazenar dados do usurio. A tabela define 4 colunas: uma coluna id que armazena uma identificao que nica para cada usurio, uma coluna de nome, endereo, e uma outra para o nmero de contato. Cada linha da tabela representa uma nica informao. Isto significa que existe um usurio chamado Duke, ao qual o endereo na Califrnia, que possui o id 14627895 e o nmero de contato 0924562788. As tabelas utilizadas num sistema de bancos de dados no so to simples quanto a apresentada acima. As tabelas definidas num banco de dados so geralmente montadas com constraints lgicas que servem para preservar a consistncia dos dados. Uma constraint uma restrio de um tipo de dado: cada coluna definida para ser de um tipo de dados especfico. O sistema automaticamente rejeita a insero de novos dados que no sejam compatveis com o tipo de dado definido pela estrutura da tabela. Por exemplo, a coluna id pode ser definida internamente para ser do tipo integer. Tentar inserir novas linhas que contenham caracteres em seus valor para o campo id causar uma falha na insero. Outra constraint geralmente imposta numa coluna a unicidade: se uma coluna definida como sendo nica o sistema no aceitar a insero de um novo dado que contenha um valor j existente no sistema. As mecnicas de definio de uma tabela esto alm do escopo desta discusso e sero deixados para posterior compreenso. Esta discusso ser focada no acesso a dados e modificao numa dada tabela.
Programao WEB
JEDITM
3. Sentenas SQL
Como j foi mencionado anteriormente, operaes em bancos de dados relacionais so realizadas por meio de SQL. Existem vrios tipos de sentenas SQL. Apesar disto, duas sero abordadas nesta lio.
SELECT marca o incio do comando SELECT column (coluna) o nome das colunas da qual os valores sero retornados. Se todas as colunas devem ser recuperadas, um asterisco(*) pode se utilizado no lugar do nome das colunas.
Recuperando mltiplas colunas -> SELECT id, nome, endereco FROM ... Recuperando todas as colunas -> SELECT * FROM ...
FROM indica o nome da tabela de onde os dados sero recuperados. Um mecanismo para a recuperao de dados de mltiplas tabelas tambm est includo na linguagem SQL, e ser discutido em detalhes mais a frente. WHERE opcional e especifica condies que os registro devero atender antes de serem includos no resultado. Mais de uma condio pode ser especificada; neste caso, as condies so separadas por uma palavra chave AND (exclusiva) ou OR (inclusiva) que executam as mesmas funes de seus equivalentes lgicos. Outros tipos de condies so permitidas e sero discutidas futuramente.
3.1.2. A clusula FROM A clusula FROM numa sentena SELECT define a(s) tabela(s) de onde os dados sero reunidos. Se os dados vierem somente de uma nica tabela, ento o nome daquela tabela simplesmente informado. Entretanto, se o dado vier de mais de uma tabela, uma operao conhecida como table join (juno de tabelas) deve ser executada. Table joins podem ser executadas de inmeros modos: User userid name address contactnum userid
14627895 36542036 84321874 14627895 Duke 65248987 Kimi 84321874 Dante San Francisco 0924562788 Finland 8687243217 San Jose 6365498428
UserDownloads
downloaditem Courseware Notes Exercises Slides downloaddate Dec. 19, 2005 Feb. 11, 2006 March 13, 2006
listando todas as tabelas que sero unidas. No comando SQL poderiam ser separadas por
6
Programao WEB
JEDITM
vrgulas. Apesar de ser mais simples, este mtodo tambm mais lento em termos de performance. O resultado obtido um produto cartesiano das tabelas. Exemplo: Dadas duas tabelas, User e UserDownloads, a unio executada por: SELECT * FROM user, userdownload [WHERE ...] Se a vrgula for utilizada como delimitador, o resultado ser como o mostrado a seguir: userid name address
San Francisco San Francisco San Francisco Finland Finland Finland San Jose San Jose San Jose
contactnum
0924562788 0924562788 0924562788 8687243217 8687243217 8687243217 6365498428 6365498428 6365498428
userid
14627895 36542036 84321874 14627895 36542036 84321874 14627895 36542036 84321874
downloaditem
Courseware Notes Exercises Slides Courseware Notes Exercises Slides Courseware Notes Exercises Slides
downloaddate
Dec. 19, 2005 Feb. 11, 2006 March 13, 2006 Dec. 19, 2005 Feb. 11, 2006 March 13, 2006 Dec. 19, 2005 Feb. 11, 2006 March 13, 2006
14627895 Duke 14627895 Duke 14627895 Duke 65248987 Kimi 65248987 Kimi 65248987 Kimi 84321874 Dante 84321874 Dante 84321874 Dante
JOIN
Fazendo uso de um dos muitos JOINs. A sintaxe : table1 JOIN table2 WHERE condition. Condio especifica quais linhas de ambas as tabelas sero unidas para que o resultado possa ser gerado.
LEFT JOIN
A performance similar ao JOIN, exceto que todas as linhas de table1 sero retornadas a unio, mesmo que no exista uma linha correspondente em table2 que atenda a condio. Utilizando o LEFT JOIN nestas tabelas, com a condio User.userid = UserDownloads.userid: userid name address
San Francisco Finland San Jose
contactnum
0924562788 8687243217 6365498428
userid
14627895 84321874
downloaditem
Courseware Notes Slides
downloaddate
Dec. 19, 2005 March 13, 2006
RIGHT JOIN
A performance similar ao JOIN, exceto que todas as linhas de table2 sero retornadas a unio, mesmo que no exista uma linha correspondente em table1 que atenda a condio. Utilizando o RIGHT JOIN nestas tabelas, com a mesma condio: userid name address
San Francisco San Jose
contactnum
0924562788 6365498428
userid
14627895 36542036 84321874
downloaditem
Courseware Notes Exercises Slides
downloaddate
Dec. 19, 2005 Feb. 11, 2006 March 13, 2006
INNER JOIN
Somente as linhas de table1 e table2 que atendam condio sero consideradas no resultado. Utilizando o INNER JOIN nestas tabelas, com a mesma condio: userid name address
San Francisco San Jose
contactnum
0924562788 6365498428
userid
14627895 84321874
downloaditem
Courseware Notes Slides
downloaddate
Dec. 19, 2005 March 13, 2006
Programao WEB
JEDITM
Na maioria dos casos, a utilizao de um INNER JOIN trar os resultados mais relevantes para as operaes da juno de tabelas. Entretanto, em casos onde as linhas de uma determinada tabela devem aparecer no resultado no importando as condies da pesquisa, um LEFT JOIN ou RIGHT JOIN considerado mais apropriado. Evite utilizar a vrgula como delimitador sempre que possvel. Apesar da escrita ser mais fcil, a performance ser muito baixa, valendo a pena gastar um pouco mais de tempo e utilizar o JOIN correta. 3.1.4. A clusula WHERE A clusula WHERE numa sentena SELECT especifica uma condio que deve ser obedecida pelos registros numa tabela qualquer para que apaream no resultado. Existem muitos operadores que podem ser utilizados para especificar uma condio:
= - Verifica a igualdade entre dois operandos dados. <=, < - Verifica se o primeiro operando menor ou igual, ou menor que o segundo operando. >=, > - Verifica se o primeiro operando maior ou igual, ou maior que o segundo operando. like - Executa uma comparao entre os caracteres dos operandos. Utilizando este operador, dois caracteres podem ser utilizados para representar um valor desconhecido.
% - Aplica-se a Strings de qualquer tamanho. Ex: 'A%s' encontrar todas as ocorrncias de palavras que se iniciem por A e terminem com s. _ - Aplica-se a qualquer caractere. Ex: 'b_t' ir encontrar todas as ocorrncias de palavras que se iniciem com 'b' e terminem com 't', mas que possuam somente um caractere entre eles.
Pesquisar pelo endereo dos usurios que tenham o nome de Smith. SELECT address from users where name = 'Smith';
Pesquisar todas as linhas da tabela users com o nome iniciado por 'S'. SELECT * from users where name like 'S%';
A linguagem SQL no case-sensitive em relao as suas palavras-chave (diferente de Java). Entretanto, case-sensitive em relao aos parmetros de comparao. A seguinte sentena trar uma coleo de registros diferente da apresentada anteriormente: SELECT * from users where name ='sMith';
JEDITM
referenciada, a associao feita com os campos passados como parmetro baseados na ordenao das colunas da tabela. Por exemplo, numa tabela chamada users, com as colunas userid, name, address, nesta ordem, o comando a seguir adicionar uma nova linha na tabela: INSERT INTO users VALUES(199700651, 'Jedi Master', 'UP Ayala Technopark'); muito importante notar que toda sentena que faz uso do comando INSERT, deve seguir todas as regras de integridade definidas pela tabela. Isto , se um campo numa tabela definido para ser not null, qualquer tentativa de inserir um valor nulo neste campo causar num erro. 3.2.2. Comando UPDATE O comando UPDATE realiza uma modificao de registros em uma determinada tabela. UPDATE table-name SET column-value(s) WHERE condition(s) Acima temos a forma bsica do comando UPDATE, onde table-name o nome da tabela que contm as linhas as serem modificadas e column-values uma lista com os novos valores das colunas na tabela. Opcionalmente, uma lista de condies pode ser adicionada para especificar quais linhas da tabela sero modificadas. Se nenhuma condio for passada, o comando UPDATE ser efetuado para todas as linhas existentes numa dada tabela. Todo comando UPDATE deve seguir as regras de integridade impostas pelo banco de dados. Por exemplo, alterar o valor de um campo marcado como not null para um valor nulo resultar na no execuo da sentena e numa mensagem de erro vinda do banco de dados relacional. 3.2.3. Comando DELETE O comando DELETE elimina registros de uma determinada tabela. Observe que oposto ao comando INSERT que adiciona novos registro a tabela. DELETE FROM table-name WHERE condition(s) Acima apresentada a forma bsica do comando DELETE, sendo table-name o nome da tabela que contm os dados que se deseja eliminar. Uma lista de condies pode ser opcionalmente especificada. Se nenhuma condio for dada, o comando ir excluir todos os registros da tabela mencionada.
Programao WEB
JEDITM
4. JDBC
Java fornece uma biblioteca padro para que o acesso a bancos de dados seja efetuado, a chamada Java Database Connectivity ou, simplesmente, JDBC. Por meio desta os desenvolvedores podem acessar bases de dados no importando quem seja seu fabricante; os desenvolvedores de um JDBC provem a implementao para as interfaces definidas nesta API, fornecendo o mesmo grupo de funcionalidades ao desenvolvedor do sistema. As seguintes classes esto na API JDBC:
java.sql.Connection Representa a conexo com o banco de dados. Encapsula os detalhes de como a comunicao com o servidor realizada. java.sql.DriverManager Gerencia os drivers JDBC utilizados pela aplicao. Em conjunto com o endereo e a autenticao, pode fornecer objetos de conexo. javax.sql.DataSource Abrange os detalhes (endereo, autenticao) de como a conexo com o banco de dados obtida. o mais recente e o preferido mtodo de obteno de objetos de conexo. java.sql.Statement Fornece meios ao desenvolvedor para que se possa executar comandos SQL. java.sql.ResultSet Representa o resultado de um comando SQL. Estes objetos normalmente so retornados por mtodos.
4.1. java.sql.DriverManager
Utilizando esta classe, o desenvolvedor pode retornar um objeto de conexo que pode ser usado para executar tarefas relativas ao banco de dados. Dois passos so necessrios para tal:
Primeiro, o driver JDBC deve estar registrado com DriverManager. Isto pode ser feito utilizando o mtodo Class.forName que carrega a classe do driver para a memria. Segundo, utilizando o mtodo getConnection, mediante informao de uma URL, assim como a senha e o nome do usurios autenticados no banco de dados. A URL deve seguir a sintaxe requisitada pela implementao do banco de dados.
Abaixo vemos um exemplo de como se obtm uma conexo com um banco de dados PostgreSQL. Novamente, a URL e o driver especficos para a implementao so utilizados. Para outros bancos de dados, verifique a documentao fornecida. String jdbcURL = "jdbc:postgresql://localhost:5432/jedi-db"; String user = "jedi"; String password = "j3d1master"; Connection conn = null; try { Class.forName("org.postgresql.Driver"); conn = DriverManager.getConnection(url, user, password); ... } catch (SQLException e) { // caso ocorra erro de SQL } Apesar de ser um mtodo vlido para a obteno de um objeto de conexo, necessita que o desenvolvedor faa o rastreamento de alguns detalhes, tais como: o nome da classe do driver, a url necessria para se efetuar a conexo, o nome de usurio e senhas para o acesso ao banco. Estes detalhes so os que mais esto sujeitos a mudanas a cada compilao da aplicao. Alm disso, gerenciar a url e o nome do driver no cdigo dificulta a aplicao a trocar a implementao de sua base de dados, se isto vier a ser necessrio.
Programao WEB
10
JEDITM
4.2. javax.sql.DataSource
Esta uma interface definida na API JDBC desde sua verso 2. Hoje em dia, este o modo recomendado para que se obtenham objetos de conexo. Recuperar objetos de conexo uma tarefa bastante direta: simplesmente chame o mtodo getConnection() de uma instncia vlida desta interface. Sendo DataSource uma interface, uma instncia no pode ser simplesmente criada pelo desenvolvedor utilizando o operador new. recomendado que se deixe para o servidor da aplicao que gerencie a criao de objetos DataSource. Com isto permite-se que o servidor adicione algumas funcionalidades, tais como a connection pooling (reserva de conexes) de uma maneira que transparente tanto para o desenvolvedor, quanto para o usurio final. 4.2.1. Configurando o Datasource no Sun Application Server Cada servidor possui seu prprio procedimento para a configurao e gerenciamento de DataSources. So trs passos para se configurar um DataSource no AppServer:
Registrar o arquivo JAR contendo o driver JDBC Criar o pool de conexes para o banco de dados Registrar um DataSource que utilize este pool
4.2.2. Registrando o arquivo JAR O primeiro passo acessar o console de administrao do servidor e disponibilizar o arquivo de conexo com o banco de dados para o Sun Application Server. Para isso, basta copiar o arquivo .jar para a pasta \lib aonde est instalado o servidor. Por exemplo, com o servidor Glassfish instalado em conjunto com o NetBeans 6.0 pode ser encontrado no Windows na pasta: C:\Program Files\glassfish-v2\ 4.2.3. Criando um pool de conexo Para iniciar a criao de um pool de conexo, selecione Resources | JDBC | Connection Pools no painel a esquerda. Na tela exibida, pressione o boto New e uma tela similar a Figura 2 ser mostrada. Em Name entre com o nome como este pool de conexo ser conhecido (exemplo: jediPool). Em Resource Type selecione javax.sql.DataSource. No Database Vendor selecione o banco de dados utilizado, caso o banco que esteja utilizando no aparea na lista deixe esta opo em branco. Pressione o boto Next, no campo Datasource Classname, caso no venha preenchido por padro, informe o nome da classe do seu banco, para o PostGreSQL: org.postgresql.jdbc3.Jdbc3PoolingDataSource Observe as propriedades para associar com este pool de conexes. Os parmetros seguintes necessitam ter seus valores fornecidos:
Password Senha do banco de dados ServerName Nome do servidor do banco de dados PortNumber Nmero da porta DatabaseName Nome do Banco de dados User Nome do usurio
Programao WEB
11
JEDITM
Selecione Resources | JDBC | Connection Pools | jediPool e pressione o boto ping a seguinte mensagem deve ser mostrada indicando que o pool de conexo foi criado com sucesso:
4.2.4. Registrando o Datasource Para registrar um datasource, selecione Resources | JDBC | JDBC Resources no lado esquerdo do painel. Na tela que aparece, pressione o boto New. Os campos devem ser preenchidos da seguinte maneira:
Nome do JNDI entre como nome lgico da sua aplicao recuperar o DataSource. recomendado que este nome tenha JDBC como seu prefixo para facilitar para futuros administradores do servidor para identificar este elemento de fonte JDBC (ex. jdbc/jediPool) Nome do Pool selecione o nome do pool de conexes criada anteriormente Descrio entre com o texto descrevendo o DataSource (opcional)
Pressione o boto OK para finalizar. Recuperando uma instncia de um DataSource de uma aplicao servidora simples e pode ser realizada usando unicamente algumas linhas de cdigo da API JNDI. Java Naming Directory Interface (JNDI) uma API Java padro para acessar diretrios. Um diretrio um local centralizado onde a aplicao Java pode recuperar recursos externos usando um nome lgico. Detalhes adicionais para JNDI e como este trabalho esto alm do escopo desta lio. A nica coisa que necessitamos conhecer que o servidor de aplicao mantm um diretrio para que seja publicado o DataSource que foi configurado anteriormente. Nossa prpria aplicao pode executar um simples lookup de nome neste diretrio para recuperar o recurso. Para nossas finalidades, bastante criarmos um contexto JNDI usando o construtor padro. Este contexto JNDI abstrai os detalhes da conexo para o diretrio, fazendo lookup do recurso numa simples chamada num mtodo singular. Tome nota que o nome usado para o lookup na fonte deve ter o mesmo nome usado na configurao no DataSource.
Programao WEB 12
JEDITM
... Context ctxt = null; DataSource ds = null; try { // criar uma instncia de um contexto JNDI ctxt = new InitialContext(); // retornar o DataSource de um diretrio com um nome lgico ds = (DataSource)ctxt.lookup("jdbc/PostgreSQLDS"); } catch (NamingException ne) { System.err("Specified DataSource cannot be found"); } Uma vez que temos um exemplo de instncia DataSource vlido, pequemos um objeto Connection to simples quanto. Connection conn = ds.getConnection();
executeQuery utilizado para a instrues de pesquisa no banco de dados (comando SELECT) e retorna o resultado da operao em um objeto do tipo ResultSet. executeUpdate utilizado para as instrues de modificao do banco de dados (comandos CREATE, DROP, ALTER, INSERT, UPDATE ou DELETE) e retorna um tipo primitivo int com o nmero de linhas afetadas.
Abaixo est um exemplo de pedao de um cdigo mostrando como realizar este procedimento: Context ctxt = null; DataSource ds = null; Connection conn = null; Statement stmt = null; ResultSet rs = null; try { ctxt = new InitialContext(); ds = (DataSource)ctxt.lookup("jdbc/PostgreSQLDS"); conn = ds.getConnection(); stmt = conn.createStatement(); rs = stmt.executeQuery("SELECT * FROM users"); } catch (NamingException e) { System.err.print("Cannot find named datasource"); } catch (SQLException se) { System.err.print("Error occurred while performing query"); }
4.4. java.sql.ResultSet
Um objeto ResultSet o resultado de uma consulta em um banco de dados. Os dados dentro de um objeto ResultSet podem ser melhor visualizados com uma tabela. As informaes podem ser recuperada uma coluna de cada vez, com o objeto ResultSet que mantem-se apontando para determinado registro. Para percorrer cada linha no ResultSet, chamamos o mtodo next(). Este mtodo move-se a um ponto interno do objeto ResultSet para a prxima linha. Retorna true se a prxima linha for encontrada e false ao encontrar o final de arquivo (EOF). while (rs.next()) {
Programao WEB 13
JEDITM
Para recuperar os campos em cada linha, o objeto ResultSet fornece um certo de nmero de mtodos de recuperao. Existe um mtodo getString para recuperar dados de uma String, um mtodo getInt para recuperar dados do tipo inteiro, getBoolean para recuperar dados tipo boolean, e assim sucessivamente. Em todos os casos esses mtodos recebem um parmetro, como o nmero da coluna da coluna que contm o dado ou o nome da coluna. Recomenda-se, entretanto, que nomes sejam usados para especificar a coluna para ser lida em vez do nmero de linhas. Isto faz com que a aplicao seja mais fcil de dar manuteno, pois possvel que a ordem da coluna seja alterada ao longo do tempo aps o incio do desenvolvimento. Context ctxt = null; DataSource ds = null; Connection conn = null; Statement stmt = null; ResultSet rs = null; try { ctxt = new InitialContext(); ds = (DataSource)ctxt.lookup("jdbc/PostgreSQLDS"); conn = ds.getConnection(); stmt = conn.createStatement(); rs = stmt.executeQuery("SELECT * FROM users"); while (rs.next()) { String userName = rs.getString("name"); String address = rs.getString("address"); int userID = rs.getInt("userid"); // Outras operaes com os dados retornados } } catch (NamingException e) { System.err("Cannot find named datasource"); } catch (SQLException se) { System.err("Error occurred while performing query"); }
JEDITM
} rs.close(); stmt.close(); conn.close(); } catch (NamingException e) { System.err("Cannot find named datasource"); } catch (SQLException se) { System.err("Error occurred while performing query"); } O problema com esta abordagem que condiciona o sucesso um nico endereo. Nos casos onde uma exceo ocorre no cdigo os recursos de sistema NO sero liberados corretamente. Um caminho melhor ser colocar a clausula finally, para assegurar que que os recursos sejam liberados no importando o que acontea. A soluo para o problema apresentada a seguir: Context ctxt = null; DataSource ds = null; Connection conn = null; Statement stmt = null; ResultSet rs = null; try { ctxt = new InitialContext(); ds = (DataSource)ctxt.lookup("jdbc/PostgreSQLDS"); conn = ds.getConnection(); stmt = conn.createStatement(); rs = stmt.executeQuery("SELECT * FROM users"); while (rs.next()) { String userName = rs.getString("name"); String address = rs.getString("address"); int userID = rs.getInt("userid"); // Outras operaes com os dados retornados } } catch (NamingException e) { System.err("Cannot find named datasource"); } catch (SQLException se) { System.err("Error occurred while performing query"); } finally { try { if (rs != null) rs.close(); } catch (SQLException e) {} try { if (stmt != null) stmt.close(); } catch (SQLException e) {} try { if (conn != null) conn.close(); } catch (SQLException e) {} } Os questionamentos sobre se o objeto nulo so necessrios apenas nos casos em que a condio de erro ocorra antes de um ou mais objetos terem sido apropriadamente instanciados. Cada mtodo close deve tambm ser separado numa clausula try-catch para assegurar que um erro causado na tentativa de fechamento de um objeto no atrapalhe o fechamento dos outros objetos.
String address = rs.getString("address"); int userID = rs.getInt("userid"); // Outras operaes com os dados retornados
Programao WEB
15
JEDITM
5. Exerccio
5.1. Usurios
Considere a seguinte tabela: USERS userid 14627895 65248987 52317568 72324489 gender M M F M firstname Jose Rosario Milagros Frank lastname Saraza Antonio Paguntalan Masipiquena login jsaraza rantonio mpaguntalan fmasipiquena password Asdfrewq167 qwer4679 ukelllll3 Df23efzsxf2341
1. Executar as instrues SQL necessrias para: a) b) c) d) e) Recuperar todos os usurios masculinos. Recuperar todos os usurios com o primeiro nome iniciando com a letra F. Alterar o nome de login do registro com um userid de 65248987 para rtonio. Eliminar todos os registros femininos. Inserir o seguinte registro na tabela: gender F firstname Anne lastname Sacramento login asacramento password k1lasdoj24f
userid 69257824
2. Criar uma classe LoginHandler. Dever conter a seguinte assinatura: public boolean isUserAuthorized(String loginName, String password) Dentro do corpo do mtodo, crie e implemente uma conexo para o banco de dados exemplo, e verifique novamente a tabela usurio se existe um registro que tenha o mesmo login e password que so dados nos parmetros. Use a classe DriverManager para obter a conexo com o banco de dados. 3. Criar um servlet de nome UserEntryServlet que fornea o seguinte formulrio: <HTML> <BODY> <table> <form action="UserEntryServlet" method="post"> <tr> <td>User ID:</td> <td><input type="text" name="userID"/></td> </tr><tr> <td>First name</td> <td><input type="text" name="firstName"/></td> </tr><tr> <td>Last name</td> <td><input type="text" name="lastName"/></td> </tr><tr> <td>Login name</td> <td><input type="text" name="loginName"/></td> </tr><tr> <td>Password</td> <td><input type="text" name="userID"/></td> </tr> </table> </form> </BODY> </HTML>
Programao WEB
16
JEDITM
Usar os valores informados no formulrio e criar um novo registro na tabela de usurios no banco de dados exemplo. Para conectar base de dados, configure o Application Server para a fonte de dados. 4. Criar um servlet dando o nome de UserRemovalServlet esperando um parmetro "userID". Eliminar o registro que corresponda a esse registro.
Programao WEB
17
JEDITM
Instituto CTS Patrocinador do DFJUG. Sun Microsystems Fornecimento de servidor de dados para o armazenamento dos vdeo-aulas. Java Research and Development Center da Universidade das Filipinas Criador da Iniciativa JEDITM. DFJUG Detentor dos direitos do JEDITM nos pases de lngua portuguesa. Banco do Brasil Disponibilizao de seus telecentros para abrigar e difundir a Iniciativa JEDITM. Politec Suporte e apoio financeiro e logstico a todo o processo. Borland Apoio internacional para que possamos alcanar os outros pases de lngua portuguesa. Instituto Gaudium/CNBB Fornecimento da sua infra-estrutura de hardware de seus servidores para que os milhares de alunos possam acessar o material do curso simultaneamente.
Programao WEB
18