38
Y. Parchemal UPD 2010 ch.. 5 - 2 Java DataBase Connections JDBC est une api permettant l'utilisation de bases de données indépendamment du type de SGBD utilisé. Il suffit d'indiquer le driver correspondant au gestionnaire de bases de données utilisé et de faire les requêtes en SQL standard.

Java DataBase Connections - plenadis.math-info.univ-paris5.frplenadis.math-info.univ-paris5.fr/java/jdbc.pdf · Y. Parchemal UPD 2010 ch.. 5 - 2 Java DataBase Connections JDBC est

Embed Size (px)

Citation preview

Y. Parchemal UPD 2010 ch.. 5 - 2

Java DataBase Connections

JDBC est une api permettant l'utilisation de bases de données

indépendamment du type de SGBD utilisé.

Il suffit d'indiquer le driver correspondant au gestionnaire de bases de données utilisé et de faire les requêtes en SQL standard.

Y. Parchemal UPD 2010 ch.. 5 - 3

JDBC

Utilisation de plusieurs classes et interfaces du package java.sql

java.sql.DriverManagerUne classe d'utilitaire permettant en particulier d'obtenir une connexion à la base de données

Des interfaces, en particulier :

java.sql.Connection

java.sql.Statement : les requêtes

java.sql.ResulSet : les résultats des requêtes

$<bd>

Y. Parchemal UPD 2010 ch.. 5 - 4

• 1 Charger la classe correspondant au driver souhaitéClass.forName("oracle.jdbc.driver.OracleDriver")

• 2 Obtenir une connexion à la base de donnéesConnection connexion = DriverManager.getConnection(…,…,…);

• 3 Construire et exécuter une requêteStatement stmt=connexion.createStatement( );ResultSet rs = stmt.executeQuery("…");ouint count = stmt.executeUpdate("…");

• 4 Traiter le résultat obtenuen utilisant les méthodes de ResultSet

. 5. Fermer le statement et la connexion connexion.close( );

Les différentes étapes pour utiliser une base de données

Y. Parchemal UPD 2010 ch.. 5 - 5

Le driver JDBC est une classe implémentant l'interface java.sql.Driver.Elle est spécifique à un SGBD précis.

exemple de chargement de driver :Class.forName("com.mysql.jdbc.Driver");// pour mysqlClass.forName("oracle.jdbc.driver.OracleDriver");// pour oracleClass.forName("jdbc.odbc.JdbcOdbcdriver");// pour odbcClass.forName("org.postgresql.Driver"); // pour postgresql

Pour indiquer le driver utilisé, on utilise la méthode Class.forName.Elle permet le chargement dynamique de classe (nous revenons en détail sur ce point dans la suite du cours).

1. Charger le bon driver jdbc

Y. Parchemal UPD 2010 ch.. 5 - 6

class DriverManager{.../** Attempts to establish a connection to the given database URL. The * DriverManager attempts to select an appropriate driver * from the set of registered JDBC drivers. * @ param url - a database url of the form jdbc:subprotocol:subname * @ param user - the database user on whose behalf the connection is being made * @ param password - the user's password * @ return a connection to the URL * @ throw SQLException if a database access error occurs */public static Connection getConnection(String url,String user,String  password)

throws SQLException {…}

Connexion connexionAvecMysql = DriverManager.getConnection("jdbc:mysql://localhost/pary","root","aw3peZ");

url avec ODBC : "jdbc:odbc:nomDeMaBase"url avec Postgres : "jdbc:postgresql://urlServeur/nomDeMaBase"

url avec mysql : "jdbc:mysql://urlServeur/nomDeMaBase"

La syntaxe des urls

2. Se connecter à la base de données

Y. Parchemal UPD 2010 ch.. 5 - 7

Les problèmes classiques avant d'arriver à exécuter un programme utilisant jdbc :

- la classe du driver et les classes associées (regroupées dans un jar) doivent être dans le classpath au moment de l'exécution

- l'url de la base doit être écrite correctement

- l'user et son password doivent être enregistrés dans le SGBD …

- la base doit être utilisable à partir du poste où l'on exécute le programme Java

Problèmes classiques lors des premières utilisation de jdbc Problèmes classiques lors des premières utilisation de jdbc

Y. Parchemal UPD 2010 ch.. 5 - 8

public static void main(String [ ] args) {try { // Tout d'abord chargement dynamique du driver

Class.forName("com.mysql.jdbc.Driver");// puis appel de la méthode getConnexionString nomBase="pary";String hostname="www.ens.math-info.univ-paris5.fr";String urlBd = "jdbc:mysql://"+hostname+"/"+nomBase;

String user="pary";String password="xxxxxxxx";Connection connection=DriverManager.getConnection(urlBd,user,password ); System.out.println("Connexion réalisée !");connection.close( ); }

catch (SQLException e){ System.out.println("Connexion non effectuée !"); e.printStackTrace( ); }

catch (ClassNotFoundException e){System.out.println("Vérifier que la classe du driver est dans le classpath"); e.printStackTrace( );} }

Exemple : se connecter à une base de données

Y. Parchemal UPD 2010 ch.. 5 - 9

// tout d'abord, récupération d'un Statement à partir de la connexionStatement stmt = connection.createStatement( );

// puis exécution de la requête en utilisant :a) executeUpdate pour les requêtes de mise à jour de la base

INSERT, CREATE, DELETE ...

b) executeQuery pour les requêtes interrogeant la baseSELECT

