java 05

background image

Plan wykładu

1. Zaawansowane możliwości JDBC:

rodzaje obiektów

ResultSet

,

dodatkowe możliwości obiektów

ResultSet

,

zapytania prekompilowane,

wywoływanie zdalnych procedur,

transakcje.

2. SSL i bazy danych: przykład HSQLDB.

1

background image

Rodzaje obiektów ResultSet

Ze względu na dostęp do odebranych danych obiekty

ResultSet

dzielimy na:

TYPE_FORWARD_ONLY

– odbiór danych kolejno od pierwszego do ostatniego

rekordu,

TYPE_SCROLL_INSENSITIVE

– dostęp do dowolnych danych, przygotowane

wyniki nie zmieniają sie pod wpływem zmian w bazie.

TYPE_SCROLL_SENSITIVE

– dostęp do dowolnych danych, przygotowane wyniki

zmieniają sie pod wpływem zmian w bazie. Kolejność rekordów nie musi być stała.

Rodzaj dostępu zmieniamy metodą

setFetchDirection(int)

. Do przechodzenia

między rekordami służą metody:

next()

,

previous()

,

last()

,

first()

,

absolute()

,

relative()

.

2

background image

Rodzaje obiektów ResultSet

Obiekty

ResultSet

mogą mieć różne możliwości zmieniana odebranych danych:

1.

CONCUR_READ_ONLY

– dane

nie mogą

być zmienione poprzez metody

updateXXX()

.

