OVH Cloud OVH Cloud

Classe globale de connexion

7 réponses
Avatar
tchou
Bonjour =E0 tous,

Je voudrais optimiser ma classe Connexion qui ouvre une connexion, set
un Resultset et retourne un resultset en la rendant globale, ce qui
=E9viterait de, dans chaque m=E9thode d'une classe faire un new
Connexion, etc. A la place l'id=E9al serait de pouvoir instancier la
connexion et la fermer une seule fois, dans le main.

J'ai lu quelques lignes sur les variables globales en Java : est ce que
je dois faire une classe globale, =E0 l'int=E9rieur de laquelle
j'instancierai la connexion =3D> mais apr=E8s faut bien que je l'appelle
cette classe donc faudrait ENCORE un new? Bref je vois pas trop comment
m'y prendre... Quelqu'un?


Merci,
Tchou.

7 réponses

Avatar
Bernard Koninckx
Je suis pas un pro mais il me semble qu'avec un pattern singleton tu devrais
t'en sortir.

Un truc du style:

public class connectionDB{
private static Connection connection = null;

private connectionDB(){}

public static Connection getConnection(){
if(connection == null){
//code création connection
}
return connection;
}
public static void closeConnection(){
if (connection != null) connection.close();
}
}

Je pense que ça devrait marcher. Tu ne dois pas créer systématiquement une
instance de ta classe puisque tu passe par des méthodes statiques. Tu peux
faire directement : connectionDB.getConnection(); et ainsi récupérer la
connexion existante dans cet objet.

Je crois également qu'il faut vérifier le code et le sécuriser.

Bernard

"tchou" a écrit dans le message de
news:
Bonjour à tous,

Je voudrais optimiser ma classe Connexion qui ouvre une connexion, set
un Resultset et retourne un resultset en la rendant globale, ce qui
éviterait de, dans chaque méthode d'une classe faire un new
Connexion, etc. A la place l'idéal serait de pouvoir instancier la
connexion et la fermer une seule fois, dans le main.

J'ai lu quelques lignes sur les variables globales en Java : est ce que
je dois faire une classe globale, à l'intérieur de laquelle
j'instancierai la connexion => mais après faut bien que je l'appelle
cette classe donc faudrait ENCORE un new? Bref je vois pas trop comment
m'y prendre... Quelqu'un?


Merci,
Tchou.
Avatar
cilovie
Le singleton oui mais pas en environnement multi thread !
regarde du côté de http://jakarta.apache.org/commons/dbcp/
Tout es prévu sous la forme de pool de connection.


Bernard Koninckx wrote:
Je suis pas un pro mais il me semble qu'avec un pattern singleton tu devrais
t'en sortir.

Un truc du style:

public class connectionDB{
private static Connection connection = null;

private connectionDB(){}

public static Connection getConnection(){
if(connection == null){
//code création connection
}
return connection;
}
public static void closeConnection(){
if (connection != null) connection.close();
}
}

Je pense que ça devrait marcher. Tu ne dois pas créer systématiquement une
instance de ta classe puisque tu passe par des méthodes statiques. Tu peux
faire directement : connectionDB.getConnection(); et ainsi récupérer la
connexion existante dans cet objet.

Je crois également qu'il faut vérifier le code et le sécuriser.

Bernard

"tchou" a écrit dans le message de
news:
Bonjour à tous,

Je voudrais optimiser ma classe Connexion qui ouvre une connexion, set
un Resultset et retourne un resultset en la rendant globale, ce qui
éviterait de, dans chaque méthode d'une classe faire un new
Connexion, etc. A la place l'idéal serait de pouvoir instancier la
connexion et la fermer une seule fois, dans le main.

J'ai lu quelques lignes sur les variables globales en Java : est ce que
je dois faire une classe globale, à l'intérieur de laquelle
j'instancierai la connexion => mais après faut bien que je l'appelle
cette classe donc faudrait ENCORE un new? Bref je vois pas trop comment
m'y prendre... Quelqu'un?


Merci,
Tchou.




