JDBC: Fechar Connection antes de pegar resultados. Pode?
6 respostas
Rafael_Afonso
Olá:
Segue o código:
publicclassTeste{publicstaticvoidmain(String[]args)throwsException{Class.forName("org.postgresql.Driver");Statementstmt=null;Connectionconn=null;ResultSetrs=null;try{try{conn=DriverManager.getConnection("jdbc:postgresql:base","Rafael U. C. Afonso","");stmt=conn.createStatement();rs=stmt.executeQuery("SELECT * FROM cliente");}finally{conn.close();}while(rs.next()){System.out.println(rs.getInt(1)+"-"+rs.getString(2));}}finally{stmt.close();rs.close();}}}
Como podem ver, estou fechando a conexão antes de pegar os resultados do ResultSet. O programa roda normalmente. Se eu colocar stmt.close() dentro do primeiro finally, uma exceção é disparada.
:?: A minha dúvida é: Isto está certo? Se não, por quê? Me convençam que isto está errado.
La vai um chute:
Isso ocorre por que o ResultSet é aberto como desconectado…
J
jrpequeno
O ResultSet é um cursor criado em memória e depois de criado, não precisa mais da conexão com o banco.
urubatan
não é não, o resultset não é um cursos em memoria, até por isto, que cada driver tem uma implementação de ResultSet
ele vai fazendo o fetch do banco a cada next (bom, isto depende de configurações, mas a ideia é esta)
wbsouza
Vc não deve fechar o connection antes do ResultSet! Como o urubatan disse, fica um cursor ativo para trazer os registros sob-demanda.
[]s, Welington B. Souza
wbsouza
Vai aí o seu código um pouco "melhorado" para se trabalhar com JDBC.
importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.sql.Statement;publicclassTeste{publicstaticvoidmain(String[]args){Statementstmt=null;Connectionconn=null;ResultSetrs=null;try{Class.forName("org.postgresql.Driver");conn=DriverManager.getConnection("jdbc:postgresql:base","Rafael U. C. Afonso","");stmt=conn.createStatement();rs=stmt.executeQuery("SELECT * FROM cliente");while(rs.next()){System.out.println(rs.getInt(1)+"-"+rs.getString(2));}}catch(ClassNotFoundExceptione1){System.out.println("Erro ao Carregar o JDBC Driver: "+e1.getMessage());}catch(SQLExceptione2){System.out.println(e2.getMessage());}finally{closeResources(conn,stmt,rs);}}privatestaticvoidcloseResources(Connectionconn,Statementstmt,ResultSetrs){if(rs!=null){try{rs.close();}catch(SQLExceptione){System.out.println(e.getMessage());}}if(stmt!=null){try{stmt.close();}catch(SQLExceptione){System.out.println(e.getMessage());}}if(conn!=null){try{conn.close();}catch(SQLExceptione){System.out.println(e.getMessage());}}}}
[]s, Welington B. Souza
Rafael_Afonso
Olá:
Urubatan: De fato pensei melhor e também acho que isso deve depender da implementação de cada driver. Mesmo se estes drivers forem para o mesmo BD.
Welington: Já estou usando um método parecido com o seu no meu projeto.
Eu gostaria de ter um jeito de me livrar das classes que não vou usar mais (como o Connection e o Statement) depois de executar a query para otimizar recursos. Entretanto parece que vou ter que carregar o trio Connection-PrepaedStatement-ResultSet até o fim da minha transação. Como dizem, a otimização precoce é a raiz de todo o mal.