Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

40
juin 2006 ~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données

Transcript of Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

Page 1: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 1

J530 (JBD)

Java : Base de Données

Page 2: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 2

Jdbc sont des Api d’interaction avec un SGBD Permet à un programme Java d’interagir sur

une base de données, selon un principe de client/serveur.

Le client est le programme Java tandis que le serveur est la base de données. Cette interaction peut se faire localement ou à distance.

Page 3: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 3

Access

Application JAVA

Jdbc Driver Manager

API JDBC

Jdbc ODBC Driver

JDBC DriverPour Oracle

JDBC DriverPour MySql

ODBC Driver

SQL server

MySql

Oracle

Page 4: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 4

Architecture

 DriverManager :est le gestionnaire de tous les drivers chargés par un programme Java.

Chaque programme Java charge le ou les drivers dont il a besoin.

Il y a un driver différent par Sgbd. Exception faites que toutes les données accessibles par ODBC nécessitent le même driver.

Page 5: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 5

Les différents types de drivers 

Il existe 4 types de drivers :   1.    Les drivers génériques JDBC-ODBC : sont

utilisés pour toutes les données accessibles par ODBC ( MS Access SQL Server, Oracle, Excel, ….) L’accès est uniquement local .

pont écrit en partenariat avec Microsoft pour les Sgbdr sous Windows

Ce driver est fourni avec le JDK et s’appelle sun.jdbc.odbc.JdbcOdbcDriver

Page 6: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 6

Type 2

2    Drivers java, partiellement écrits en Java, qui reposent sur des librairies propriétaires. (souvent écrites en C).

Pour ces 2 premiers types, l’appel est de la forme :jdbc :driver :sourceEx : jdbc:odbc:client

Client est le nom source ODBCDéclaration de la source de données ODBC

A partir du panneau de configuration - outils d'administration - sources de données Odbc

Parmi la liste des pilotes disponibles, choisissez celui qui correspond à votre Sgbd

Créer une nouvelle source de données : 1.      choisissez un nom et2.      sélectionnez votre base .

Page 7: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 7

Type 3

   Les drivers 100 % java. Ils communiquent localement ou à distance avec le Sgbd, et disposent d’un protocole réseau générique.

Le driver de type 3 pour Oracle s'appelle OCI

Page 8: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 8

Type 4

1.    Ils sont aussi 100% en java, mais utilisent un protocole propriétaire au SGBD

 Pour ces 2 types, l’appel est de la forme :

jdbc:driver:adresseexemple :

jdbc:mysql://elios.univ-paris8.fr/employes 

ou jdbc:oracle:thin:@elios. univ-paris8.fr:1521:employes

employes est le SID de votre base

Page 9: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 9

Type 4 (suite)

Le driver de type 4 pour Oracle s'appelle thin. Il faut charger un fichier appelé ojdbc14.jar

Sous Eclipse : File - New - Projet, Java projet, nommez le

projet, puis next, choisir l'onglet Librairie, puis add external

jar sélectionner LE FICHIER ojdbc14

Page 10: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 10

Les classes utiles

La méthode statique forName(xxx) de la classe Class, permet le chargement de la classe du driver dans la VM.

La classe java.sql.Connection : permet la connexion à la base de données ou au lien Odbc, elle prend en argument l'url de la base, le login de connexion et le mot de passe.

La classe Statement du package java.sql, permet de créer un canal de communication avec la base.

Page 11: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 11

L’implémentation sous Odbc