najwyższy poziom współbieżności (największa liczba użytkowników jednocześnie

operujących na danych

jedyna możliwość w wersji JDBC 1.0

2.

CONCUR_UPDATABLE

– dane mogą być zmieniane.

zmniejszony poziom współbieżności,

mniejsza wydajność.

3

background image

Rodzaje obiektów ResultSet

Connection con = DriverManager.getConnection(

"jdbc:my_subprotocol:my_subname");

Statement stmt = con.createStatement(

ResultSet.

TYPE_SCROLL_SENSITIVE

,

ResultSet.

CONCUR_UPDATABLE

,

ResultSet.

HOLD_CURSORS_OVER_COMMIT

);

stmt.setFetchSize(25);

ResultSet rs = stmt.executeQuery(

"SELECT col1, col2 FROM table1");

Obiekt

rs

udostępnia

dane w dowolnej kolejności

,

umożliwia zmianę danych

,

nie

jest zamykany przy zatwierdzeniu transakcji

. Do bazy danych zostaje przekazana

sugestia, aby dane odbierać w pakietach po 25 rekordów.

4

background image

Inne operacje na obiektach ResultSet

1. Usuwanie rekordów:

rs.first();

rs.deleteRow();

2. Wstawianie rekordów:

rs.moveToInsertRow();

rs.updateObject(1, myArray);

rs.updateInt(2, 3857);

rs.updateString(3, "Mysteries");

rs.insertRow();

rs.first();

5

background image

Inne operacje na obiektach ResultSet

Uwagi do wstawiania rekordów:

1. Na wstawianym rekordzie można wywoływać metody

getXXX()

. Jeśli

odpowiednia wartość

nie została

ustawiona wcześniej metodą

updateXXX()

wartość zwracana będzie

nieokreślona

.

2. Aktualizacja wartości we wstawianym rekordzie nie zmienia obiektu

ResultSet

.

3. metoda

insertRow()

, dodająca rekord do obiektu

ResultSet

i do bazy danych

zrzuca

SQLException

, jeśli liczba lub typy kolumn nie zgadzają się ze specyfikacją

tabeli w bazie.

4. Bieżącym rekordem jest ten, który był nim przed wywołaniem metody

moveToInsertRow()

.

6

background image

Inne operacje na obiektach ResultSet

Odczytywanie dużych porcji danych:

Statement stmt = con.createStatement();

ResultSet rs = stmt.executeQuery("SELECT xdata FROM Table2");

byte [] buff = new byte[4096];

while (rs.next()) {

InputStream fin = rs.getAsciiStream(1);

for (;;) {

int size = fin.read(buff);

if (size == -1) break;

// wypisanie danych

System.out.write(buff, 0, size);

}

}

7

background image

Prekompilowane zapytania

JDBC przewiduje możliwość tworzenia prekompilowanych zapytań. Służy do tego

klasa

PreparedStatement

wyprowadzona z klasy

Statement

. Przykłady:

PreparedStatement pstmt = con.prepareStatement(

"UPDATE table4 SET m = ? WHERE x =
?");

PreparedStatement pstmt2 = con.prepareStatement(

"SELECT a, b, c FROM Table1",
ResultSet.TYPE_SCROLL_SENSITIVE,

ResultSet.CONCUR_UPDATABLE);

ResultSet rs = pstmt2.executeQuery();

Używanie prekompilowanych zapytań może zwiększyć szybkość działania

programu.

8

background image

Przekazywanie parametrów

Przekazywanie parametrów:

pstmt.setString(1, "Hi");

for (int i = 0; i < 10; i++) {

pstmt.setInt(2, i);

int rowCount = pstmt.executeUpdate();

}

Od wersji JDBC 2.0 można przekazywać parametry typu

SQL BLOB

oraz

SQL

ARRAY

.

PreparedStatement pstmt = con.prepareStatement(

"UPDATE Table3 SET Stats = ? WHERE Depts = ?");

pstmt.setBlob(1, statistics);

pstmt.setArray(2, departments);

9

background image

Przekazywanie dużych parametrów

Przykład pokazuje jak przesłać zawartość pliku jako parametr wejściowy:

File file = new File("/tmp/data");

int fileLength = file.length();

InputStream fin = new FileInputStream(file);

PreparedStatement pstmt = con.prepareStatement(

"UPDATE Table5 SET stuff = ? WHERE index = 4");

pstmt.setBinaryStream (1, fin, fileLength);

pstmt.executeUpdate();

Inny sposób polega na wykorzystaniu typów BLOB i CLOB.

10

background image

Informacje o parametrach

Dodatkowe dane o parametrach prekompilowanego zapytania można uzyskać

poprzez interfejs

ParameterMetaData

(JDBC 3.0):

PreparedStatement pstmt = con.prepareStatement(

"INSERT INTO QUOTAS (ID, LAST, FIRST, DEPT, QUOTA) " +

"VALUES (?, ?, ?, ?, ?)";

ParameterMetaData paramInfo = pstmt.getParameterMetaData();

int numberOfParams = paramInfo.getParameterCount();

for (int i = 1; i <= numberOfParams; i++) {

String dbType = paramInfo.getParameterTypeName(i);

System.out.println("Param " + i " is DBMS type " + dbType);

}

11

background image

Serie prekompilowanych zapytań

Podobnie jak w przypadku

Statement

istnieje możliwość przesłania serii zapytań.

PreparedStatement pstmt = con.prepareStatement(

"UPDATE Table4 SET History = ? WHERE ID = ?");

pstmt.setClob(1, clob1);

pstmt.setLong(2, 350985839);

pstmt.addBatch();

pstmt.setClob(1, clob2);

pstmt.setLong(2, 350985840);

pstmt.addBatch();

int [] updateCounts = pstmt.executeBatch();

Jeśli którekolwiek z zapytań

UPDATE

zwróci cokolwiek ponad liczbę zmienionych

rekordów metoda

executeBatch()

zrzuci wyjątek.

12

background image

Zdalne procedury

Do wywoływania zdalnych procedur używa się obiektów klasy

CallableStatement

:

CallableStatement cstmt = con.prepareCall(

"{call updatePrices(?, ?)}");

cstmt.setString(1, "Colombian");

cstmt.setFloat(2, 8.49f);

cstmt.addBatch();

cstmt.setString(1, "Colombian_Decaf");

cstmt.setFloat(2, 9.49f);

cstmt.addBatch();

int [] updateCounts = cstmt.executeBatch();

Procedura zostanie wywołana dwukrotnie Parametry przekazywane do procedury

nazywamy parametrami IN.

13

background image

Zdalne procedury – odbieranie wyników

Istnieje możliwość ustawienia parametrów przez zdalną procedurę (parametry OUT):

CallableStatement cstmt = con.prepareCall(

"{call getTestData(?, ?)}");

cstmt.registerOutParameter(1, java.sql.Types.TINYINT);

cstmt.registerOutParameter(2, java.sql.Types.DECIMAL);

ResultSet rs = cstmt.executeQuery();

// ... odczyt danych poprzez ResultSet

byte x = cstmt.getByte(1); // odczyt zwracanych parametrow

BigDecimal n = cstmt.getBigDecimal(2);

Procedura wypełnia przekazywane parametry.

14

background image

Zdalne procedury – odbieranie wyników

Numeracja parametrów OUT:

CallableStatement cstmt = con.prepareCall(

"{call getTestData(25, ?)}");

cstmt.registerOutParameter(1, java.sql.Types.TINYINT);

Przy numeracji uwzględniane są tylko parametry oznaczone znakiem zapytania

15

background image

Zdalne procedury – parametry INOUT

Parametry INOUT to takie, które są przekazywane do procedury a następnie

modyfikowane przez wywołaną procedurę.

CallableStatement cstmt = con.prepareCall(

"{call reviseTotal(?)}");

cstmt.setByte(1, (byte)25);

cstmt.registerOutParameter(1, java.sql.Types.TINYINT);

cstmt.executeUpdate();

byte x = cstmt.getByte(1);

Parametr jest najpierw ustawiany – IN a następnie rejestrowany jako OUT. Po

wywołaniu procedury można odebrać jego nową wartość. Zaleca się odebranie

wszystkich danych poprzez obiekt

ResultSet

przed

odebraniem parametrów

INOUT.

16

background image

Transakcje

Transakcje to zbiór operacji zgrupowanych w jednym lub wielu obiektach

Statement

. Aby zakończyć transakcję należy wywołać metodę

commit()

na rzecz

obiuektu

Connection

. Domyślnie metoda

commit()

jest wywoływana po

zakończeniu wykonywania zapytań w ramach jednego obiektu

Statement

. Aby to

zmienić należy użyć metody

setAutoCommit(false)

. Do anulowania zmian

wprowadzonych przez niezatwierdzoną transakcję służy metoda

rollback()

.

17

background image

Poziomy izolacji

Zwykle w systemy baz danych realizują jednocześnie wiele transakcji. Aby

zapewnić kontrolę nad tym procesem wprowadzono tzw. poziomy izolacji, poprzez

które określa się zasady równoległej realizacji kilku transakcji. JDBC przewiduje

pięć poziomów izolacji:

TRANSACTION_NONE

– brak transakcji.

TRANSACTION_READ_UNCOMMITTED

– dopuszcza odczyt danych przed

wywołaniem metody

commit()

.

TRANSACTION_READ_COMMITTED

– inne transakcje nie mogą odczytywać

zmienionych wierszy przed wywołaniem metody

commit()

(dirty reads).

18

background image

Poziomy izolacji

TRANSACTION_REPEATABLE_READ

– dodatkowo chroni przed sytuacją gdy

transakcja odczytuje wiersz, druga transakcja go zmienia a pierwsza ponownie go

odczytuje otrzymując inne dane (non-repetable reads).

TRANSACTION_SERIALIZABLE

– dodatkowo chroni przed sytuacją, gdy jedna

transakcja odczytuje zbiór wierszy spełniający kryteria zawarte w warunku

WHERE

,

następnie druga transakcja wstawia wiersz spełniający ten warunek, po czym

pierwsza transakcja ponownie odczytuje zbiór wierszy dostając nowy rekord

(phantom-read).

Poziomy izolacji ustawia się metodą

setTransactionIsolation(int)

wywołaną na rzecz obiektu klasy

Connection

.

19

background image

Etapy transakcji - Savepoints

Obiekt

Savepoint

(JDBC 3.0) umożliwia częściowe odwrócenie (rollback)

transakcji zamiast całkowitego. Do utworzenia tego obiektu służy metoda

setSavepoint()

.

Statement stmt = con.createStatement();

int rows = stmt.executeUpdate("INSERT INTO AUTHORS VALUES " +

"(LAST, FIRST, HOME) 'TOLSTOY', 'LEO', 'RUSSIA'");

Savepoint save1 = con.setSavepoint("SAVEPOINT_1");

int rows = stmt.executeUpdate("INSERT INTO AUTHORS VALUES " +

"(LAST, FIRST, HOME) 'MELVOY', 'HAROLD', 'FOOLAND'");

...

con.rollback(save1);

...

con.commit();

20

background image

HSQLDB – SSL

21

HSQLDB umożliwia szyfrowanie transmisji. Aby taka transmisja była możliwa

zarówno serwer jak i klient muszą być odpowiednio skonfigurowane. Konfiguracja

serwera:

1. Generowanie certyfikatu serwera:

>keytool -genkey -alias hsqldb -keyalg RSA -validity 30 -keystore
hsqlserver.store

Enter keystore password:

hsqldb

What is your first and last name?

[Unknown]:

localhost

...

Is CN=localhost, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown,
C=Unknown correct?

[no]:

yes

Enter key password for <hsqldb>

(RETURN if same as keystore password):

background image

HSQLDB – SSL

22

Inny sposób generowania klucza – gdy posiadamy certyfikat podpisany przez

zewnętrzne Centrum Autoryzacji”

openssl pkcs8 -topk8 -outform DER -in Xpvk.pem -inform PEM

-out Xpvk.pk8 -nocrypt

openssl x509 -in Xcert.pem -out Xcert.der -outform DER

java DERImport server.store NEWALIAS Xpvk.pk8 Xcert.der

UWAGA: hasło dla klucza musi być takie samo jak hasło dla

server.store

!

background image

HSQLDB – SSL

23

2. Uruchomienie serwera:

>java

-Djavax.net.ssl.keyStorePassword=hsqldb
-Djavax.net.ssl.keyStore=hsqlserver.store
-cp hsqldb.jar
org.hsqldb.Server

[Server@13c5982]: [Thread[main,5,main]]: checkRunning(false)
entered

...

[Server@13c5982]: Using TLS/SSL-encrypted JDBC

...

[Server@13c5982]: Startup sequence completed in 978 ms.

[Server@13c5982]: 2006-03-19 10:16:28.100 HSQLDB server 1.8.0
is online

background image

HSQLDB – SSL

24

Po stronie klienta należy:

1. Uzyskać certyfikat serwera np:

>keytool -export -keystore server.store -alias hsqldb

-file server.cer

Enter keystore password: hsqldb

Certificate stored in file <server.cer>

Jeśli nie mamy dostępu do

server.store

możemy użyć dowolnego narzędzia do

połączenia się z serwerem i odebrania certyfikatu np:

openssl s_client -connect host:port

- zakodowany w

Base64

certyfikat

pojawi sie na ekranie pomiędzy liniami

-----BEGIN CERTIFICATE-----
...
----END CERTIFICATE-----

.

Ten fragment zapisujemy do pliku

server.cer

.

background image

HSQLDB – SSL

25

2. Dodać certyfikat serwera jako zaufany:

>keytool -import -trustcacerts -keystore hsqlclient.store -alias hsql

-file hsqlserver.cer

Enter keystore password:

hsqldb

Owner: CN=localhost, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown,
C=Unknown

Issuer: CN=localhost, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown,
C=Unknown

Serial number: 441d1f43

Valid from: Sun Mar 19 10:07:15 CET 2006 until: Tue Apr 18 11:07:15
CEST 2006

Certificate fingerprints:

MD5: 68:A2:33:BA:FA:4B:08:4A:E2:21:DD:E5:F6:7B:E3:8A

SHA1: 59:6A:4D:66:03:C8:D6:B0:D1:4C:0B:1B:30:E2:90:0F:
88:66:EC:40

Trust this certificate? [no]:

yes

Certificate was added to keystore

background image

HSQLDB – SSL

26

JVM musi zostać poinformowana, ze w pliku

hsqlclient.store

znajdują się

zaufane certyfikaty. Można to zrobić na trzy sposoby:

a) plik

hsqlclient.store

należy dodać do katalogu z zaufanymi certyfikatami

(w JDK zwykle:

JAVA_HOME/jre/lib/security/cacerts

),

b) wywołać program kliencki z opcją:

-Djavax.net.ssl.trustStore=/sciezka/do/hsqlclient.store

c) w kodzie programu klienckiego użyć instrukcji:

