Banco de Dados Relacionais

Propaganda
Banco de Dados Relacionais
Tabelas
•
•
•
•
•
DB Relacionais são baseados em tabelas
As tabelas armazenam registros
Cada registro ocupa uma linha da tabela
Registros são dividos em campos
Cada campo armazena um e somente um
tipo de dado
Tabelas
• DB são baseados em tabelas
campo
Tabela “Cafés”
Tipo de Café
registro
ID_Vendedor
Preço
Vendas
Total
Colombiano
1001
1,35
0
0
Francês
201
1,38
0
0
Expresso
201
1,43
0
0
Brasileiro
1001
1,31
0
0
Descafeinado
201
1,33
0
0
Principais Operações
Realizadas nas Tabelas de
um Banco de Dados
Principais Operações
• Projeção sobre um ou mais campos
• Seleção de um ou mais registros
• Junção (join) de duas ou mais tabelas a
partir dos
valores de dois ou mais de seus campos
Seleção
• Selecione todos os registros cujo preço é maior que 1,34
na tabela Cafés
campo
Tabela “Cafés”
Tipo de Café
registro
ID_Vendedor
Preço
Vendas
Total
Colombiano
1001
1,35
0
0
Francês
201
1,38
0
0
Expresso
201
1,43
0
0
Brasileiro
1001
1,31
0
0
Descafeinado
201
1,33
0
0
Projeção
• Projete o campo Vendas sobre a tabela Cafés
campo
Tabela “Cafés”
Tipo de Café
ID_Vendedor
Preço
Vendas
Total
Colombiano
1001
1,35
0
0
Francês
201
1,38
0
0
Expresso
201
1,43
0
0
Brasileiro
1001
1,31
0
0
Descafeinado
201
1,33
0
0
Uma Linguagem Para
Trabalhar com BD
Relacionais
SQL
• A principal linguagem usada para trabalhar com banco de
dados é o SQL (Structured Query Language). SQL é
dividida em duas partes:
• Linguagem de Definição de Dados (DDL) – usado para
definição da estrutura do banco de dados, suas tabelas e
seus índices.
• Linguagem de Manipulação de Dados (DML) – usado
para operação do banco de dados, consultas, inserções e
remoções nos dados.
DDL
• Definindo a tabela “COFFEES”
CREATE TABLE COFFEES
(
COF_NAME VARCHAR(32),
SUP_ID
INTEGER,
PRICE
FLOAT,
SALES
INTEGER,
TOTAL
INTEGER
)
DML
• Fazendo um seleção e projeção na
tabela “Fornecedores”
– SELECT Fornecedor_ID, Nome
– FROM Fornecedores
– WHERE Cidade LIKE “Salvador”
JDBC
Java Database Connectivity
• JDBC é uma biblioteca Java de acesso universal a
banco de dados.
• Ela usa um protocolo padrão para acessar qualquer
base de dados.
• Os fabricantes de bases de dados são responsáveis
por disponibilizar os drivers de acesso as suas bases
de dados. Estes drivers são classes Java carregadas
em tempo de execução pelos programas que usam
JDBC.
• Exceto pelos drivers, todo o programa segue então
um padrão que pode ser aplicado sobre qualquer BD
que suporta JDBC
Para Usar JDBC
• Precisamos do Java – biblioteca java.sql.*
• Precisamos de um Banco de Dados – neste
curso usaremos o MS Access
• Precisamos de Driver JDBC para este banco de
dados – neste curso usaremos a ponte JDBCODBC que já vem com o Java
Carregando um Driver
O primeiro passo para seu programa usar o JDBC é
carregar um driver para o banco de dados. Isto é feito
com o comando:
Class.forName("jdbc.DriverXYZ");
Esta declaração carrega o driver e o torna disponível para
uso mais tarde quando formos abrir a conexão com o
servidor de banco de dados. Quando é carregado em
memória, o driver registra a se próprio com a classe
java.sql.DriverManager como um dos drivers de banco
de dados disponíveis. No nosso exemplo faremos:
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Fazendo Uma Conexão
O próximo passo é efetivamente conectar com o banco
de dados. Isto é feito pelo comando:
Connection con = DriverManager.getConnection(
url, "myLogin", "myPassword");
A única parte difícil nesta declaração é a url . Ela vai
efetivamente definir a localização do banco de dados a
ser acessado usando um dado protocolo. O protocolo é
definido na documentação do fabricante do banco de
dados. No caso das pontes ODBC usa-se:
String url = "jdbc:odbc:MeuBanco";
Connection con = DriverManager.getConnection(
url, “Manoel", “fredflinstone");
O Driver Manager
A classe DriverManager gerencia todos os detalhes do
estabelecimento de uma conexão. A não ser que você va
escrever um driver você mesmo, você não precisa usar
nenhum dos métodos da interface Driver, e o único
método de DriverManager que você usará será
DriverManager.getConnection.
A conexão retornada por este método é um conexão para
o banco de dados pela qual você pode usar comando
JDBC para passar comandos SQL para o gerenciador de
banco de dados (DBMS). No nosso exemplo anterior, con
é esta conexão que foi aberta.
A Conexão
Comandos SQL e respostas
login:
manoel
password: fredflintone
Programa Java
DBMS
(base Aulas)
String url = "jdbc:odbc:MeuBanco";
Connection con = DriverManager.getConnection(
url,“Manoel",“fredflinstone");
Rodando
Comandos SQL com JBDC
Montando um Comando SQL
• JDBC “fala” com o banco de dados usando SQL. Desta
forma qualquer operação JDBC sobre o banco de dados
deve montar um comando SQL em DDL ou DML em uma
String, por exemplo:
• String query = "CREATE TABLE COFFEES
(COF_NAME VARCHAR(32), SUP_ID INTEGER,
PRICE FLOAT, SALES INTEGER, TOTAL
INTEGER)";
• Note que está é exatamente a declaração que nós vimos a
pouco. Ela cria a tabela COFFEES no seu banco de dados.
Executando um Comando SQL
• Após montado, o comando deve ser passado pelo JDBC ao
gerenciador do banco de dados, isto é feito em dois passos.
• Passo 1, obtém-se um objeto “declaração SQL” para a
conexão estabelecida:
– Statement stmt = con.createStatement();
• Passo 2, executa-se o comando SQL através deste objeto:
– stmt.executeUpdate("CREATE TABLE COFFEES " +
"(COF_NAME VARCHAR(32), SUP_ID INTEGER, PRICE
FLOAT, " + "SALES INTEGER, TOTAL INTEGER)");
– ou
– stmt.executeUpdate(query);
O Método executeUpdate
• Usamos o método executeUpdate na transparência anterior
pois a declaração executada foi um declaração DDL.
Outras declaração nesta linha incluem alterar (alter) e
descartar (drop) tabela.
• O método executeUpdate é também usado para atualizar
(update) uma tabela, um comando DML. Na prática
executeUpdate é muito mais usado para atualizar tabelas
que para cria-las , pois normalmente se cria a tabela uma
vez e se atualiza ela muitas vezes. Isto é, comandos DDL
são muito mais infreqüentes que comandos DML.
Atualizando uma Tabela
• O exemplo abaixo mostra a atualização do
campo Cidade da tabela Fornecedores:
– Statement stmt = con.createStatement();
stmt.executeUpdate("UPDATE
Fornecedores " + "SET Cidade='São
Salvador'" +"WHERE Cidade LIKE
'Salvador'");
Valor retornado por
executeUpdate
• O método executeUpdate retorna um valor inteiro.
Este valor indica quantas linhas da tabela foi
alterada:
– int i = stmt.executeUpdate("UPDATE
Fornecedores " + "SET Cidade='São Salvador'" +
"WHERE Cidade LIKE 'Salvador'");
Inserindo Dados numa Tabela
• O exemplo abaixo mostra a inserção dos dados da tabela
COFFEES:
– Statement stmt = con.createStatement();
– stmt.executeUpdate("INSERT INTO COFFEES " +” VALUES
('Colombian', 101, 7.99, 0, 0)");
– stmt.executeUpdate("INSERT INTO COFFEES " + "VALUES
('French_Roast', 49, 8.99, 0, 0)");
– stmt.executeUpdate("INSERT INTO COFFEES " + "VALUES
('Espresso', 150, 9.99, 0, 0)");
– stmt.executeUpdate("INSERT INTO COFFEES " + "VALUES
('Colombian_Decaf', 101, 8.99, 0, 0)");
– stmt.executeUpdate("INSERT INTO COFFEES " + "VALUES
('French_Roast_Decaf', 49, 9.99, 0, 0)");
Consultas ao
Banco de Dados
Consultas
• Consultas são de longe as operações mais executados em banco de
dados. Em SQL isso é executado através do comando Select. O Select
mais simples tem a seguinte forma: SELECT * FROM COFFEES
• O asterisco (*) indica que todas a colunas devem ser selecionadas. A
ausência do WHERE indica que todas as linhas da tabela devem ser
selecionadas. Desta forma a tabela inteira é retornada como resposta:
–
–
–
–
–
COF_NAME SUP_ID
--------------- -----Colombian 101
French_Roast
Espresso
150
PRICE
----7.99
49
SALES
----0
8.99
9.99
0
TOTAL
----0
0
0
0
Projeção
• O comando select permite a seleção das colunas desejadas
na(s) tabela(s) consultada(s), numa operação chamada de
“projeção”. Por exemplo, o comando SELECT
COF_NAME, PRICE FROM COFFEES retorna:
–
–
–
–
–
–
–
COF_NAME
-------Colombian
French_Roast
Espresso
Colombian_Decaf
French_Roast_Decaf
PRICE
----7.99
8.99
9.99
8.99
9.99
Seleção
• O comando select usa a cláusula
WHERE para selecionar as linhas
desejadas na(s) tabela(s) consultada(s).
Por exemplo, o comando:
– SELECT COF_NAME, PRICE
– FROM COFFEES
– WHERE PRICE < 9.00
Executando Consultas em
JDBC
• Consultas são executadas em JBDC através do
método executeQuery da classe Statement:
• Statement stmt = con.createStatement();
• ResultSet rs = stmt.executeQuery("SELECT
COF_NAME, PRICE FROM COFFEES");
• Note que as consultas retornam valores, muitas
vezes conjunto de dados enormes. Para receber os
valores retornados deve-se usar um objeto da
classe ResultSet.
ResultSet
• Objetos da classe ResultSet recebem os dados da tabela
linha a linha. Ele possui métodos para nominalmente pegar
os campos de dados de uma determinada linha (getXXX).
• O método next move o cursor para a próxima linha e
retorna verdadeiro. Inicialmente o cursor é posicionado
acima da primeira linha. As sucessivas invocações do
método next move o cursor para a linha de baixo até que se
alcance a última linha. Método next retorna falso quando o
cursor chega na ultima linha.
Exemplo de Uso de ResultSet
• Abaixo mostra-se uso dos métodos next() e getXXX() da
classe ResultSet:
– String query = "SELECT COF_NAME, PRICE FROM
COFFEES";
– ResultSet rs = stmt.executeQuery(query);
– while (rs.next()) {
– String s = rs.getString("COF_NAME");
– float n = rs.getFloat("PRICE");
– System.out.println(s + " " + n);
– }
• O resultado retornado é mostrado a seguir:
– Colombian 7.99
– French_Roast 8.99
Formas de Uso do getXXX()
• O JDBC oferece duas formas de identificar a
coluna a qual o método getXXX se refere. Uma
forma é dar o nome da coluna como visto na
transparência passada:
– String s = rs.getString("COF_NAME");
– float n = rs.getFloat("PRICE");
• A outra forma é dar o índice (número) da coluna
na tabela de resultado:
– String s = rs.getString(1);
– float n = rs.getFloat(2);
Declarações Preparadas a
Priori
Declarações Preparadas a
Priori
• Quando o mesmo tipo de declaração tem que ser
executada muitas vezes é mais eficiente usar a
classe PreparedStatement para fazer isso.
• PreparedStatement é uma subclasse de Statement.
• Objetos desta classe permitem a pré-definição de
uma declaração SQL que depois pode ser chamada
várias vezes com diferentes parâmetros (valores).
Criando um
PreparedStatement
• Como nos objetos Statement, você cria objetos
PreparedStatement usando objetos da classe Connection.
• Usando o mesmo objeto “con” dos exemplos
anteriores,nós poderíamos preparar o seguinte
PreparedStatement:
– PreparedStatement updateSales =
con.prepareStatement("UPDATE COFFEES SET SALES =
? WHERE COF_NAME LIKE ?");
• Este objeto deverá receber dois parâmetros de entradana
hora de execução. Este parâmetros são indicados ao
DBMS pêlos sinais de interrogação.
Executando o
PreparedStatement
• Os parâmetros são preparados com métodos setXXX() e
executados com os métodos executeUpdate e/ou
executeQuerry():
– PreparedStatement updateSales =
con.prepareStatement("UPDATE COFFEES SET SALES =
? WHERE COF_NAME LIKE ?");
– updateSales.setInt(1, 75);
– updateSales.setString(2, "Colombian");
– updateSales.executeUpdate();
• Este comando é equivalente a:
– String updateString = "UPDATE COFFEES SET SALES =
75 " +"WHERE COF_NAME LIKE 'Colombian'";
– stmt.executeUpdate(updateString);
Vantagens do
PreparedStatement
• A principal característica de um objeto da classe
PreparedStatement é que, ao contrário de objetos da classes
Statement, ele recebe uma declaração SQL na hora de sua
de criação.
• Isto permite que a declaração seja enviada ao DBMS para
ser compilada na hora de sua declaração. Como resultado,
objetos PreparedStatement contêm declarações précompiladas.
• Quando um PreparedStatement é executado, o DBMS pode
executar seu comando SQL imediatamente sem ter que
compila-lo primeiro.
PreparedStatement em Loops
• PreparedStatement é tipicamente usando em loops, veja o exemplo
abaixo:
– PreparedStatement updateSales;
– String updateString = "update COFFEES " +"set SALES = ? where
COF_NAME like ?";
– // envia comando a DBMS que o pré-compila para execução
– updateSales=con.prepareStatement(updateString);
– // cria lista com dados
– int [] salesForWeek = {175, 150, 60, 155, 90};
– String [] coffees = {"Colombian", "French_Roast", "Espresso",
– "Colombian_Decaf", "French_Roast_Decaf"};
– int len = coffees.length;
– // executa declaração para todos os dados da lista
– for(int i = 0; i < len; i++) {
– updateSales.setInt(1, salesForWeek[i]);
– updateSales.setString(2, coffees[i]);
– updateSales.executeUpdate();
– }
Download