3 exécution de requêtes

Y. Parchemal UPD 2010 ch.. 5 - 10

// tout d'abord, récupération d'un Statement à partir de la connexionStatement stmt = connection.createStatement( );

// puis exécution de la requêteint count = stmt.executeUpdate(

"INSERT INTO QUESTION(intitule,reponse,auteur,niveau)"+ "VALUES (\"Les classes sont toujours abstraites\",\"non\",\"pary\",1)" );

/** Executes the given SQL statement, which may be an INSERT, UPDATE, or DELETE statement * or an SQL statement that returns nothing, such as an SQL DDL statement. * @param sql - an SQL INSERT, UPDATE or DELETE statement * or an SQL statement that returns nothing * @ return either the row count for INSERT, UPDATE or DELETE statements, * or 0 for SQL statements that return nothing * @ throws SQLException - if a database access error occurs or the given SQL statement produces a ResultSet object*/public int executeUpdate(String sql) throws SQLException

3a executeUpdate

Y. Parchemal UPD 2010 ch.. 5 - 11

//La fonction ci dessous permet de créer la table question si elle n'existait pas déjà

/** crée les tables nécessaires pour les comptes en utilisant la 'connection' fournie*/private static void createIfNotExistsTableQuestion(Connection connection)

throws SQLException{Statement statement = connection.createStatement( );String request = "CREATE TABLE question" +

" (intitule VARCHAR(80),reponse VARCHAR(80),"+ "auteur VARCHAR(80),niveau INTEGER not NULL)";

try{statement .executeUpdate(request);}

catch (SQLException ignored) {System.out.println(request);ignored.printStackTrace( );}

finally {if (statement !=null) statement.close( );}

}

3a exemple de création de table avec executeUpdate

Y. Parchemal UPD 2010 ch.. 5 - 12

Statement stmt = connection.createStatement( );

ResultSet rs= stmt.executeQuery("SELECT intitule,reponse FROM question");

// Interface Statement/** Executes the given SQL statement, which returns a single ResultSet object. * @param sql - an SQL statement to be sent to the database sql ,

typically a static SQL SELECT statement * @ return a ResultSet object that contains the data produced by the given query;

never null * @ throws SQLException - if a database access error occurs or the given SQL statement produces anything other than a single ResultSet object */public ResultSet executeQuery(String sql) throws SQLException{…}

3b executeQuery

Y. Parchemal UPD 2010 ch.. 5 - 13