System.getProperties().put("javax.net.ssl.trustStore",

"/sciezka/do/hsqlclient.store");

background image

HSQLDB – SSL

27

Przykładowy program klienta:

import java.sql.*;

public class HSQLDb {

public static void main(String[] args){

System.getProperties().put("javax.net.ssl.trustStore",

"/sciezka/do/hsqlclient.store");

System.getProperties().put("javax.net.debug","all");

try {

Class.forName("org.hsqldb.jdbcDriver").newInstance();

} catch (Exception e) { e.printStackTrace(); return; }

background image

HSQLDB – SSL

28

try {

Connection con = DriverManager.getConnection(

"jdbc:hsqldb:

hsqls

://localhost/test", "sa", "");

Statement stmt = con.createStatement();

ResultSet rs = stmt.executeQuery("SELECT NOW()");

rs.next();

System.out.println(rs.getString(1));

con.close();

} catch (SQLException ex) { ex.printStackTrace(); }

}

}

}


Wyszukiwarka

Podobne podstrony:
notatki java 05
JAVA 05 operatory
Java 05 Klasy(1)
Java 05 Klasy
java 05
notatki java 05
r12-05, Programowanie, ! Java, Java Server Programming
Java praca domowa 05
r20-05, Programowanie, ! Java, Java Server Programming
05 WeWy, wisisz, wydzial informatyki, studia zaoczne inzynierskie, jezyk java
O Autorach-05, Programowanie, ! Java, Java Server Programming
r05-05, Programowanie, ! Java, Java Server Programming
r07-05, Programowanie, ! Java, Java Server Programming
r03-05, Programowanie, ! Java, Java Server Programming
rE-05, Programowanie, ! Java, Java Server Programming
r19-05, Programowanie, ! Java, Java Server Programming

więcej podobnych podstron