J'avoue cette méthode ne me rassure pas. Si la connexion ne se fait pas correctement au début de la servlet ou de la jsp, c'est toute la requête qui échoue et vis-à-vis du client ça la fout mal !
J'avoue cette méthode ne me rassure pas. Si la connexion ne se fait pas correctement au début de la servlet ou de la jsp, c'est toute la requête qui échoue et vis-à-vis du client ça la fout mal !
la connexion n'a aucun raison de ne pas se faire. Au contraire, c'est le fait de marteler le SGBD de connexion à grande vitesse qui rend ton application instable.
De plus, quand tu fera de l'écriture, il sera important de tout faire dans la même connexion pour avoir une base de données cohérente.
OK
Donc on est bien d'accord sur le principe :
Chaque DAO à une instance de ma classe DataBase que voici :
Les DAO sont des singletons et sont instanciés à chaque servlets et chaque pages jsp (si besoin)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87 public class DataBase{ private String url, userName, password; private Statement st; private Connection con; /** * @author Brice * Constructor */ private DataBase () throws SQLException { //attributes constructor this.userName = "root";//user of database this.password = "a";//password to connect database this.url = "jdbc:mysql://srv-arche/Javarch?user=root&password=a";//database adress } public static DataBase getIstance () { try {return new DataBase();} catch (SQLException ex) {ex.printStackTrace();return null;} } /** * @param void * @return void * Connect the programm to database */ public void connection () throws SQLException { try {Class.forName("com.mysql.jdbc.Driver");} catch (ClassNotFoundException e) {System.out.println("ClassNotFoundException");} con = DriverManager.getConnection(url, userName, password); st = con.createStatement(); } /** * @param String request * @return ResultSet * Execute a querry request on database and return an Object[][] */ public Object[][] getResult (String request) { ResultSet rs = null; PreparedStatement pst = null; try { rs = st.executeQuery(request); int numberField = rs.getMetaData().getColumnCount(); int size =0; ArrayList<Object> [] listArrays = new ArrayList[numberField];//arrayList collection //building arrayList collection for (int i=0; i<numberField; i++) { listArrays[i] = new ArrayList <java.lang.Object>(); } while(rs.next()) { size++;//match number rows from the database result for (int i=0; i<numberField; i++) { listArrays[i].add(rs.getString(i+1)); } } Object[][] ret = new Object[size][numberField]; for (int i=0; i<listArrays[0].size(); i++) { for (int j=0; j<listArrays.length; j++) { ret[i][j] = listArrays[j].get(i); } } return ret; } catch (SQLException sql){sql.printStackTrace();return null;} finally { try { rs.close(); pst.close(); con.close(); } catch (SQLException sql){} catch (NullPointerException np) {} } } /** * ju- * @param request * @throws SQLException */ public void update(String request) throws SQLException { st.executeUpdate(request); } }
Ma classe DataBase est instanciée, elle à chaque servlets et est stockées dans la request. De ce fait, je la récupère dans ma JSP et la transmet à l'instanciation d'un DAO en cas de besoin ?
Les DAO, si ils sont des singletons, ne doivent pas conserver de l'objet database, sinon quand la connexion sera coupée, ils continueront de l'utiliser.
Soit les DAO on la même durée de vie ou plus courte que ton objet database -> alors tu leur passe (mais dans ce cas, ce ne sont pas des singletons)
Soit les DAO sont effectivement des singletons, alors c'est à eux d'aller interroger l'endroit ou tu stocke la database pour connaitre la database de l'utilisateur courant. En général, dans ce genre de schéma, on met en place un filtre ou autre chose spécifique au framework utilisé (un phase listener sous JSF par exemple). Dans ce filtre, on stocke alors la connexion ou l'objet enrobant la connexion dans une membre statique de type ThreadLocal. Et on prend bien garde à le nettoyer quoi qu'il arrive à la fin de la requête.
Je rajoute que ta classe utilitaire ne devrait vraiment que retourner une connexion, rien d'autre. Charge à l'appelant de faire le ménage sur les différentes ressources connexes.
Tu peux regarder celle-ci
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 public class ConnectionUtils { private static final ThreadLocal<Connection> session = new ThreadLocal<Connection>(); private static final String className = "..."; private static final String url = "..."; private static final String user = "..."; private static final String password = "..."; /** * Récupération de la connexion */ public static Connection currentConnection() throws Exception { Connection c = session.get(); // Ouvre une nouvelle Session, si ce Thread n'en a aucune if (c == null) { Class.forName(className); c = DriverManager.getConnection(url, user, password); session.set(c); } return c; } /** * Fermeture de la connexion courrante */ public static void closeConnection() throws Exception { Connection c = session.get(); if (c == null ) return ; session.set(null); c.close(); } }
Ca revient un peu au même !
Mes DAO meurent une fois la jsp affichée non ?
Du coup à la prochaine request, j'instancie un nouvel objet DataBase puis créé une nouvelle connexion, et les DAO dont j'ai besoin. Ça me parait plus simple en fait !
Ah oauis, le fait qu'ils soient static impliquent qu'ils ne sont pas détruits à la fin de la servlet et de la JSP ?
Dans ce cas, ils ne meurent pas![]()
Est-ce que je peux déclarer mes DAO sans connexion à la BDD lors de la connexion du client et transmettre en paramètre un objet DataBase qui sera instancié à la request appropriée, à chaque appel de méthode du DAO ?
Partager