while (rs.next( )){Object obj1 = rs.getObject(1);// l'intituléObject obj2 = rs.getObject(2);// la réponseSystem.out.println("("+obj1+","+obj2+")") ;}

4 Utiliser le ResultSet

La méthode next de ResultSet permet de parcourir une à une les lignes du résultat. La méthode getObject de ResultSet permet de récupérer la valeur d'une colonne sur la ligne courante.

ResultSet rs= stmt.executeQuery("SELECT intitule,reponse FROM question");

La méthode next permet de passer à la ligne suivante. Elle rend false s'il n'y a pas de ligne suivante

Le premier appel à next permet de se positionner sur la première ligne

4 Utiliser le ResultSet

Y. Parchemal UPD 2010 ch.. 5 - 14

/** deplace le curseur vers la ligne suivante @return vrai si il y a une ligne suivante @exception SQLException si une erreur survient lors de l'accès à la base*/public boolean next( ) throws SQLException

/** rend l'objet de la colonne n° 'numCol' de la rangée courante de ce ResultSet@exception SQLException si une erreur survient lors de l'accès à la base*/public Object getObject(int numCol) throws SQLException

/** rend l'objet de la colonne de nom 'nomCol' de la rangée courante de ce ResultSet@exception SQLException si une erreur survient lors de l'accès à la base*/public Object getObject(String nomCol) throws SQLException

Il existe aussi de nombreuses autres méthodes similaires getString, getDouble( ) … utilisable pour certains types de données SQL

Quelques méthodes de l'interface java.sql.ResultSet

Y. Parchemal UPD 2010 ch.. 5 - 15

SQL classe de getObject( ) Autre fonction utilisable

CHAR String String getString(…)VARCHAR String String getString(…)INTEGER Integer int getInt(…)REAL Float float getFloat(…)DOUBLE Double double getDouble(…)TIMESTAMP java.sql.TimeStamp TimeStamp getTimeStamp(…)

ResultSet rs= stmt.executeQuery("SELECT niveau,auteur FROM question");while (rs.next( )){

int niveau = rs.getInt(1);String auteur = rs.getString(2);System.out.println("( niveau : "+niveau+" auteur :"+auteur+")") ;}

Quelques correspondances entre type SQL et type Java

Y. Parchemal UPD 2010 ch.. 5 - 16

public interface ResultSetA table of data representing a database result set, which is usually generated by executing a statement that queries the database. A ResultSet object maintains a cursor pointing to its current row of data. Initially the cursor is positioned before the first row. The next method moves the cursor to the next row, and because it returns false when there are no more rows in the ResultSet object, it can be used in a while loop to iterate through the result set. A default ResultSet object is not updatable and has a cursor that moves forward only. Thus, it is possible to iterate through it only once and only from the first row to the last row.

The ResultSet interface provides getXXX methods for retrieving column values from the current row. Values can be retrieved using either the index number of the column or the name of the column. In general, using the column index will be more efficient. Columns are numbered from 1. For maximum portability, result set columns within each row should be read in left-to-right order, and each column should be read only once.

extraits de la documentation en ligne de ResultSet

Y. Parchemal UPD 2010 ch.. 5 - 17

String srequete="SELECT intitule, reponse FROM question "+"WHERE question.niveau= ? AND question.auteur=? "

PreparedStatement stmt = connexion.prepareStatement(srequete);stmt.setInt(1,4);//niveau = 4stmt.setString(2,"dupond");// auteur = dupondResultSet result = stmt.executeQuery( );

String srequete="SELECT intitule, reponse FROM question "+ "WHERE question.niveau= 4 AND question.auteur='dupond' "

Statement stmt = connexion.createStatement( );ResultSet result = stmt.executeQuery(srequete);

Avec createStatement

Avec preparedStatement

PreparedStatement

Y. Parchemal UPD 2010 ch.. 5 - 18

/** @return le nombre de colonne du ResultSet de ce ResultSetMetaData*/public int getColumnCount( ) throws SQLException {…}

/**@return le nom d'affichage de la colonne n° 'column' de ce ResultSetMetaData ATTENTION : les colonnes sont numérotées à partir de 1 !*/public String getColumnLabel(int column) throws SQLException

/** Get the designated column's specified column size. * For numeric data, this is the maximum precision. * For character data, this is the length in characters... */public int getPrecision(int column) throws SQLException;

$<bd>

La méthode getMetaData de l'interface ResultSet permet de récupérer une instance de ResultSetMetaData.

ResultSetMetaData permet deconnaître le nombre de colonnes, le nom des colonnes, ...

L'interface ResultSetMetaData

Y. Parchemal UPD 2010 ch.. 5 - 19

$<bd>

// par défaut, un commit est exécuté après chaque requête// on demande ici que ce ne soit pas le casconnection.setAutocommit(false);

// dans ce cas, la transaction ne prend fin // qu'après l'appel à commit ou rollback

// commit pour la validerconnection.commit( );

// rollback pour la rejeterconnection.rollback( );

Transactions : commit et rollback

Y. Parchemal UPD 2010 ch.. 5 - 20

La méthode Class.forName permet de forcerle chargement dynamique de classe

Lors de l'exécution d'un programme Java, les classes ne sont pas toutes chargées en mémoire .

Les classes sont chargées lorsque c'est nécessaire :- quand la construction d'une instance(directe ou indirecte) est demandée- quand une méthode de la classe doit être utilisée- quand la méthode class.forName("nomDeLaClasseACharger") est appelée

Chargement dynamique

Y. Parchemal UPD 2010 ch.. 5 - 21

$<chargedyn>

La définition d'une classe peut contenir des blocs statics.public class C1{private String s;private static Date dateChargement;static {

// nous sommes à l'intérieur d'un bloc static // (ils sont déclarés au même niveau que les membres de la classe)System.out.println("Chargement de la classe C1 en cours");// on peut dans un bloc static initialiser des données membres statics par exempledateChargement=new Date( );// on peut aussi appeler des méthodes d'autres classesC2.prevenirQueC1EstChargee( );// en fait, on peut faire ce que l'on veut}

// après, la définition de la classe continuepublic C1(String nom){…}... LES BLOCS STATICS SONT EXECUTES UNE FOIS

AU MOMENT DU CHARGEMENT DE LA CLASSE

Bloc static

Y. Parchemal UPD 2010 ch.. 5 - 22

La méthode Class.forName permet le chargement dynamique de classeLes blocs statics de la classe concernée sont donc exécutés.

$<chargedyn>

Revenons à nos drivers jdbc ...

Toutes les classes de drivers ont un bloc static qui fait les 2 opérations suivantes:- création d'une instance de la classe en chargement- appel d'une méthode de la classe DriverManager

prenant en paramètre cette instance et ayant pour rôle de l'insérer dans la liste des drivers disponibles.

Ainsi, au moment de l'appel de getConnection de DriverManager, le driver est connu et la connexion au SGBD peut être effectué.

Chargement dynamique des drivers jdbc

Y. Parchemal UPD 2010 ch.. 5 - 23

Autre différence :- import nécessite de mettre le nom de la classe "en dur" dans le programme,

or la classe du Driver est souvent mise dans un fichier de configuration

String className = lireFichier("conf.xml");Class.forName(className);

Cela permet d'utiliser le même programme avec des SGBD différents sans aucune modification

import <nomDeClasse> ;C'est un alias évitant de mettre le nom complet des classes dans le programme : cela ne garantie en rien que la classe sera chargée

import com.mysql.jdbc.Driver; // insuffisant ici car on veut que la classe soit chargée pour être enregistrée auprès du DriverManager avant l'appel de getConnection.

Pourquoi Class.forName("com.mysql.jdbc.Driver"); et pas import com.mysql.jdbc.Driver; ?

$<chargedyn>

Class.forName et import

Y. Parchemal UPD 2010 ch.. 5 - 24

Un exemple complet utilisant jdbc : la classe CompteBD

Nous allons voir :1. Une exemple d'utilisation de la classe CompteBD

2. La base de données utilisée

3. La définition de la classe BDune classe qui encapsule les informations de connection pour obtenir facilement des Statement

4. La définition de la classe CompteBD

Nous allons définir une classe CompteBD avec les fonctionnalités habituelles (ajout d'une opération, consultation du solde...)

et sauvegarde en base de données

Y. Parchemal UPD 2010 ch.. 5 - 25

Utilisation de la classe CompteBD

public static void main(String[ ] args) throws Exception {// creation des tables à la première exécutionCompteBD.creerLesTablesSiEllesNexistentPas( );// on récupère les comptes de Dupond et DurandCompteBD c1=CompteBD.getCompteByName("Dupond",true);CompteBD c2=CompteBD.getCompteByName("Durand",true);// on effectue des opérations et on affiche des infos// (il faudrait un menu à la place …)c1.addOperation(120);c2.addOperation(210);System.out.println(c1.getNomTitulaire( )+" "+c1.getSolde( )+

" "+c1.getDecouvertAutorise( ));System.out.println(c2.getNomTitulaire( )+" "+c2.getSolde( )+

" "+c2.getDecouvertAutorise( ));}

Y. Parchemal UPD 2010 ch.. 5 - 26

La base de données associée

3 tables

solde nom VARCHAR(80) montant INTEGER

decouvert nom VARCHAR(80) montant INTEGER

operation nom VARCHAR(80) montant INTEGER

Les montants sont enregistrés en centimes d'euros.

mémorisationdu solde

mémorisationdu découvert

mémorisationdes opérations

Y. Parchemal UPD 2010 ch.. 5 - 27

La classe BD/** une classe qui encapsule les informations de connection pour obtenir facilement des connexions et les fermer après usage */class BD {

static {try {Class.forName("com.mysql.jdbc.Driver");} catch (ClassNotFoundException e) {e.printStackTrace();}}

/** rend une connection à la base de données*/public static Connection getConnection( ) throws SQLException{

return DriverManager.getConnection("jdbc:mysql"+"://localhost/comptebd", "root", "");}

/** pour fermer d'un coup le statement */public static void close(Statement statement) throws SQLException{

if (statement!=null) statement.close();}

/** pour fermer d'un coup la connexion*/public static void close(Connection connection) throws SQLException{

if (connection!=null) connection.close(); }}

Y. Parchemal UPD 2010 ch.. 5 - 28

/** rend le compte dont le titulaire est nommé 'nomTitulaire' Si create == true, crée le compte s'il n'existe pas */public static CompteBD getCompteByName(String nomTitulaire,boolean create)

throws SQLException{…}

Méthodes statiques de la classe CompteBD

Récupération de comptes existants , création de comptes

private static boolean isCompteExisteDansLaBase(String nomTitulaire)throws SQLException{

Savoir si un compte existe

/** précise les informations de connexion à la base et crée si besoin les tables */public static void creerLesTablesSiEllesNexistentPas( )

throws SQLException{…}

Création des tables

Y. Parchemal UPD 2010 ch.. 5 - 29

/** ajoute une opération de 'montant' euros sur ce compte */public void addOperation(double montant) throws SQLException{…}

/** retourne le solde de ce compte */public double getSolde( ) throws SQLException{…}

/** retourne le découvert autorise pour ce compte */public double getDecouvertAutorise( ) throws SQLException{…}

/** teste si le solde de ce compte est insuffisant */public boolean isSoldeInsuffisant( ) throws SQLException{…}

/** le découvert autorise pour ce compte devient égal à 'decouvertAutorise'*/public void setDecouvertAutorise(double decouvertAutorise) throws SQLException {…}

/** retourne le nom du titulaire de ce compte */public String getNomTitulaire( ) {…}/** retourne une chaîne illustrant l'historique des opérations sur ce compte */public String getHistorique( ) throws SQLException{…}

Les méthodes d'instance de la classe CompteBD

Y. Parchemal UPD 2010 ch.. 5 - 30

/** le titulaire de ce compte*/ private String nomTitulaire;

La classe CompteBD : les attributs

Le seul attribut d'instance est nomTitulaireLe solde, le découvert autorisé et l'historique

sont mémorisés dans la base de données

Y. Parchemal UPD 2010 ch.. 5 - 31

/** précise les informations de connexion à la base et crée si besoin les tables */public static void creerLesTablesSiEllesNexistentPas( )throws SQLException{

Connection connection = BD.getConnection();Statement statement = connection.createStatement( );//création des 3 tables,si elles existaient déjà, une SQLException sera alors lancée// par jdbc. On attrape l'erreur dans le bloc catch.try{ statement.executeUpdate("CREATE TABLE decouvert " +

"(nom VARCHAR(25) PRIMARY KEY,montant INTEGER not NULL)");

statement.executeUpdate("CREATE TABLE solde " +"(nom VARCHAR(25) PRIMARY KEY,montant INTEGER not NULL)");

statement.executeUpdate("CREATE TABLE operation " +"(nom VARCHAR(25),montant INTEGER not NULL)");

}catch (SQLException exp) {exp.printStackTrace( ));}finally {BD.close(statement); BD.close(connection);}}