class Rbd { Statement stmt = null; Connection con=null; public Rbd () {

try {

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");} catch (Exception e) {

System.out.println("Failed to load JDBC/ODBC driver.");

return; }

Attention aux Majuscules

Page 12: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 12

L’implémentation sous Odbc

try {con = DriverManager.getConnection

( "jdbc:odbc:cnrs", "","");

//URL,login,passwd  stmt = con.createStatement();

  } catch (Exception e) {

System.err.println("problems connecting to ");}

Page 13: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 13

Fermeture de la connexion

public void finalize() { try {

con.close();// fermeture de la connexion

}catch (Exception e) {

e.printStackTrace(); } }

Pour fermer la connexion ODBC lors de

la destruction de l'instance

Page 14: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 14

Implémentation sous Oracle

class Rbd { Statement stmt = null; Connection con=null; public Rbd () {

try {Class.forName("oracle.jdbc.driver.OracleDriver");

} catch (Exception e) {System.out.println("Failed to load Oracle

driver."); return;

}

Page 15: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 15

Implémentation sous Oracle

try {con = DriverManager.getConnection

("jdbc:oracle:thin:@poseidon:1521:orcl","stage","stage");

  stmt = con.createStatement();

  } catch (Exception e) {

System.err.println("problems connecting to ");}

Page 16: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 16

Vrai ou Faux

1. Java se connecte toujours à une base de données avec les droits d'administrateur ?

2. Une seule connexion est possible par lien odbc ?

3. Oracle sous Windows est accessible soit par odbc soit par un driver propre ?

4. Le nom de la base est toujours identique au nom du sid ?

5. Lors d'un lien odbc, le nom de la base n'apparaît jamais en clair ?

à vous

Page 17: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 17

Le ResultSet

java.sql.Statement est un canal de communication établi sur une connexion.

Elle dispose d'une méthode executeQuery qui prend en argument une requête sql de type select et renvoie un Objet de type ResultSet.

Le ResultSet peut être assimilé à un tableau d'enregistrements dans lequel le nom des colonnes correspond au nom des champs de la base.

Les données sont accessibles soit par le nom du champ soit par le numéro de la colonne.

Page 18: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 18

Le ResultSet

Le type des champs de la base de données doit à priori être connu, puisqu'il détermine la méthode à utiliser pour retourner l'objet resultSet.getString (xx) retourne une String resultSet.getInt (xx) retourne un entier

Le déplacement dans un ResultSet est par défaut 'en avance seul'.

La méthode resultSet.next() permet de se positionner sur le premier enregistrement du ResultSet puis d'avancer à l'enregistrement suivant.

Page 19: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 19

Accès aux données

public void recherche(String req) { //génère une requête sur la base. Attention, pas de ; derrière la requête

try { // req contient :  “SELECT * FROM ages”

ResultSet result = stmt.executeQuery( req); result.next();String bdnom = result.getString("nom"); int bdage = result.getInt("age");// result.getString( 1 ) récupère la String de la première

colonne

System.out.println("nom : "+bdnom+" age: "+bdage);

 }

Page 20: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 20

Accès aux données

Les mises à jour, insert, create et update de la base se font par :int res = stmt.executeUpdate(« INSERT INTO ages

VALUES(‘toto’,12)”); boolean getBoolean(int); boolean

getBoolean(String); byte getByte(int); byte getByte(String); Date getDate(int); Date getDate(String); double getDouble(int); double getDouble(String); float getFloat(int); float getFloat(String); int getInt(int); int getInt(String); long getLong(int); long getLong(String); short getShort(int); short getShort(String); String getString(int); String getString(String);

Page 21: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 21

Vrai ou Faux ?

1. Pour récupérer les informations d'une base de données, il faut impérativement connaître le nom des champs de la table ?

2. Il est possible de créer plusieurs Statement à partir d'une connexion ?

3. Le curseur se trouve sur la première ligne du ResultSet après un executeQuery() ?

4. Si la requête sql ne retourne aucun enregistrement de la base, la méthode executeQuery() génère une exception de type SqlException ?

à vous

Page 22: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 22

à vous ...

Créer une base sous Oracle qui contienne une table Identité :

Nom, Prenom, Age (entier), Solde (réel), Etat (booléen).

Afficher la totalité de la table dans une Jtable avec le texte débiteur si le champs Etat de la base contient vrai.

Page 23: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 23

Les dates et objets de grande taille

Le type DATE sql correspond au type java java.sql.Date et s’obtient par getDate()

 BLOB Binary Large Object et CLOB Character

Large Objet de SQL, pour stocker des données de grandes tailles (exemple des fichiers). Ils correspondent en Java au type java.lang.Objet et s’obtiennent avec getObjet()

Page 24: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 24

Curseurs multi-directionnel et dynamique

Par défaut, un ResultSet est en avance seule et en lecture seule.

CreateStatement peut prendre 2 arguments : createStatement(int direction, int maj)

 Les directions sont : ResultSet.TYPE_FORWARD_ONLYResultSet.TYPE_SCROLL_INSENSITIVEResultSet.TYPE_SCROLL_SENSITIVE

Page 25: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 25

Les curseurs

Modificateurs des options du curseurResultSet.CONCUR_READ_ONLYResultSet.CONCUR_READ_UPDATABLE  Curseur multi-directionnel : Stmt =

rs.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY)

Page 26: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 26

Les curseurs

Curseur Dynamique :Stmt =

rs.createaStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_UPDATABLE)

