• Nenhum resultado encontrado

Lista de Códigos

7.3 Modelo de dados relacional

7.3.2 JDBC

A linguagemSQL pode ser utilizada diretamente pelo usuário, quando o SGBD oferece um interpretadorSQL interativo ou através de comandos embutidos em uma aplicação desenvolvida em uma linguagem de programação. No caso da linguagem de programação Java, a forma de interagir com o banco de dados é especificada pela API JDBC (SPEEGLE, 2001), discutida nesta seção.

O Java Database Connectivity (JDBC) é uma APIJava (pacote java.sql) para execução e manipulação de resultados de consultas SQL. Para uma aplicação Java acessar um banco de dados relacional é necessária a execução dos seguintes passos:

1. habilitar odriver JDBC;

2. estabelecer uma conexão com o banco de dados;

3. executar a consultaSQL; e 4. apresentar resultados da consulta.

7.3.2.1 Drivers JDBC

O driver JDBC consiste em um componente de software que permite que uma aplicação Java interaja com um banco de dados. Para conectar com banco de dados individuais, o JDBC requer drivers para cada SGBD (PostgreSQL, MySQL, etc.).

O driver JDBC fornece a conexão ao banco de dados e implementa o protocolo para transferir a consulta e o resultado entre a aplicação-cliente Java e oSGBD.

Do ponto de vista da aplicação Java, um driver nada mais é do que uma classe cuja funcionalidade precisa ser disponibilizada para a aplicação. A funcionalidade básica que um driver deve oferecer é especificada através da interface Driver. A forma mais usual é carregar odriver explicitamente para a JVM através do método forName()da classe Class, como em

Class.forName("org.postgresql.Driver"); // Carrega odriverpara o SGBD PostgreSQL Class.forName("com.mysql.jdbc.Driver"); // Carrega odriverpara o SGBD MySQL

Class.forName("org.apache.derby.jdbc.ClientDriver"); // Carrega odriverpara o SGBD Apache Derby

Alternativamente, a classe DriverManager estabelece um conjunto básico de serviços para a manipulação de drivers JDBC. Como parte de sua inicialização, essa 184

classe tentará obter o valor da propriedadejdbc.driversde um arquivo de definição de propriedades e carregar os driversespecificados pelos nomes das classes.

7.3.2.2 Conexão com banco de dados

Uma vez que o driver esteja carregado, a aplicação Java pode estabelecer uma conexão com o sistema gerenciador de banco de dados. Para especificar com qual banco de dados se deseja estabelecer a conexão, é utilizada uma string na forma de uma URL na qual o protocolo é jdbc: e o restante da string é dependente do driver. Por exemplo, aURL jdbc:derby://localhost:1527/Museu, especifica uma conexão ao banco de dadosMuseuque se encontra sob a gerência doSGBD Apache Derbyhospedado na máquina local.

Identificado o banco de dados, a sessão, a ser estabelecida para o acesso ao banco de dados, será controlada por uma instância de uma classe que implementa a interface Connection. ODriverManageroferece o métodogetConnection()para executar essa tarefa. O encerramento de uma sessão é sinalizado pelo método close() da conexão.

String url = "jdbc:derby://localhost:1527/Museu"; // URL de conexão String usuário = "root"; // usuário do SGBD

String senha = "root"; // senha do usuário do SGBD ...

Connection c = DriverManager.getConnection(url, usuário, senha);

...

c.close(); // encerra a conexão com o banco

7.3.2.3 Execução da consulta

Estabelecida a conexão ao banco de dados, é possível criar uma consulta SQL e executá-la a partir da aplicação Java. Para representar uma consulta SQL, o JDBC utiliza uma instância de uma classe que implementa a interface Statement. Um objeto dessa classe pode ser obtido através do métodocreateStatement()da classe Connection.

Uma vez que uma instância de Statement esteja disponível, é possível aplicar a ele o método executeQuery(), que recebe como argumento uma string repre- sentando uma consultaSQL. O resultado da execução da consulta é disponibilizado através de um objetoResultSet.

185

...

Connection c = DriverManager.getConnection(url, usuário, senha);

..

Statement s = c.createStatement();

String query = "SELECT * FROM Empregado";

ResultSet r = s.executeQuery(query);

...

s.close();

c.close(); // encerra a conexão com o banco