Avatar
Bernard Koninckx
Je n'y connais pas encore grand chose en connexion db en tout cas merci pour
l'info, ça me sera toujours utiles pour plus tard

J'avais donné cette solution parce qu'il n'avais pas dit si il travaillait
en multi-thread. De plus, il souhaite ouvrir une seule connexion et la
refermer dans le main.

Il est cependant vrai que cela pourrait poser problème au niveau
transactionnel.

Bernard

"cilovie" a écrit dans le message de
news:42860387$0$26065$
Le singleton oui mais pas en environnement multi thread !
regarde du côté de http://jakarta.apache.org/commons/dbcp/
Tout es prévu sous la forme de pool de connection.


Bernard Koninckx wrote:
Je suis pas un pro mais il me semble qu'avec un pattern singleton tu
devrais


t'en sortir.

Un truc du style:

public class connectionDB{
private static Connection connection = null;

private connectionDB(){}

public static Connection getConnection(){
if(connection == null){
//code création connection
}
return connection;
}
public static void closeConnection(){
if (connection != null) connection.close();
}
}

Je pense que ça devrait marcher. Tu ne dois pas créer systématiquement
une


instance de ta classe puisque tu passe par des méthodes statiques. Tu
peux


faire directement : connectionDB.getConnection(); et ainsi récupérer la
connexion existante dans cet objet.

Je crois également qu'il faut vérifier le code et le sécuriser.

Bernard

"tchou" a écrit dans le message de
news:
Bonjour à tous,

Je voudrais optimiser ma classe Connexion qui ouvre une connexion, set
un Resultset et retourne un resultset en la rendant globale, ce qui
éviterait de, dans chaque méthode d'une classe faire un new
Connexion, etc. A la place l'idéal serait de pouvoir instancier la
connexion et la fermer une seule fois, dans le main.

J'ai lu quelques lignes sur les variables globales en Java : est ce que
je dois faire une classe globale, à l'intérieur de laquelle
j'instancierai la connexion => mais après faut bien que je l'appelle
cette classe donc faudrait ENCORE un new? Bref je vois pas trop comment
m'y prendre... Quelqu'un?


Merci,
Tchou.






Avatar
pierre
Une autre solution est d'utiliser la classe ThreadLocal.
Pour le tutorial:
http://www-106.ibm.com/developerworks/java/library/j-threads3.html
Les threadLocal permettent de manipuler des instances uniques mais par
Thread. Cette classe est souvent utilisé dans la pattern ServiceLocator.

Cordialement.
Pierre.


cilovie wrote:
Le singleton oui mais pas en environnement multi thread !
regarde du côté de http://jakarta.apache.org/commons/dbcp/
Tout es prévu sous la forme de pool de connection.


Bernard Koninckx wrote:

Je suis pas un pro mais il me semble qu'avec un pattern singleton tu
devrais
t'en sortir.

Un truc du style:

public class connectionDB{
private static Connection connection = null;

private connectionDB(){}

public static Connection getConnection(){
if(connection == null){
//code création connection
}
return connection;
}
public static void closeConnection(){
if (connection != null) connection.close();
}
}

Je pense que ça devrait marcher. Tu ne dois pas créer systématiquement
une
instance de ta classe puisque tu passe par des méthodes statiques. Tu
peux
faire directement : connectionDB.getConnection(); et ainsi récupérer la
connexion existante dans cet objet.

Je crois également qu'il faut vérifier le code et le sécuriser.

Bernard

"tchou" a écrit dans le message de
news:
Bonjour à tous,

Je voudrais optimiser ma classe Connexion qui ouvre une connexion, set
un Resultset et retourne un resultset en la rendant globale, ce qui
éviterait de, dans chaque méthode d'une classe faire un new
Connexion, etc. A la place l'idéal serait de pouvoir instancier la
connexion et la fermer une seule fois, dans le main.

J'ai lu quelques lignes sur les variables globales en Java : est ce que
je dois faire une classe globale, à l'intérieur de laquelle
j'instancierai la connexion => mais après faut bien que je l'appelle
cette classe donc faudrait ENCORE un new? Bref je vois pas trop comment
m'y prendre... Quelqu'un?


