Ajuda na implementação de metodo buscar

Galera sou novo em java gostaria de saber como faço funcionar o seguinte:

Tenho meu metodo buscar e estou querendo fazer a seguite verificação, quando o usuario digitar um ID de Carro que não exista no BD, que seja retornado uma mensagem dizendo que “Nenhum Registro Encontrado”;

O codigo é o seguinte



    public void buscar(Carro c) {

        conn = cb.getConection();


        String sql = "select * from carro where id = ?";

        if (!(conn == null)) {

            try {

                ps = conn.prepareStatement(sql);
                ps.setInt(1, c.getIdCarro());
                rs = ps.executeQuery();

                if () {

                    JOptionPane.showMessageDialog(null, "Nenhum Registro Encontrado");

                } else {

                    while (rs.next()) {

                        c.setNomeCarro(rs.getString("nome"));
                        c.setModeloCarro(rs.getString("modelo"));
                        c.setGaratiaCarro(rs.getString("garantia"));

                    }

                }

                rs.close();
                ps.close();
                conn.close();

            } catch (Exception e) {
                e.printStackTrace();
            }


        } else {

            JOptionPane.showMessageDialog(null, "Link com Banco de Dados Off-line");
        }

    }

o detalhe deve estar naquele meu IF() vazio. ali ele tem que verificar se o sql veio vazio, sem resultado. Nao sei como fazer isso.
Alguem pode me ajudar?

Que tal:

[code]
public void buscar(Carro c) {
conn = cb.getConection();
String sql = “select * from carro where id = ?”;
if (!(conn == null)) {
try {
ps = conn.prepareStatement(sql);
ps.setInt(1, c.getIdCarro());
rs = ps.executeQuery();
if (rs.next()) {
c.setNomeCarro(rs.getString(“nome”));
c.setModeloCarro(rs.getString(“modelo”));
c.setGaratiaCarro(rs.getString(“garantia”));
} else {
JOptionPane.showMessageDialog(null, “Nenhum Registro Encontrado”);
}
}
rs.close();
ps.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
} else {
JOptionPane.showMessageDialog(null, “Link com Banco de Dados Off-line”);
}

}[/code]

Se você está procurando pela chave primária, é obvio que só poderá haver apenas 1 registro. Então você não precisa usar while. Pode usar o if.

E mais uma coisa: os metodos close() deveriam ficar numa clausula finally porque se por algum problema milenar como por exemplo, Plutão se alinhar com Mercurio e o seu metodo lançar alguma exception, você nunca irá invocar os metodos close() matendo assim conexões abertas para nada.

Na questão do while eu ja tinha me atentando, so nao sei oq fiz de erro que nao pegou quando testei sem ele. Pois como vc mesmo disse, é so 1 registro que virá.

vo testar aqui e ja posto o resultado!

testei aqui, e funcionou mas tive que mudar os closes de lugar, pois fora do try eles estavam dando erro.

Mas ficou bom, pelo que percebi o proprio rs.next retorna talves um boolean que ja me serve pra fazer essa verificacao se ele veio true ou false.

Agora quanto aos finaly ainda nao sei como fazer.

No mais obrigado

Para os closes ficariam assim:

public void buscar(Carro c) { conn = cb.getConection(); String sql = "select * from carro where id = ?"; if (!(conn == null)) { try { ps = conn.prepareStatement(sql); ps.setInt(1, c.getIdCarro()); rs = ps.executeQuery(); if (rs.next()) { c.setNomeCarro(rs.getString("nome")); c.setModeloCarro(rs.getString("modelo")); c.setGaratiaCarro(rs.getString("garantia")); } else { JOptionPane.showMessageDialog(null, "Nenhum Registro Encontrado"); } } rs.close(); ps.close(); conn.close(); } catch (Exception e) { e.printStackTrace(); } finally { rs.close(); ps.close(); conn.close(); } } else { JOptionPane.showMessageDialog(null, "Link com Banco de Dados Off-line"); } }

Só tome cuidado para que o ResultSet, PreparedStatement e/ou Connection não estejam null na clausula finally. Eu tive o mesmo problema esses dias e pelo que me disseram aqui no GUJ a melhor solução seria um

if(rs != null) { rs.close(); }

Só repetir o codigo acima para o PreparedStatement e o Connection.

Se estiver usando Java 7, use o try with resources.

Outra coisa estranha no seu código. As variáveis conn, ps e rs deveriam ser locais do método.
Por que elas foram declaradas na classe?

[quote=ViniGodoy]Outra coisa estranha no seu código. As variáveis conn, ps e rs deveriam ser locais do método.
Por que elas foram declaradas na classe?[/quote]

Aproveitando esse topico, suponhamos que eu tenha uma classe que só serve para acessar o banco de dados. Ela tem varios metodos que fazem select, insert, update e delete. Para evitar a repetição de declaracao do Connection, PreparedStatement e ResultSet em todos esses metodos, faria sentido eu declara-las como variaveis de instancia? Se sim, se eu tiver varias classes desse tipo, estaria correto criar uma classe abstrata que ja tenha essas variaveis de instancias declaras para evitar a repetiçao de codigo?

[quote=ViniGodoy]Outra coisa estranha no seu código. As variáveis conn, ps e rs deveriam ser locais do método.
Por que elas foram declaradas na classe?[/quote]

ViniGodoy - isso prejudica alguma coisa? Fiz somente pra poder reaproveitar nessa classe que tenho outros métodos que tambem usaram ps e rs.

Cada variável deve ter o menor escopo possível, e não deve ser reaproveitada se isso não fizer sentido.

Reaproveitar variáveis é sinal que alguma coisa ruim pode ocorrer mais cedo ou mais tarde - porque você tem algo que em um determinado trecho de seu programa tem uma personalidade, e mais na frente tem outra personalidade - é diferente da novela das 9, onde uma pessoa se chamava Rita e depois começou a se chamar Nina :slight_smile: .

Se a conexão deve permanecer aberta (ou seja, você não está usando um pool) então ela até pode pertencer à classe, mas nem sempre esse é o caso. De modo geral, se algo é aberto e fechado dentro de um determinado método, deve ser declarado como local dentro desse método, e ter o menor escopo possível.

Se quiser reaproveitar o nome, você pode artificialmente criar um novo escopo, se for o caso, para limitar o escopo da variável.
Se você estiver artificialmente criando muitos escopos, é melhor então criar novos métodos (porque o método provavelmente está ficando muito grande),

[quote=entanglement]Cada variável deve ter o menor escopo possível, e não deve ser reaproveitada se isso não fizer sentido.

Reaproveitar variáveis é sinal que alguma coisa ruim pode ocorrer mais cedo ou mais tarde - porque você tem algo que em um determinado trecho de seu programa tem uma personalidade, e mais na frente tem outra personalidade - é diferente da novela das 9, onde uma pessoa se chamava Rita e depois começou a se chamar Nina :slight_smile: .

Se a conexão deve permanecer aberta (ou seja, você não está usando um pool) então ela até pode pertencer à classe, mas nem sempre esse é o caso. De modo geral, se algo é aberto e fechado dentro de um determinado método, deve ser declarado como local dentro desse método, e ter o menor escopo possível.

Se quiser reaproveitar o nome, você pode artificialmente criar um novo escopo, se for o caso, para limitar o escopo da variável.
Se você estiver artificialmente criando muitos escopos, é melhor então criar novos métodos (porque o método provavelmente está ficando muito grande), [/quote]

Entendido! obrigado pelas dicas pessoal!