Os métodos da interface ResultSet permitem a manipulação dos resultados individuais de uma tabela de resultados. Métodos como getDouble(), getInt() e getString(), que recebem como argumento a especificação de uma coluna da tabela, permitem acessar o valor da coluna especificada na tupla corrente para os diversos tipos de dados suportados.

Para varrer a tabela, um cursor é mantido. Inicialmente, ele está posicionado antes do início da tabela, mas pode ser manipulado pelos métodosfirst(),next(), previous(),last()eabsolute(int row). Por exemplo,

ResultSet r = s.executeQuery("SELECT * FROM EMPREGADO");

System.out.println("Id Nome");

while (r.next()) { System.out.println(r.getString("Id")+ + r.getString("Nome")); } r.close();

Para lidar com atributos que podem assumir valores nulos, o método wasNull() é oferecido. Ele retorna verdadeiro quando o valor obtido pelo métodogetXXX()for nulo, em queXXXé um dos tipos SQL.

A interface ResultSetMetadata permite obter informação sobre a tabela com o resultado da consulta. Um objeto desse tipo pode ser obtido através da aplicação do método getMetaData() ao ResultSet. Uma vez obtido esse objeto, a infor- mação desejada pode ser obtida através de métodos tais comogetColumnCount(), getColumnLabel(),getColumnTypeName()egetColumnType(). O último método retorna tipos que podem ser identificados a partir de constantes definidas na classe java.sql.Types.

Além da forma interface Statement, JDBC oferece duas formas alternativas que permitem, respectivamente, ter acesso a comandos SQL pré-compilados (PreparedStatement) e a procedimentos armazenados no banco de dados (CallableStatement).

186

7.3.2.4 AplicaçãoListaObrasDeArte

Esta seção apresenta uma aplicação Java (Código 7.2) que acessa o banco de dadosMuseu hospedado na máquina local. Com propósitos de ilustração, o Apache Derby2será utilizado nessa aplicação. No entanto, o leitor deve sentir-se à vontade para usar outro SGBD se este já estiver instalado e configurado. Os links abaixo apresentam dicas na configuração do Apache Derby e na posterior integração com os dois principaisIDEs open-source:

• Netbeans: https://netbeans.org/kb/docs/ide/java-db_pt_BR.html.

• Eclipse: http://db.apache.org/derby/integrate/plugin_help/start_toc.html.

Essa aplicação supõe que o banco de dadosMuseufoi criado e populado conforme descrito no script apresentado no Código 7.1. A classe ListaObrasDeArte apenas possui o método main(), que simplesmente conecta com o banco de dados Museu e imprime a lista de obras de arte armazenada nesse banco de dados. A saída da execução desse programa é similar à apresentada na Tabela 7.1.

ID TITULO ARTISTA MATERIAL ANO CATEGORIA TIPO ALTURA

1 Mona Lisa Leonardo da Vinci Madeira 1503 1 Óleo null

2 David Michelangelo Mármore 1501 2 null 4,10

3 O Lavrador de Café Cândido Portinari Madeira 1939 1 Óleo null

4 O Pensador Auguste Rodin Bronze 1909 2 null 1,40

Tabela 7.1 Saída da execução da classeListaObrasDeArte.

Conforme se pode observar, o método main()executa os quatro passos neces- sários para acessar um banco de dados relacional utilizando aAPI JDBC:

1. habilitar odriver JDBC(linha 14);

2. estabelecer uma conexão com o banco de dados (linhas 16-21);

3. executar a consultaSQL (linhas 23-25); e 4. apresentar resultados da consulta (linhas 27-61).

2 http://db.apache.org/derby/.

187

1 /∗∗

C l a s s e L i s t a O b r a s D e A r t e−− C o n e c t a com o b a n c o de d a d o s Museu e i m p r i m e a l i s t a de o b r a s de a r t e 2 3

a r m a z e n a d a na t a b e l a O b r a D e A r t e p r e s e n t e n e s s e b a n c o de d a d o s .

4

5

@ a u t h o r D e l a n o M e d e i r o s B e d e r

6

/

