21/12/2021

ResultSet: une erreur assez basique

Actuellement, je prépare des notes de cours sur le développement web avec Java. C'est l'occasion pour moi de revoir les opérations basiques d'accès aux bases de données avec l'API JDBC (Java DataBase Connectivity). Avec cette API, une requête SQL est traitée en cinq étapes:

  1. Etablir la connexion à la base de données.
  2. Créer le statement SQL (associé à la requête SQL: requête simple, préparée ou procédure stockée).
  3. Exécuter la requête SQL.
  4. Parcourir les résultats de la requête (ResultSet)
  5. Fermer la connexion
Dans mon cas, c'est au niveau du parcours des résultats (4) qu'une erreur s'est produite. Durant l'exécution de ces cinq étapes, deux exceptions doivent être levées: ClassNotFoundException et SQLException. Voici le code: 

public void persistBookObject(Book book) {  
    try {
          Class.forName(driverName); //pour charger le driver
          connection = DriverManager.getConnection(url, dbUsername, dbPassword);

          PreparedStatement stmt = connection.prepareStatement("SELECT DISTINCT COUNT(*) AS 
          NBR_PUBLISHER FROM PUBLISHER WHERE CODE = ?");
          stmt.setString(1, book.getPublisher().getCode());
          ResultSet rs = stmt.executeQuery();
          int ifPublisherExists = 0;
          ifPublisherExists = rs.getInt("NBR_PUBLISHER");
          System.out.println("INFO: " + ifPublisherExists);
          stmt.close();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
      		e.printStackTrace();
 		} finally {
      		try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
  }

Dans mon cas, l'exécution de ce code produit l'exception suivante:

java.sql.SQLException: Before start of result set
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63)
at com.mysql.cj.jdbc.result.ResultSetImpl.checkRowPos(ResultSetImpl.java:517)
at com.mysql.cj.jdbc.result.ResultSetImpl.getObject(ResultSetImpl.java:1314)
at com.mysql.cj.jdbc.result.ResultSetImpl.getInt(ResultSetImpl.java:822)
at com.mysql.cj.jdbc.result.ResultSetImpl.getInt(ResultSetImpl.java:843)
at service.BookStoreService.persistBookObject(BookStoreService.java:34)
at client.BookStoreClient.main(BookStoreClient.java:28)

En analysant cette exception et le code ci-dessus, je m'aperçois que l'erreur vient de l'accès au résultat produit par l'exécution de la requête SQL. Pour corriger cette erreur, il faudra donc parcourir le tableau des résultats renvoyé par l'exécution de la requête SQL. En terme simple, le ResultSet doit d'abord être parcouru. Puisqu'une seule valeur est renvoyée par la requête, il suffit de placer le curseur sur la prochaine valeur du ResultSet. Je dois donc faire: 

if (rs.next()) {
    ifPublisherExists = rs.getInt("NBR_PUBLISHER");
    System.out.println("INFO: " + ifPublisherExists);
}

En conclusion, le ResultSet est une interface importante fournit par l'API JDBC qui permet d'accéder aux résultats issus de l'exécution d'une requête SQL sur une base de données. Maîtriser cette interface permet d'accéder efficacement aux données recherchées. Voyons en détail cette interface dans un prochain post.

Aucun commentaire:

Enregistrer un commentaire