 Les modifications ne sont prises en

compte qu’après un rs.updateRow();

Page 27: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 27

Les différents types de Statement

Ordinaires Pré-compilés Procédures stockées

Page 28: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 28

Modifiez l'exemple précédent pour permettre l'ajout et la suppression de lignes lorsque l'on clique respectivement sur le bouton Ajouter ou Supprimer.

Lors de l'ajout d'un enregistrement, une fenêtre popup permet de saisir les nouvelles données

Lors de la suppression, une fenêtre popup permet de saisir la valeur du champs nom de l'enregistrement à supprimer dans la base

à vous ...

Page 29: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 29

Statement

java.sql.Statement Interprété à chaque exécution Long à l'exécution

ResultSet result = stmt.executeQuery( "SELECT * FROM ages WHERE nom = 'martin' and age < 12 ");

Attention, pas de ; derrière la requête

Page 30: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 30

Pré-compilés

java.sql.PreparedStatement

Paramétrables, préparées pour être exécutées plusieurs fois, gérées par le programme

Rapide, le type de Statement le plus utilisé PreparedStatement pStmt

=con.prepareStatement( “SELECT * FROM ages WHERE nom = ? and age < ? ");

Page 31: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 31

Les paramètres

Les paramètres sont renseignés par leur position : pStmt.setString (1,"paul") le 1er ? est paul pStmt.setInt (2, 23) le 2ème ? est 23

 Exécution de la requête une fois que les

paramètres sont renseignés : pStmt.executeQuery(); Ou executeUpdate() pour les autres types

de requêtes

Page 32: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 32

Dans le programme précédent, remplacez l'utilisation de requêtes simples par des requêtes pré-compilées.

Insérer un champ Inscription de type Date que vous ferez afficher dans votre Jtable

à vous ...

Page 33: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 33

Procédures Stockées

java.sql.CallableStatement Paramétrables, Ecrites dans le langage interne au Sgbd

CallableStatement csStmt. = con.prepareCall(" { call pubs.GetRage(?) }");

csSstmt.setInt (1, 23) le 1er paramètre est 23csSstmt.executeQuery();

Page 34: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 34

Transactions

Une transaction est un groupe de requêtes devant être exécutées de façon indivisible. Par exemple, le transfert d'un ordre de virement, les ordres de mise à jour de table ...

La transaction doit être validée (commit) ou annulée ( rollback)

  Au début de la transaction:

con.setAutoCommit( false);  Statement st = ….... INSERT ....

Page 35: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 35

Transactions

A là fin de la transaction

validation de la transaction:con.commit();

ou annulation de la transaction

con.rollback();

Page 36: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 36

Traitement par lots

Objectif : réduire le coût d'une série de mises à jourStatement stmt = con.createStatement(); // ajout des différentes requêtesst.addBatch("INSERT INTO ages VALUES( 'Paul',12));st.addBatch("INSERT INTO ages VALUES( 'Pierre',14));st.addBatch("INSERT INTO ages VALUES( 'Raoul',112)); // exécution des requêtes int [] res = stmt.executeBatch();

Page 37: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 37

Recherche de la structure de la base

Permet de découvrir le schéma de la base à l'exécution

Récupération des enregistrements d'une table :Statement stmt = con.createStatement();ResultSet rs = st.executeQuery("SELECT * FROM

ages"); 

Récupération d'un objet de la classe ResultSetMetaData décrivant le ResultSet

ResultSetMetaData rsmd =rs.getMetaData();

Page 38: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 38

Recherche de la structure de la base

Interrogation du ResultSetMetaData pour découvrir le schéma de la table ages :

int colnbre = rsmd.getColumnCount(); String colLabel = rsmd.getColumnLabel(i);

String colType = rsmd.getColumnTypeName(i);

Informations sur les tables contenues dans la baseDataBaseMetaData dbmd = con.getMetaData();

  Récupération des tables utilisateur de la base :

ResultSet tables = dbmd.getTable(null,null,null, {"Table"});

Page 39: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 39

Recherche de la structure de la base

Récupération des noms de table

while( tables.next() ) {String tableName =

tables.getString ("TABLES_NAME");}

Page 40: Juin 2006~ Brigitte Groléas ~ 1 J530 (JBD) Java : Base de Données.

juin 2006 ~ Brigitte Groléas ~ 40

Valeur unique générée automatiquement

Valeur incrémentée à chaque ajout d'enregistrementType auto_increment (MySQL) , serial (PostGReSQL)CREATE TABLE users ( id INT, AUTO_INCREMENT, nom

VARCHAR(30)) String req = "INSERT INTO users (nom) VALUES ('paul')";Stmt.executeStatement( req,

Statement.RETURN_GENERATED_KEYS );ResultSet rs = stmt.geGenerateKeys();rs.next();int key = rs.getInt(1);