Création des tables de la base

Y. Parchemal UPD 2010 ch.. 5 - 32

/** rend le compte dont le titulaire est nommé 'nomTitulaire Si create == true, crée le compte en base s'il n'existe pas */public static CompteBD getCompteByName(String titulaire,boolean create)

throws SQLException{if (isCompteExisteDansLaBase(titulaire) || create) // creation de l'instance correspondante return new CompteBD(titulaire); else throw new RuntimeException("Compte inexistant: "+titulaire);}

La classe CompteBD : le constructeur

Y. Parchemal UPD 2010 ch.. 5 - 33

La classe CompteBD : le constructeur

/** creation d'un Compte avec initialisation éventuelle de la BD */private CompteBD(String nomTitulaire)throws SQLException{

this.nomTitulaire=nomTitulaire;

if (! isCompteExisteDansLaBase(nomTitulaire)){Connection connection=null;Statement statement=null;try {connection = BD.getConnection();

statement = connection.createStatement( );// L'initialisation consiste à mettre le solde et le découvert à zéro.statement.executeUpdate("INSERT INTO solde (nom,montant) VALUES ('" +

nomTitulaire + "',0)");statement.executeUpdate("INSERT INTO decouvert (nom,montant) VALUES ('" +

nomTitulaire + "',0)");}

finally {BD.close(statement); BD.close(connection);}}

}

