ResultSet.close() ? cursor aberto no BD?

ola forum,

tenho um problema com ResultSet…

tenho uma classe que faz todo acesso ao BD(insere, exclui, altera), e essa classe tambem me retorna um ResultSet das select´s, e esse é o problema, com o comando ResultSel.close();, fecha o ResultSet mais não o cursor no banco dados… para fechar esse cursor tenho declarar o PreparedStatement como publico, e não estou achando isso muito legal,

alguem conhece outro forma de se fechar o cursor, sem declarar o PreparedStatement como publico ???

valeu

Não sei como está feita a sua classe, mas não tem como criar um método público na mesma classe em que está o seu PreparedStatement que realize a tarefa de fechá-lo?

ARGH!! Vc guarda o statement numa variável de instância??

Monta Lists de Maps, sei lah… Ou cria uma classe interna que implementa Iterator e percorre o ResultSet, e mantenha-o ao alcance do seu adapter (a instância que faz os acessos ao BD).

Na verdade, não tem problema o cursor continuar aberto, pq ele vai ser reutilizado com seu próximo select. Se vc quer mesmo prosseguir assim, lembre-se de que vc tem recursos extras a liberar quando sua instância for finalizada:

  protected void finalize() throws Throwable {
    myStatement.close();
    super.finalize(); // importante!
  }

[]s…

bari, ok !
eu poderia criar um metodo publico para fechar o cursor, mais ainda não é o ponto que eu quero chegar.

o ponto é: o que retornar da classe que faz acesso ao banco ?
Não posso retornar um ResultSet, e antes de usa-lo, fechar o PreparedStatement, pq é um objeto do banco.

gostaria de retornar um ResultSet, que não tenha vinculo com o PreparedStatement, existe possibilidade ?

não sei se deu pra entender.

valew !

Tem que ser especificamente um objeto ResultSet?
Você pode passar todo seu conteúdo para algum outro objeto qualquer (uma array, por exemplo) e aí retornar este objeto.

A resposta já foi dada, mas vou tentar esclarecer melhor.

O ideal é que sua classe que acessa o banco de dados não exporte ResultSet ou Statements, acho que você já quer fazer isso e não sabe como.

Você não deve exportar esses objetos porque você encapsulou seu acesso a banco na sua classe, então, só ela deveria ter acesso a recursos de banco, leia-se ResultSet, Statement, Connection, etc.

Então, uma idéia é exportar o seu “ResultSet” dentro de uma Collection de Map’s. Assim você pode liberar todos os recursos “de banco” após sua chamada ao banco.

Você pode fazer algo como:

	import java.util.*;
	...
	public Collection listar() throws EJBException {
		Collection usuarios = new LinkedList();
		try
		{
			Map map;
			Connection con = getConnection(datasourceName);
			Statement st = con.createStatement();

			ResultSet rs = st.executeQuery("select id,nome,login,senha,dt_cadastro,apelido,descricao,email," +
				"nascimento,site,assinatura,pergunta,email_publico,cadastro_publico,im_publico,icq,messenger " +
				"from usuario");
			while (rs.next()) {
				map = new TreeMap();
				map.put("id", new Long(rs.getLong("id")));
				map.put("nome", rs.getString("nome"));
				map.put("login", rs.getString("login"));
				map.put("senha", rs.getString("senha"));
				map.put("dt_cadastro", rs.getDate("dt_cadastro")); 
				map.put("apelido", rs.getString("apelido"));
				map.put("descricao", rs.getString("descricao"));
				map.put("email", rs.getString("email"));
				map.put("nascimento", rs.getDate("nascimento"));
				map.put("site", rs.getString("site"));
				map.put("assinatura", rs.getString("assinatura"));
				map.put("pergunta", rs.getString("pergunta"));
				map.put("email_publico", (rs.getInt("email_publico") == 1 ? new Boolean(true) : new Boolean(false)));
				map.put("cadastro_publico", (rs.getInt("cadastro_publico") == 1 ? new Boolean(true) : new Boolean(false)));
				map.put("im_publico", (rs.getInt("im_publico") == 1 ? new Boolean(true) : new Boolean(false)));
				map.put("icq", rs.getString("icq"));
				map.put("messenger", rs.getString("messenger"));
				usuarios.add(map);
			} 
			// Liberando recursos "de banco"
			rs.close();
			st.close();
			con.close();
		}
		catch (Exception e)
		{
			e.printStackTrace(System.out);
		}

		//Seu ResultSet encapsulado em uma Collection
		return usuarios;
	}

Caso você não saiba, você tem que ler a respeito de Collections e Map’s, fazem parte das classes “fundamentais” Java. São cobradas inclusive nas provas de certificação.

beleza pessoal,

minhas duvidas eram essas mesmo, deu pra entendeu certinho com o codigo de map e Collection funcionam,

valeu galera…

falow ae

Ao invés de usar um Map onde você teria que especificar cada campo para o Map em um loop, você pode utilizar o CachedRowSet, ele faz o mesmo serviço apenas usando o método populate(<resultset>).