Est-il possible de transmettre ResultSet?

Dans ma situation, je demande à une firebase database un retour spécifique (dans ce cas des informations d’enregistrement basées sur un nom d’utilisateur).

//Build SQL Ssortingng and Query Database. if(formValid){ try { SQL = "SELECT * FROM users WHERE username=? AND email=?"; Collections.addAll(fields, username, email); results = services.DataService.getData(SQL, fields); if (!results.next()){ errMessages.add("User account not found."); } else { user = new User(); user.fillUser(results); //Is it ok to pass ResultSet Around? } } catch (SQLException e) { e.printStackTrace(); } finally { services.DataService.closeDataObjects(); //Does this close the ResultSet I passed to fillUser? } } 

Donc, une fois que j’interroge la firebase database, si un résultat est trouvé, je crée un nouvel object Utilisateur et le remplit avec les données que j’ai reçues de la firebase database. J’avais l’habitude de faire tout cela directement dans la méthode dans laquelle je tirais le jeu de résultats, mais je me suis rendu compte que je faisais beaucoup de codage redondant tout au long de mon projet.

  public void fillUser(ResultSet data) throws SQLException{ setUserId(data.getInt("id")); setFirstName(data.getSsortingng("first_name")); setLastName(data.getSsortingng("last_name")); setUsername(data.getSsortingng("username")); setType(data.getSsortingng("type")); setEmail(data.getSsortingng("email")); } 

J’ai effectué quelques tests et, d’après ce que je peux déterminer, comme je ferme le jeu de résultats d’origine dans le dernier bloc de la requête, le jeu de résultats que je transmets à la méthode fillUser est également fermé. Ou est-ce que je me trompe et que je sors sérieusement des données? C’est en fait la deuxième fois que je passe un jeu de résultats (donc ses deux instances d’une seule) car le bloc que j’utilise pour interroger ma firebase database est

  public static ResultSet getData(Ssortingng SQL, ArrayList fields) throws SQLException { try{ connection = Database.getConnection(); preparedStatement = connection.prepareStatement(SQL); for(int i=0; i<fields.size(); i++){ Integer num = i + 1; Object item = fields.get(i); if(item instanceof String){ preparedStatement.setString(num, (String) item); //Array item is String. } else if (item instanceof Integer){ preparedStatement.setInt(num, (Integer) item); //Array item is Integer. } } resultSet = preparedStatement.executeQuery(); return resultSet; }finally{ } } 

Tous ces extraits de code vivent dans des classes séparées et sont réutilisés plusieurs fois dans mon projet. Est-il possible de passer un resultat comme ceci ou devrais-je essayer une autre méthode? Mon objective est de réduire la redondance des codes, mais je ne suis pas sûr de le faire de manière légale.

Techniquement, il est acceptable de transmettre des ensembles de résultats, tant que vous ne le sérialisez pas et ne le transmettez pas à une machine virtuelle Java différente, et que votre connexion et votre déclaration JDBC sont toujours ouvertes.

Cependant, il est probablement préférable de disposer d’une couche d’access à la firebase database qui renvoie le jeu de résultats sous forme codée en Java (liste d’ User dans votre exemple). De cette façon, votre code sera plus propre et vous n’aurez pas à vous inquiéter si le ResultSet est déjà ouvert ou si vous devez le faire défiler vers le haut, nommez-le …

Comme tout le monde avant moi l’a dit, c’est une mauvaise idée de réussir le jeu de résultats. Si vous utilisez la bibliothèque de pools de connexions comme c3p0, vous pouvez utiliser en toute sécurité CachedRowSet et son implémentation CachedRowSetImpl . En utilisant cela, vous pouvez fermer la connexion. Il utilisera uniquement la connexion si nécessaire. Voici l’extrait du doc ​​java:

Un object CachedRowSet est un ensemble de lignes déconnecté, ce qui signifie qu’il n’utilise brièvement qu’une connexion à sa source de données. Il se connecte à sa source de données pendant la lecture des données pour se remplir de lignes et à nouveau pendant la propagation des modifications dans la source de données sous-jacente. Le rest du temps, un object CachedRowSet est déconnecté, y compris lorsque ses données sont en cours de modification. Être déconnecté rend un object RowSet beaucoup plus léger et donc beaucoup plus facile à passer à un autre composant. Par exemple, un object RowSet déconnecté peut être sérialisé et transmis par le fil à un client léger tel qu’un assistant numérique personnel (PDA).

Voici l’extrait de code pour interroger et renvoyer ResultSet:

 public ResultSet getContent(Ssortingng queryStr) { Connection conn = null; Statement stmt = null; ResultSet resultSet = null; CachedRowSetImpl crs = null; try { Connection conn = dataSource.getConnection(); stmt = conn.createStatement(); resultSet = stmt.executeQuery(queryStr); crs = new CachedRowSetImpl(); crs.populate(resultSet); } catch (SQLException e) { throw new IllegalStateException("Unable to execute query: " + queryStr, e); }finally { try { if (resultSet != null) { resultSet.close(); } if (stmt != null) { stmt.close(); } if (conn != null) { conn.close(); } } catch (SQLException e) { LOGGER.error("Ignored", e); } } return crs; } 

Voici l’extrait de code pour la création d’une source de données à l’aide de c3p0:

  ComboPooledDataSource cpds = new ComboPooledDataSource(); try { cpds.setDriverClass(""); //loads the jdbc driver } catch (PropertyVetoException e) { e.printStackTrace(); return; } cpds.setJdbcUrl("jdbc:"); cpds.setMinPoolSize(5); cpds.setAcquireIncrement(5); cpds.setMaxPoolSize(20); javax.sql.DataSource dataSource = cpds;