130 votes

Comment utiliser des ressources d’essai avec JDBC?

J'ai une méthode pour obtenir des utilisateurs à partir d'une base de données avec JDBC:

public List<User> getUser(int userId) {
    String sql = "SELECT id, name FROM users WHERE id = ?";
    List<User> users = new ArrayList<User>();
    try {
        Connection con = DriverManager.getConnection(myConnectionURL);
        PreparedStatement ps = con.prepareStatement(sql); 
        ps.setInt(1, userId);
        ResultSet rs = ps.executeQuery();
        while(rs.next()) {
            users.add(new User(rs.getInt("id"), rs.getString("name")));
        }
        rs.close();
        ps.close();
        con.close();
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return users;
}

Comment dois-je utiliser Java 7 essayez-avec-des ressources pour améliorer ce code?

J'ai essayé avec le code ci-dessous, mais il utilise beaucoup d' try, et n'améliore pas la lisibilité beaucoup. Dois-je utiliser try-with-resources d'une autre manière?

public List<User> getUser(int userId) {
    String sql = "SELECT id, name FROM users WHERE id = ?";
    List<User> users = new ArrayList<>();
    try {
        try (Connection con = DriverManager.getConnection(myConnectionURL);
             PreparedStatement ps = con.prepareStatement(sql);) {
            ps.setInt(1, userId);
            try (ResultSet rs = ps.executeQuery();) {
                while(rs.next()) {
                    users.add(new User(rs.getInt("id"), rs.getString("name")));
                }
            }
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return users;
}

172voto

Jeanne Boyarsky Points 5968

Je me rends compte que cela a été répondu il y a longtemps, mais je voudrais suggérer une approche supplémentaire qui évite le blocage d'essais imbriqués.

 public T getUser(int userId) {
    try (Connection con = DriverManager.getConnection(myConnectionURL);
         PreparedStatement ps = createPreparedStatement(con, userId); 
         ResultSet rs = ps.executeQuery()) {

         return processResultSet(rs);
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return users;
}

private PreparedStatement createPreparedStatement(Connection con, int userId) throws SQLException {
    String sql = "SELECT id, username FROM users WHERE id = ?";
    PreparedStatement ps = con.prepareStatement(sql);
    ps.setInt(1, userId);
    return ps;
}

private T processResultSet(ResultSet rs) { 
   // code
}
 

67voto

bpgergo Points 9407

Il n'y a pas besoin d'essayer extérieur

 public List<User> getUser(int userId) {
    String sql = "SELECT id, username FROM users WHERE id = ?";
    List<User> users = new ArrayList<>();
    try (Connection con = DriverManager.getConnection(myConnectionURL);
         PreparedStatement ps = con.prepareStatement(sql);) {
        ps.setInt(1, userId);
        try (ResultSet rs = ps.executeQuery();) {
            while(rs.next()) {
                users.add(new User(rs.getInt("id"), rs.getString("name")));
            }
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return users;
}
 

2voto

Qu'en créer une autre classe wrapper?

package com.naveen.research.sql;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public abstract class PreparedStatementWrapper implements AutoCloseable {

    protected PreparedStatement stat;

    public PreparedStatementWrapper(Connection con, String query, Object ... params) throws SQLException {
        this.stat = con.prepareStatement(query);
        this.prepareStatement(params);
    }

    protected abstract void prepareStatement(Object ... params) throws SQLException;

    public ResultSet executeQuery() throws SQLException {
        return this.stat.executeQuery();
    }

    public int executeUpdate() throws SQLException {
        return this.stat.executeUpdate();
    }

    @Override
    public void close() {
        try {
            this.stat.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}




Puis dans l'appel de la classe, vous pouvez implémenter la méthode prepareStatement:



 essayez(Connection con = DriverManager.getConnection(JDBC_URL, prop);
 PreparedStatementWrapper stat = new PreparedStatementWrapper(con, requête, new Object[] {123L, "TEST"}) {
@Override
 protected void prepareStatement(Objet... params) throws SQLException {
 stat.setLong(1, Long.classe.cast(params[0]));
 stat.setString(2, Chaîne de caractères.valueOf(params[1]));
}
};
 ResultSet rs = stat.executeQuery();
 ) {
 while(rs.next()) 
 Système..println(String.format("%s, %s", rs.getString(2), rs.getString(1)));
 } catch(SQLException e) {
e.printStackTrace();
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by: