Sunteți pe pagina 1din 45

Java Data Base Connectivity

Connexion aux bases de donnes

Rappels
API JDBC
Pilotes JDBC
Connexion
ResultSet
Requtes interprtes
Requtes prpares

Modlisation des donnes


Cration d'un schma entits/associations
Entits :
identifiables ( notion de cl)
pertinente pour l'application
caractrises par des proprits (attributs)

Reprsentation graphique

OMT, Merise, UML


3

Schma relationnel
schma entit/association

A
attr

schma relationnel

- tables A et B
- la cl de A devient un attribut de B
( cl trangre)

- tables A et B
- table AB pour l'association
avec cl=(cl A,cl B)
- attribut de l'association = attribut de la
table AB

Mysql
Types mysql :
CHAR(n)
INTEGER
VARCHAR(n)
DECIMAL(m,n)
DATE
TIME
DATETIME
TEXT

chane de longueur n
entier
chane de longueur <=n
m= longueur partie entire, n=lg partie dcimale
jour, mois, an
heure, minutes et secondes (temps sur 24h)
date et horaire
texte de longueur quelconque

Serveur de bases
de donnes
Relationnelles
SQL

Expression des contraintes


DEFAULT val
NOT NULL

val = valeur par dfaut


valeur obligatoire

Cls
PRIMARY KEY( num)
l'attribut num est la cl primaire
FOREIGN KEY(idad) REFERENCES Personne
la cl trangre idad rfrence la cl primaire de la table Personne
5

Correspondances des types de


donnes SQL/Java
Type SQL
CHAR VARCHAR

Type Java
String

Mthode getter
getString()

INTEGER

int

getInt()

TINYINT

byte

getByte()

SMALLINT

short

getShort()

BIGINT

long

getLong()

BIT

boolean

getBoolean()

REAL

float

getFloat()

FLOAT DOUBLE

double

getDouble()

NUMERIC DECIMAL java.math.BigDecimal getBigDecimal()


DATE

java.sql.Date

getDate()

TIME

java.sql.Time

getTime()

TIMESTAMP

java.sql.Timestamp

getString()
6

SQL
SELECT attr, ... FROM table, ... WHERE condition
o condition est une expression sur les attributs des tables du FROM
les oprateurs applicables sont :
oprateurs arithmtiques : +,*,-, ...
oprateurs relationnels : <,>,>=,... ,!=
oprateurs logiques : AND, NOT, OR
BETWEEN, IN, LIKE
caractres joker
'_'
remplace n'importe quel caractre
'%'
remplace n'importe quelle chane de caractres

Destruction
DELETE FROM table WHERE condition

Modification
UPDATE table SET attr1=val1,Ai=vali,... WHERE condition

EXEMPLES
SELECT *
FROM Boutique
WHERE nom IN ('Dijon','Lyon')

nom

ventes

date

Dijon

1500

05-Jan-2009

Lyon

2400

21-Jan-2009

nom

ventes

Dijon
1500
SELECT *
FROM Boutique
Chalon 400
WHERE Date BETWEEN '06-Jan-2009' AND '11-Jan-2009'

SELECT *
FROM Boutique
WHERE nom LIKE '%ON%'

date
05-Jan-2009

09-Jan-2009

nom

ventes

date

Dijon

1500

05-Jan-2009

Chalon

400

09-Jan-2009

Lyon

2400

21-Jan-2009

SELECT nom
FROM Boutique
WHERE ventes > 1000 OR (ventes < 500 AND ventes > 275)
8

Introduction JDBC

Pour les applications web utilisant une ou plusieurs


bases de donnes, les servlets et l'API JDBC offrent une solution :

efficace, la connexion est maintenue durant tout


le cycle de vie de l'application
flexible, l'accs une base de donnes dpend peu
de son fournisseur. Il est facile de porter une application
vers une base de donnes d'un autre fournisseur

Principe de fonctionnement de JDBC


Permet un programme Java d'interagir
localement ou distance
avec une base de donnes relationnelle
Fonctionne selon un principe client/serveur
client = le programme Java
serveur = la base de donnes
Principe
le programme Java ouvre une connexion
il envoie des requtes SQL
il rcupre les rsultats
...
il ferme la connexion
10

Architecture 3 tiers

utilisateur

couche
prsentation
interface
web

couche
mtier
(domaine)

couche
d'accs
aux
donnes

BD

les trois couches sont rendues indpendantes grce l'utilisation


d'interfaces Java

11

API JDBC
l'API JDBC se trouve dans le paquetage java.sql
l'API JDBC est constitue d'un ensemble d'interfaces pour interagir
avec des bases de donnes
l'API JDBC ne fournit donc aucune implmentation des comportements
spcifis par les interfaces
l'API JDBC permet d'excuter des instructions SQL et
de rcuprer les rsultats
La version la plus rcente de l'API est la version 3.0

12

Pilotes JDBC (1/2)


Le pilote JDBC a pour rle de permettre l'accs un systme de bases de
donnes particulier. Il gre le dtail des communications avec un type de SGBD
A une API JDBC correspond plusieurs implmentations selon les
fournisseurs (un type de driver par SGBD Oracle, Sybase, Access, ...).
Il en existe pour la plupart des SGBD relationnels
Le pilote implmente l'interface java.sql.Driver
Il existe un driver gnrique JDBC-ODBC pour toutes les donnes
accessibles par ODBC
- SGBD : MS Access, SQL Server, Oracle, dBase, ...
- tableurs : Excel, ...
- tout autre application conforme ODBC

13

Gestionnaire de pilotes
DriverManager
DriverManager est une classe, gestionnaire de tous les drivers
chargs par un programme Java

Chaque programme Java charge le (ou les) drivers dont il a


besoin
L'enregistrement des pilotes est automatique

14

Java et les BD

application

Connexion
Connexion
Gestionnaire
Gestionnairede
depilotes
pilotes

Pilote
PiloteOracle
Oracle

Pont
PontJDBC_ODBC
JDBC_ODBC

Pilote
PiloteSybase
Sybase

Pilote
PiloteODBC
ODBC
BD
Oracle

BD
Sybase
BD
ODBC
15

Connexion une base de donnes


Disposer de l'URL d'un pilote pour le SGBD
com:mysql:jdbc:Driver
Sun:jdbc:odbc:JdbcOdbcDriver
jdbc:sqlite
Charger le pilote
Class.forName("com:mysql:jdbc:Driver");
// cration d'une instance du pilote
// enregistrement automatique auprs du DriverManager
Etablir l'URL (protocole) de la base
String dbUrl="jdbc:mysql://localhost:3306/maBD";
String dbUrl="jdbc:sqlite:mesdata/mesbds/mags.sqlite";
Ouvrir la connexion : le DriverManager choisit le pilote appropri
cette URL parmi l'ensemble des pilotes disponibles.
Connection dbcon =
DriverManager.getConnection(dbUrl,user,password);
Connection dbcon = DriverManager.getConnection(dbUrl);
16

Code de connexion : exemple (1/2)

try {
//Dclaration du driver :
Class.forName("com.mysql.jdbc.Driver");
//Url de connexion
String dbUrl="jdbc:mysql://localhost:3306/laboBD";
//Profil/mot de passe
String user = "root";
String password = "19AB5";
//connexion la base
dbcon = DriverManager.getConnection(dbUrl,user,password);
}

17

Code de connexion : exemple (2/2)


catch( ClassNotFoundException e ){
// erreur de chargement du pilote
}
catch( SQLException e ){
// erreur d'obtention de la connexion
}
finally{
// fermeture de la connexion pour librer
// les ressources de la BD
try{
if (dbcon!=null) dbcon.close();
}
catch(SQLException e){...}
}

18

Sqlite : connexion

Class.forName("org.sqlite.JDBC");
Connection conn = DriverManager.getConnection
("jdbc:sqlite:mesdata.mesbds.magss.sqlite");

Fermeture de la connexion
conn.close();

19

3 types de requtes
interface
Statement

interface
PreparedStatement

requtes interprtes
chaque excution

requtes
prcompiles

interface
CallableStatement
requtes stockes
dans la base
20

L'interface ResultSet

Un objet de type ResultSet est une table reprsentant le rsultat d'une


requte une base de donnes
Le nombre de lignes du tableau peut tre nul.
Les donnes de la table sont accessibles ligne par ligne grce un curseur
Un resultSet gre un curseur sur la ligne courante de la table des donnes
satisfaisant aux conditions de la requte.

21

Excution d'une requte SQL de type


Statement (1/2)

Le type de rsultat obtenu dpend de la manire dont on souhaite manipuler


le ResultSet
3 constantes de types :
TYPE_FORWARD_ONLY ( le curseur se dplace uniquement vers l'avant )
TYPE_SCROLL_INSENSITIVE ( le curseur se dplace en avant et en arrire mais le
Resultset est insensible aux modifications apportes la BD durant le traitement)
TYPE_SCROLL_SENSITIVE ( le curseur se dplace en avant et en arrire mais les
changements faits la BD durant le traitement sont reflts dans le ResultSet)

2 constantes de concurrence :
CONCUR_READ_ONLY ( les donnes du Resultset ne peuvent pas tre modifies)
CONCUR_UPDATABLE ( des modifications de la BD peuvent tre effectues via le
Resultset )

22

Exemple

//
//
//
//
//

Crer un objet de la classe java.sql.Statement


Statement stmt = dbcon.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);

indique que le ResultSet est scrollable et non


modifiable.
ResultSet.CONCUR_UPDATABLE indiquerait
qu'un seul utilisateur la fois peut modifier
la donne

Statement stmt = dbcon.createStatement(


ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
// lorsqu'on apporte un changement au ResultSet, on peut y
// accder par la suite car le type est "scrollable" et on peut
// rcuprer sa valeur car le type est "SENSITIVE"
Pour que les modifications apportes au
Resultset prennent effet dans la base, il faut appliquer
les mthodes updateRow
23

Sqlite : cration
Statement stat = conn.createStatement();
stat.executeUpdate("drop table if exists magasins;");
stat.executeUpdate("create table magasins
(id, magasin,produit,prix);");

24

Excution d'une requte SQL de type


Statement (2/2)
Par dfaut, le ResultSet n'est ni scrollable, ni modifiable
Statement stmt = dbcon.createStatement();
dbcon.createStatement(TYPE_FORWARD_ONLY,
CONCUR_READ_ONLY);
Construire la requte SQL
Soit la table personne(nom,prenom,age)
String reqSQL = "select * from personne";
Excuter la requte
ResultSet rs = stmt.executeQuery( reqSQL );
25

Exploiter les rsultats d'une requte


(1/5)
A la cration du ResultSet, le curseur est plac avant la premire ligne (N1).
Pour le dplacer, on dispose des mthodes :

next() dplacement d'une ligne en avant

previous() dplacement d'une ligne en arrire

first() dplacement vers la premire ligne

last() dplacement vers la dernire ligne

beforeFirst() dplacement avant la premire ligne.


Si le ResultSet est vide, cela n'a aucun effet.
afterLast() dplacement aprs la dernire ligne.
Si le ResultSet est vide, cela n'a aucun effet.

relative(int i) dplace de i lignes par rapport la position courante

absolute(int i) dplace le curseur vers la i-me ligne

26

Exploiter les rsultats d'une requte


(2/5)
Dplacement absolu absolute( int i)
i>0 dplacement vers la ligne numro i

rs.absolute(1) => dplacement vers la ligne 1


i<0 dplacement partir de la fin
rs.absolute(-1) => dplacement sur la dernire ligne
rs.absolute(-3)=> si 30 lignes, dplacement vers ligne 28

Dplacement relatif relative( int i)


On spcifie le nombre de dplacements partir de la ligne courante
i>0 => dplacements en avant
i<0 => dplacements en arrire

rs.absolute(4); // curseur sur la 4me ligne


rs.relative(-3); // curseur sur la premire ligne
rs.relative(2); // curseur sur la 3me ligne

27

Exploiter les rsultats d'une requte


(3/5)
On rcupre le contenu d'une ligne du ResultSet colonne par colonne
Les mthodes d'accs sont construites sur le modle : getXXX (XXX tant
un type primitif ou String)
La colonne est spcifie soit par son nom, soit par son numro (la premire
colonne est numrote 1)
par son nom
String getString(String nomAttribut)
float getFloat(String nomAttribut)
par le numro de la colonne qui lui correspond
String getString(int indexColonne)
float getFloat(int indexColonne)
idem pour les int, double, long, boolean, Object

28

Exploiter les rsultats d'une requte


(4/5)
Pour obtenir le n de la ligne courante
int getRow()
rs.absolute(5);
int i = rs.getRow(); // i=5
Pour tester la position dans le Resultset
isFirst, isLast, isBeforeFirst, isAfterLast.
if (rs.isAfterLast() == false) {
rs.afterLast(); }

29

Exploiter les rsultats d'une requte


(4/5)

String reqSQL = "select * from personne";


ResultSet rs = stmt.executeQuery( reqSQL );
while (rs.next()){
String prenom = rs.getString("prenom");
int age = rs.getInt("age");
}

30

Sqlite : interrogation
ResultSet rs = stat.executeQuery
("select * from magasins;");
while (rs.next()) {
System.out.println("magasin = " +
rs.getString("magasin"));
System.out.println("produit = " +
rs.getString("produit"));
System.out.println("prix = " +
rs.getString("prix"));
}
rs.close();
31

Mises jour de table (1/2)


Il est prfrable que le ResultSet soit scrollable lors d'une mise
jour
Statement stmt = con.createStatement(
ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
Pour mettre jour, 2 mthodes:
updateXXX avec 2 paramtres (nom et valeur de la colonne)
updateRow() rendre effective la mise jour

32

Mises jour de table (2/2)


Nom
Meyer
Legrand
Dupont

Prnom
Ren
La
Marcel->Robert

Age
54->37
18
43

String reqSQL = "select * from personne";


ResultSet rs = stmt.executeQuery( reqSQL );
rs.next();
rs.updateInt("Age",37);
rs.last();
rs.updateString("Prnom","Robert");
rs.updateRow();

33

L'interface ResultSetMetaData

Permet d'obtenir la description du contenu du ResultSet


ResultSetMetaData metaData = rs.getMetaData();
A partir de cette information, obtenir le nombre de colonnes du rsultat
int nbCols = metaData.getColumnCount();
Obtenir le nom de la colonne connaissant son indice ( partir de 1)
String nomCol = metaData.getColumnName( int i );

34

Exemple
ResultSet rs = stmt.executeQuery( "SELECT * FROM personne" );
StringBuffer resultat = new StringBuffer();
ResultSetMetaData metaData = rs.getMetaData();
int nbCols = metaData.getColumnCount();
for ( int i=1;i<=nbCols;i++ )
resultats.append( metaData.getColumnName( i )+"\t" );
resultats.append( "\n" );
while ( rs.next() ){
for ( int i=1;i<=nbCols;i++ )
// pour simplifier, chaque donne est du type Object
// sinon le type de la valeur est obtenu par getColumnType
resultats.append( rs.getObject( i )+"\t" );
resultats.append( "\n" );
}

35

Requtes prpares
L'excution de chaque requte une BD ncessite 4 tapes :
analyse
compilation
optimisation
Excution
Pour des requtes identiques, les 3 premires tapes n'ont pas tre
effectues de nouveau.
Avec la notion de requte prpare, les 3 premires tapes ne sont
effectues qu'une seule fois.
JDBC propose l'interface PreparedStatement qui drive de l'interface
Statement pour modliser cette notion.
36

Excution d'une requte SQL de type


PreparedStatement
Avec l'interface Statement, on crivait :
Statement smt = dbcon.createStatement();
ResultSet rs = smt.executeQuery("SELECT * FROM personne" );

Avec l'interface PreparedStatement, on crit :


PreparedStatement pSmt =
dbcon.prepareStatement("SELECT * FROM personne" );
ResultSet rs = pSmt.executeQuery();

On voit que la requte est prpare l'avance et n'est donc pas transmise
en argument au moment de l'excution ( executeQuery()).

37

Excution d'une requte SQL de type


PreparedStatement
Pour prparer des requtes paramtres de la forme :
SELECT nom FROM Personnes WHERE age > ? AND adresse = ?
On utilise les PreparedStatement avec les mthodes
setType(numroDeLArgument, valeur)
Type reprsente le type de l'argument
numroDeLArgument reprsente le numros de l'argument (commenant
1 dans l'ordre d'apparition dans la requte).
valeur reprsente la valeur qui lui est associe
Exemple :
PreparedStatement pSmt = dbcon.prepareStatement
("SELECT nom FROM Personne WHERE age > ? AND prenom=?" );
pSmt.setInt(1, 22);
pSmt.setString(2, "Adrien");
ResultSet rs = pSmt.executeQuery();
38

Excution d'une requte SQL de type


PreparedStatement
PreparedStatement psmt = dbcon.prepareStatement(
"update personne set nom = ? where prenom like ?");
psmt.setString(1, "Bauer");
psmt.setString(2, "Ren");
int i = psmt.executeUpdate():

On a chang en Bauer le nom de la personne dont le prnom est Ren


La valeur retourne par executeUpdate() est le nombre de lignes mises
jour

39

Sqlite : insertion
PreparedStatement prep = conn.prepareStatement(
"insert into magasins (magasin,produit,prix)
values (?, ?, ?);");
prep.setString(1, "fdk");
prep.setString(2, "cafe");
prep.setFloat(3, 0.40f);
prep.addBatch();
prep.setString(1, "fdk");
prep.setString(2, "soda");
prep.setFloat(3, 1.10f);
prep.addBatch();
prep.setString(1, "fdk");
prep.setString(2, "barres");
prep.setFloat(3, 0.90f);
prep.addBatch();
conn.setAutoCommit(false);
prep.executeBatch();
conn.setAutoCommit(true);

40

Procdures stockes (1/2)

Les procdures stockes permettent d'embarquer du code


procdural directement dans la base

Elles excutent une ou plusieurs requtes SQL

Intrt :

Elles sont prcompiles

Ne ncessitent pas de trafic rseau

JDBC utilise la classe java.sql.CallableStatement

Syntaxe d'appel des procdures stockes

{call nom-proc-stoke(?,?)}

// procdure sans rsultat

{?=call nom-proc-stoke(?,?)} // retour d'une valeur

41

Procdures stockes (2/2)


CallableStatement cstmt =
dbcon.prepareCall("{call nom-proc-stoke(?,?)}");
cstmt.registerOutParameter(2,java.sql.Types.FLOAT);
// indique que le second paramtre donne le rsultat
cstmt.setInt(1,ID);
// fixe la donne en entre
cstmt.execute();
//excute la procdure stocke
System.out.println("Solde : " +cstmt.getFloat(2);
// affiche le rsultat de l'excution de la procdure
// stocke figurant dans le second paramtre
42

Exercice

Soit une BD de nom " mags ", constitue de la seule table


magasins :
(ID, magasin, produit, prix)

Cette BD est accessible avec les identifiants (" root ", " 2dwsk8 ")

Inutile pour sqlite

Ecrire le morceau de code Java permettant d'afficher le rsultat


de la requte : " liste des produits dont le prix est infrieur 50 "
sous la forme :
produit
.....
.....

prix
.....
.....

On utilisera pour cela les requtes prpares de JDBC


Complter le code pour modifier la table afin de ramener les prix
43
de 50 49,95

Utilisation de sqlite

SQLite : gestionnaire de BD sans ncessit d'un serveur de BD

Tlcharger le pilote JDBC pour SQLite : sqlitejdbc-v056.jar

Sous firefox, tlcharger et installer le add-on :

https://addons.mozilla.org/en-US/firefox/addon/sqlite-manager/

Sous firefox, lancer le manager (menu outils)

Entrer le nom de la BD

Connecter la BD

Crer les tables

Insrer les valeurs

44

Exporter une BD Mysql


Sous wamp, il faut exporter la base pour obtenir le script sql correspondant
On ajoute ensuite une ligne qui permet de vrifier l'existence d'une Base de mme nom

DROP DATABASE IF EXISTS `tp`;


CREATE DATABASE `tp` DEFAULT CHARACTER SET latin1 COLLATE
latin1_swedish_ci;
USE `tp`;
CREATE TABLE `personne` (`nom` varchar(20) NOT NULL default '',`prenom`
varchar(20) NOT NULL default '',`age` tinyint(4) NOT NULL default '0',PRIMARY KEY
(`nom`,`prenom`)) ENGINE=MyISAM DEFAULT CHARSET=latin1;
INSERT INTO `personne` VALUES ('Meyer', 'Luc', 30);
INSERT INTO `personne` VALUES ('Dupont', 'Ren', 40);
Il suffit d'enregistrer le script dans un fichier sur votre cl usb
ATTENTION : chaque commande sql est situ sur une seule ligne
45

S-ar putea să vă placă și