7 p u b l i c c l a s s L i s t a O b r a s D e A r t e {

8 9 p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {

10 f i n a l S t r i n g f m t 1 0 = " %−10.10 s " ;

11 f i n a l S t r i n g f m t 2 0 = " %−20.20 s " ;

12 13 t r y {

14 C l a s s . forName ( d r i v e r ) ; // C a r r e g a d r i v e r

15 16 // E s t a b e l e c e c o n e xão com o b a n c o de d a d o s

17 S t r i n g d r i v e r = " o r g . a p a c h e . d e r b y . j d b c . C l i e n t D r i v e r " ;

18 S t r i n g u r l = " j d b c : d e r b y : / / l o c a l h o s t : 1 5 2 7 / Museu " ;

19 S t r i n g u s e r = " r o o t " ;

20 S t r i n g p a s s w o r d = " r o o t " ;

21 C o n n e c t i o n c o n n e c t i o n = D r i v e r M a n a g e r . g e t C o n n e c t i o n ( u r l , u s e r , p a s s w o r d ) ;

22 23 // Monta e e x e c u t a c o n s u l t a

24 S t a t e m e n t s = c o n n e c t i o n . c r e a t e S t a t e m e n t ( ) ;

25 R e s u l t S e t r = s . e x e c u t e Q u e r y ( "SELECT FROM O b r a D e A r t e " ) ;

26 27 // A p r e s e n t a e s t r u t u r a da T a b e l a

28 S t r i n g B u i l d e r s b =new S t r i n g B u i l d e r ( ) ;

29 f o r (i n t i = 0 ; i < 1 2 ; i ++) {

30 s b . a p p e n d ( "−−−−−−−−−−" ) ;

31 }

32 S y s t e m . o u t . p r i n t l n ( s b ) ;

33 34 R e s u l t S e t M e t a D a t a m = r . g e t M e t a D a t a ( ) ;

35 i n t c o l C o u n t = m. g e t C o l u m n C o u n t ( ) ;

36 f o r (i n t i = 1 ; i <= c o l C o u n t ; ++i ) {

37 i f (m. g e t C o l u m n T y p e ( i ) != T y p e s . VARCHAR) {

38 S y s t e m . o u t . p r i n t f ( fmt10 , m. getColumnName ( i ) ) ;

39 } e l s e {

40 S y s t e m . o u t . p r i n t f ( fmt20 , m. getColumnName ( i ) ) ;

41 }

42 }

43 S y s t e m . o u t . p r i n t l n ( ) ;

44 S y s t e m . o u t . p r i n t l n ( s b ) ;

45 46 w h i l e ( r . n e x t ( ) ) {

47 S y s t e m . o u t . p r i n t f ( fmt10 , S t r i n g . v a l u e O f ( r . g e t I n t ( 1 ) ) ) ; // Obtém p e l o número da c o l u n a

48 S y s t e m . o u t . p r i n t f ( fmt20 , r . g e t S t r i n g ( "TITULO" ) ) ; // Obtém p e l o nome da c o l u n a

49 S y s t e m . o u t . p r i n t f ( fmt20 , r . g e t S t r i n g ( 3 ) ) ; // Obtém p e l o número da c o l u n a

50 S y s t e m . o u t . p r i n t f ( fmt20 , r . g e t S t r i n g ( "MATERIAL" ) ) ; // Obtém p e l o nome da c o l u n a

51 S y s t e m . o u t . p r i n t f ( fmt10 , S t r i n g . v a l u e O f ( r . g e t I n t ( 5 ) ) ) ; // Obtém p e l o número da c o l u n a

52 S y s t e m . o u t . p r i n t f ( fmt10 , S t r i n g . v a l u e O f ( r . g e t I n t ( 6 ) ) ) ; // Obtém p e l o número da c o l u n a

53 S y s t e m . o u t . p r i n t f ( fmt20 , r . g e t S t r i n g ( " TIPO " ) ) ; // Obtém p e l o nome da c o l u n a

54 d o u b l e a l t u r a = r . g e t D o u b l e ( 8 ) ; // Obtém p e l o número da c o l u n a

55 56 i f ( a l t u r a == 0 ) {

57 S y s t e m . o u t . p r i n t f ( f m t 1 0+" \ n " , " n u l l " ) ;

58 } e l s e {

59 S y s t e m . o u t . p r i n t f ( " %−10.2 f \ n " , r . g e t D o u b l e ( 8 ) ) ;

60 }

61 }

62 r . c l o s e ( ) ;

63 c o n n e c t i o n . c l o s e ( ) ; // F e c h a c o n e xão com b a n c o de d a d o s

64 } c a t c h ( E x c e p t i o n e ) {

65 S y s t e m . e r r . p r i n t l n ( e ) ;

66 }

67 }

68

}

Código 7.2 ClasseListaObrasDeArte.

188