Bonjour,
Question générale, sans réel rapport avec JDBC, d'où mon choix pour ce forum. Mais question "illustrée" par un cas de figure utilisant JDBC. Concrètement je souhaite afficher le résultat d'une requête SQL (base MySQL). La séquence à respecter est :
- création d'un objet Connection
- création d'un objet Statement via l'objet Connection
- création d'un objet ResultSet via l'objet Statement
- faire quelque chose d'utile du ResultSet (ouf! enfin! )
Connection, Statement et ResultSet sont des ressources (AutoCloseable) à libérer.
Objectif : éviter de coder à chaque fois les étapes 1 à 3.
J'ai d'abord créé une fonction retournant un RésultSet, comme suit :
Dans le code appelant, lorsque je souhaite utiliser le ResultSet, j'ai le droit à une exception : Operation not allowed after ResultSet closed
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 private static ResultSet executeQuery(String sqlq) throws SQLException { try ( Connection conn = DriverManager.getConnection(URL); Statement stmt = conn.createStatement() ) { return stmt.executeQuery( sqlq ); } }
De fait, j'ai changé mon fusil d'épaule, voilà ce que ça donne :
Ca fonctionne, certes, et il n'y pas de répétition des étapes 1 à 3 si je veux exécuter un autre SELECT et faire quelque chose du résultat...
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 package testjdbc; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class TestJDBC { private static final String URL = "jdbc:mysql://localhost/test_jdbc?user=user_test&password=secret"; private interface IExecuteQuery { public void use(ResultSet rs) throws SQLException; } private static void executeQuery(String sqlq, IExecuteQuery ieq) throws SQLException { try ( Connection conn = DriverManager.getConnection(URL); Statement stmt = conn.createStatement() ) { ieq.use( stmt.executeQuery( sqlq ) ); } } public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException { // The newInstance() call is a work around for some broken Java implementations (source: site MySQL) Class.forName("com.mysql.jdbc.Driver").newInstance(); executeQuery( "select * from login", new IExecuteQuery() { @Override public void use(ResultSet rs) throws SQLException { while( rs.next() ) { System.out.println( String.format( "idLogin:%d, login:\"%s\", password:\"%s\"", rs.getInt("idLogin"), rs.getString("login"), rs.getString("password") ) ); } } } ); } }
Pour autant, c'est un peu lourd AMHA...
Est-il possible, de faire plus léger (en terme de lignes de code) ? Quelque chose comme un délégué C#, bref une sorte de pointeur de fonction typé (prenant un ResultSet en paramètre), et que je passerais à ma fonction executeQuery() ?
D'avance merci
Partager