Merci,
Tchou.






Avatar
LR
Une autre solution est d'utiliser la classe ThreadLocal.
Pour le tutorial:
http://www-106.ibm.com/developerworks/java/library/j-threads3.html
Les threadLocal permettent de manipuler des instances uniques mais par
Thread. Cette classe est souvent utilisé dans la pattern ServiceLocator.

Cordialement.
Pierre.


Oui, et si on reprend l'exemple précédent, ça devrait donner quelque chose
comme ça :

public class connectionDB{
private static ThreadLocal connection = null;

private connectionDB(){}

public static Connection getConnection(){
if(connection == null){
//code création connection
}
return (Connection)connection;
}
public static void closeConnection(){
if (connection != null) ((Connection)connection).close();
}
}

A vérifier...

Lilian

Avatar
tchou
Je suis pas un pro mais il me semble qu'avec un pattern singleton tu
devrais

t'en sortir.


Merci à tous!

Comme c'est une appli à user unique pour l'instant, j'ai déjà
essayé de faire ça mais il y a une erreur que je ne comprends pas.
Avant, dans Connexion j'avais aussi le Statement et le Resultset, ça
fonctionnait. J'ai "externalisé" le stmt et resultset en créant une
classe Query => erreur d'entrée sortie. Alors que le reste du code n'a
pas changé. Un peu d'indulgence, j'ai commencé le java y a 3 mois :-)
Mais tous les conseils sont le bienvenu :-)

--------------------------------------
SingleConnection
--------------------------------------

package pretack.commun;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class SingleConnection{
class Connexion{
private Connection Conn = null;

Connexion(){
try {
Class.forName("org.postgresql.Driver");
Conn = DriverManager.getConnection(

"jdbc:postgresql://localhost/pretack?user=tchou&password=surlepontdavig non");

}
catch (SQLException e) {
System.out.println("Connexion impossible à PostgreSQL");
e.printStackTrace();
}
catch (ClassNotFoundException e) {
System.out.println("Classe introuvable");
e.printStackTrace();
}
}

public void close(){
try {
Conn.close();
}
catch (SQLException e){
e.printStackTrace();
}
}
public Connection getConnection(){
return Conn;
}
}
private Connexion conn = null;
private static SingleConnection cnxUnique;

// constructeur privé car permis une seule fois
// par une méthode de la classe
//
private SingleConnection(){
conn = new Connexion();
}
//
// classe appelée pour l'initialiser
public static SingleConnection getInstance(){
if (cnxUnique==null){
cnxUnique = new SingleConnection();
}
return cnxUnique;
}
public Connexion getConnexion(){
return conn;
}
}

--------------------------------------
Query
--------------------------------------

package pretack.commun;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
* Classe simplifiée pour créer un Resultset
*/
public class Query {
private Statement Stmt = null;
private ResultSet RS = null;
SingleConnection cnx = SingleConnection.getInstance();

public Query(String req){
try {
Stmt = cnx.getConnexion().getConnection().createStatement();
}
catch (SQLException e1) {
System.out.println("Echec creation statement");
e1.printStackTrace();
}
try {
RS = Stmt.executeQuery(req);
}
catch (SQLException e) {
System.out.println("Echec de la requete ");
e.printStackTrace();
//new Alert("Echec de la requete");
}
System.out.println(req);
}
public ResultSet getRS(){
return RS;
}
public void close(){
try {
if (RS!=null) RS.close();
Stmt.close();
}
catch (SQLException e){
System.out.println("Erreur cloture Query");
e.printStackTrace();
}
}
}

--------------------------------------
Ligne appelante
--------------------------------------
Query qUpdateVendeur = new Query(req);
(la requete est valide, elle fonctionne sous postgreSQL et marchait
avant la modif de Connexion aussi)

Avatar
tchou
J'ai oublié de dire que ça plantait dans le constructeur de Query, à
cette ligne :
RS = Stmt.executeQuery(req);