Y. Parchemal UPD 2010 ch.. 5 - 34

/** teste si le compte correspond à 'nomTitulaire' existe en base */private static boolean isCompteExisteDansLaBase(String nomTitulaire)throws SQLException{boolean existe=false;Connection connection=null;PreparedStatement statement=null;try { connection = BD.getConnection(); statement = connection.prepareStatement(

"SELECT montant FROM solde WHERE nom=?"); statement.setString(1,nomTitulaire); // le critère d'existence est : y a-t-il un solde pour ce compte ? ResultSet rs= statement.executeQuery( ); existe= rs.next( ); }finally {BD.close(statement); BD.close(connection);}return existe;}

isCompteExiste

Y. Parchemal UPD 2010 ch.. 5 - 35

/** enregistre une opération de 'montant' Euros sur ce compte * @param montant le montant en euros de l'opération */public void addOperation(double montant)throws SQLException{Connection connection=null;PreparedStatement statement=null;try {

connection = BD.getConnection();statement = connection.prepareStatement(

"INSERT INTO operation(nom,montant) VALUES (?,?)"); statement.setString(1, this.nomTitulaire);statement.setInt(2,(int)montant*100);statement.executeUpdate();

}finally {BD.close(statement); BD.close(connection);}this.setSolde(this.getSolde( )+montant);}

La classe CompteBD : la méthode addOperation

Y. Parchemal UPD 2010 ch.. 5 - 36

/** modifie le découvert autorisé sur ce compte */public void setDecouvertAutorise(double decouvertAutorise)throws SQLException{Connection connection=null;PreparedStatement statement=null;

try {connection = BD.getConnection();statement = connection.prepareStatement(

"UPDATE decouvert SET montant=? WHERE nom=?");statement.setInt(1,(int)decouvertAutorise*100);statement.setString(2, this.nomTitulaire);statement.executeUpdate();

}finally {BD.close(statement); BD.close(connection);}}

setDecouvertAutorise

setSolde se définit de la même façon

Y. Parchemal UPD 2010 ch.. 5 - 37

/** retourne le solde de ce compte * @return le solde de ce compte */public double getSolde( ) throws SQLException{double solde;Connection connection=null;PreparedStatement statement=null;try {connection = BD.getConnection();

statement = connection.prepareStatement("SELECT montant FROM solde WHERE nom=?");

statement.setString(1, this.nomTitulaire);ResultSet rs = statement.executeQuery( );if (rs.next( ))

solde= rs.getInt(1)/100.0;else throw new RuntimeException("Compte inexistant: "+this.nomTitulaire);

}finally {BD.close(statement); BD.close(connection);}return solde;}

La classe CompteBD : la méthode getSolde

getDecouvertAutorise de définit de la même façon

Y. Parchemal UPD 2010 ch.. 5 - 38

/** retourne l'historique des opérations effectuées sur ce compte * @return l'historique des opérations effectuées sur ce compte */public String getHistorique( ) throws SQLException{ArrayList histo = new ArrayList( );Connection connection=null;PreparedStatement statement=null;try {connection = BD.getConnection();

statement = connection.prepareStatement("SELECT montant FROM operation WHERE nom =?" );

statement.setString(1, this.nomTitulaire);ResultSet rs = statement.executeQuery( );while (rs.next( )) {

double montant=rs.getInt(1)/100.0;histo.add(new Double(montant));

} }finally {BD.close(statement); BD.close(connection);}return(histo.toString( ));}

getHistorique

Y. Parchemal UPD 2010 ch.. 5 - 39

/** teste si le solde de ce compte est insuffisant */public boolean isSoldeInsuffisant( ) throws SQLException {return this.getSolde( ) < - this.getDecouvertAutorise();}

public String getNomTitulaire( ) {return this.nomTitulaire;}

public String toString( ){return("Compte de "+this.nomTitulaire);}

La classe CompteBD :les autres méthodes