Qual consulta é mais rápida e viável?

Olá, galerinha do GUJ!
Tudo beleza?

Tô aqui fazendo um TableModel para uma aplicação, e me surgiu uma dúvida:
Qual das duas consultas seria mais viável usar?

Suponhamos que eu queira pesquisar todos os tipos de documentos que começem com a letra ‘C’.

  1. Pesquisar os dados no Banco, retornando uma coleção de objetos, e printando estes na Table:
public class TiposDocumentosTableModel extends BaseTableModel<TipoDocumento>
{
   private List<TipoDocumento> tiposDocumentos = new ArrayList<TipoDocumento>();
   
   public TiposDocumentosTableModel(List<TipoDocumento> tiposDocumentos)
   {
      this.tiposDocumentos = tiposDocumentos;
   }

   public List<TipoDocumento> pesquisarRegistros(String criteria) throws Exception
   {
      tiposDocumentos = TiposDocumentosService.pesquisarRegistros(criteria);
      fireTableDataChanged();
   }
}
  1. Pesquisar na própria coleção que eu tenho em mãos, já que essa coleção é reflexo da minha base de dados:
public class TiposDocumentosTableModel extends BaseTableModel<TipoDocumento>
{
   private List<TipoDocumento> tiposDocumentos = new ArrayList<TipoDocumento>();
   private List<TipoDocumento> tiposDocumentosTemp = new ArrayList<TipoDocumento>();

   public TiposDocumentosTableModel(List<TipoDocumento> tiposDocumentos)
   {
      this.tiposDocumentos = tiposDocumentos;
      tiposDocumentosTemp = tiposDocumentos;
   }
   public List<TipoDocumento> pesquisarRegistros(String criteria) throws Exception
   {
      List<TipoDocumento> temp = new ArrayList<TipoDocumento>();
 
      tiposDocumentos = tiposDocumentosTemp;
      for (TipoDocumento tipoDocumento : tiposDocumentos)
      {
         if (tipoDocumento.getNome().equals(criteria)) temp.add(tipoDocumento);
      }
      
      tiposDocumentos = temp;
      fireTableDataChanged();
   }
}

A cada caractere digitado em um JTextField para consulta, é executado o método pesquisarRegistros(String criteria). Com a primeira solução, toda vez que eu digitar um caractere, a base de dados será acionada, uma nova conexão aberta e uma nova consulta realizada. Com a segunda solução, eu não tenho que ir todas as vezes na base de dados e pegar novos dados, economizando tempo.

Qual das duas soluções é mais viável, na opinião de vocês?

Fiquem com Deus, um abraço!

Consultar no banco parece mais fácil e se vc não tiver nenhum problema de performance usando essa estratégia não vejo pq não faze-lo.
Consultar direto da lista de objetos que vc já tem em mãos é com certeza mais rápido, mas além do código ser mais complexo manter
tantas informações na memória pode não ser muito bom.

Eu aconselho vc a implementar do modo mais simples e depois fazer um teste de performance. Se a performance for boa…
Lembre-se de nunca otimizar cedo demais. Tenha certeza q modo simples não é eficiente o bastante.

Se você tem certeza que os dados da base não irão mudar a cada pesquisa acredito que você deveria optar pela segunda opção.

utilizaria a consulta em memória…a consulta em banco é mais lenta que em memória, o tempo de resposta para o usuário será menor…

provavelmente você só buscará um id e a descrição que o usuário está preenchendo, não vai ocupar tanta ram assim…

só analisaria o número de registros totais na tabela…

se for na casa de dezenas de milhares…eu esperaria o usuário digitar os primeiros caracteres e só após isso fazer a pesquisa no banco (que já teria um número reduzido de opções) e a partir daí trabalhar em memória com esse resultado.

Atencao digo por experiencia propia.
O Banco de dados foi feito exactamente com o objectivo de guardar dados e fazer pesquisas, por isso podera ser mais lento para pesquisar se a quantidade de dados for pouca ou talvez media,mas se tiver muitos dados na tabela de pesquisa fica mais rapido no banco de dados,.
deve se deixar o minimo de objectos necessarios na memoria, para ter performance, agora para aplicacoes pequenas nao é preciso se preocupar com performance porque nunca dara problema de performance com 50 dados, mas se for 5000000 dados ja começa a pesar para a memoria.
e por outra o Padrao MVC diz que devemos separar as responsabilidades da aplicacao em MODEL VIEW CONTROLLER, mas nao deves se prender apenas por ai, é claro que se tivermos uma aplicacao com requisitos muito especificos podemos ter mais separacoes (DAO, etc), agora meter pesquisas em objectos na VIEW nao é boa idea, e nem no CONTROLLER, isso é funcao do DAO

[quote=sulito]Atencao digo por experiencia propia.
O Banco de dados foi feito exactamente com o objectivo de guardar dados e fazer pesquisas, por isso podera ser mais lento para pesquisar se a quantidade de dados for pouca ou talvez media,mas se tiver muitos dados na tabela de pesquisa fica mais rapido no banco de dados,.
deve se deixar o minimo de objectos necessarios na memoria, para ter performance, agora para aplicacoes pequenas nao é preciso se preocupar com performance porque nunca dara problema de performance com 50 dados, mas se for 5000000 dados ja começa a pesar para a memoria.
e por outra o Padrao MVC diz que devemos separar as responsabilidades da aplicacao em MODEL VIEW CONTROLLER, mas nao deves se prender apenas por ai, é claro que se tivermos uma aplicacao com requisitos muito especificos podemos ter mais separacoes (DAO, etc), agora meter pesquisas em objectos na VIEW nao é boa idea, e nem no CONTROLLER, isso é funcao do DAO[/quote]

Sulito, carregar uma lista de 5 objetos ou 50000 objetos não é o ponto, nem se a pesquisa está na view ou etc.

O que ele perguntou é se deveria ou não re-preencher a lista a cada consulta.

Se você tem 50000 registros na base e carrega eles em uma coleção na hora de resgatar você vai estar carregando os objetos da mesma forma na memória.
Acesso a memória é sempre muito mais rápido que qualquer tipo de IO.

Estou exactamente com o mesmo problema!
E quanto mais lei-o sobre padrões mais confuso fico, uns dizem para dividir em camadas outros não :S
Eu só sei que quero o mais eficiente! e neste momento estou a ter alguns problemas a carregar os meus dados para o tableModel.
Vou deixar um exemplo:

TAble MOdel

package TableModels;

import java.util.ArrayList;

public class ClientTableModel extends AbstractTableModel{

	private static final long serialVersionUID = 1L;
	private String[] head = {"Nº Cliente", "Nº Cont", "Nome"};
	private ArrayList<Client> list;
	
	public ClientTableModel(ArrayList<Client> list) {
		this.list = list;
	}

	public ClientTableModel() {
		list = new ArrayList<Client>();
	}
	
	public ArrayList<Client> getList(){
		return list;
	}
	
	public Client getObject(int idx){
		if(idx < 0 || idx > list.size()) return null;
		return list.get(idx);
	}
	
	@Override
	public int getColumnCount() {
		return head.length;
	}

	@Override
	public int getRowCount() {
		return list.size();
	}

	@Override
	public Object getValueAt(int line, int column) {
		Client c = list.get(line);
		
		switch(column){
		case 0: return c.getnClient();
		case 1:{
			if(c.getnCont()==0)
				return "N/D";
			else
				return c.getnCont();
		} 
		case 2: return c.getName();
		default: return null;
		}
	}
	
	@Override
	public void setValueAt(Object val, int line, int column){
		Client c = list.get(line);
		
		switch(column){
		case 0: c.setnClient((Integer)val);
		case 1: c.setnCont((Integer) val);
		case 2: c.setName((String)val);
		}
		
	}

	public void updateRows(ArrayList<Client> c){
		 this.list = c;
		 fireTableRowsInserted(0, c.size());
	}
	
	public void addAll(ArrayList<Client> c){
		if(c == null) return;
		this.list = c;
		fireTableRowsInserted(0, c.size());
	}
	
	public void addRow(Client c){
		list.add(c);
		fireTableRowsInserted(list.size()-1, list.size()-1);
	}
	
	public void removeRow(int index){
		list.remove(index);
		fireTableRowsDeleted(index, index);
	}
	
	public void removeAll(){
		int end = list.size();
		list = new ArrayList<Client>();
		fireTableRowsInserted(0, end);
	}
	
	@Override
	public String getColumnName(int columnIndex){
		return head[columnIndex];
	}
	
	@Override   
    public boolean isCellEditable(int rowIndex, int columnIndex){   
        return false;   
    }
	
	public Class getColumnClass(int c) {  
	
		 return getValueAt(0, c).getClass();
 
	 } 
}

Código de ligação a base de dados


package DataManagement;

import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;

public class Client extends BaseDataManagement implements Comparable<Object>{

    private int nClient;
	private int nCont;
    private String name;
    private String adress;
    private int codPost1;
    private int codPost2;
    private String freg;
    private int phoneNumber;
    private int mobilePhone;
    private String email;
    private Date bornDate;
    private ArrayList<Car> lstCar;

    /**
     * @param nCont
     * @param name
     * @param adress
     * @param codPost1
     * @param codPost2
     * @param freg
     * @param phoneNumber
     * @param mobilePhone
     * @param email
     */
    public Client(int nClient, int nCont, String name, String adress, int codPost1,
            int codPost2, String freg, int phoneNumber, int mobilePhone, String email, ArrayList<Car> lst, Date bornDate) {

        super();
        this.nClient = nClient;
        this.nCont = nCont;
        this.name = name;
        this.adress = adress;
        this.codPost1 = codPost1;
        this.codPost2 = codPost2;
        this.freg = freg;
        this.phoneNumber = phoneNumber;
        this.mobilePhone = mobilePhone;
        this.email = email;
        lstCar = lst;
        this.bornDate = bornDate;
    }

    public Client() {
        super();
    }

    public int getnClient() {
		return nClient;
	}

	public void setnClient(int nClient) {
		this.nClient = nClient;
	}

	/**
     * @return the nCont
     */
    public int getnCont() {
        return nCont;
    }
    
    public void setnCont(int nCont){
    	this.nCont = nCont;
    }

    /**
     * @return - Nome do Cliente
     *
     */
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return - Morada do Cliente
     *
     */
    public String getAdress() {
        return adress;
    }

    public void setAdress(String adress) {
        this.adress = adress;
    }

    /**
     * @return -  Codigo postal (4 primeiros digitos) do Cliente
     *
     */
    public int getCodPost1() {
        return codPost1;
    }

    public void setCodPost1(int codPost1) {
        this.codPost1 = codPost1;
    }

    /**
     * @return - Codigo postal (3 ultimos digitos) do Cliente
     *
     */
    public int getCodPost2() {
        return codPost2;
    }

    public void setCodPost2(int codPost2) {
        this.codPost2 = codPost2;
    }

    /**
     * @return - freguesia do Cliente
     *
     */
    public String getFreg() {
        return freg;
    }

    public void setFreg(String freg) {
        this.freg = freg;
    }

    /**
     * @return - numero de telefone do Cliente
     *
     */
    public int getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(int phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    /**
     * @return - Email do Cliente
     *
     */
    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    /**
     * @return the mobilePhone
     */
    public int getMobilePhone() {
        return mobilePhone;
    }

    /**
     * @param mobilePhone the mobilePhone to set
     */
    public void setMobilePhone(int mobilePhone) {
        this.mobilePhone = mobilePhone;
    }

    public void setCars(ArrayList<Car> lst ){
    	lstCar = lst;
    }
    
    public ArrayList<Car> getCars() {
        return lstCar;
    }
    

    public Date getDateBorn(){
        return bornDate;
    }

    public boolean insert(int nCont, String name, String adress, int codPost1,
            int codPost2, String freg, int phoneNumber, int mobilePhone, String email, ArrayList<Car> lstCar, Date bornDate){

        try {

            name = name.toUpperCase();
            email = email.toUpperCase();
            freg = freg.toUpperCase();
            adress = adress.toUpperCase();

            query.open();

            boolean	aux = query.insert("insert into client(nCont, nameClient, adressClient, phoneClient, mobileClient, codPost1, codPost2, freg, email, bornDate)values (?,?,?,?,?,?,?,?,?,?)",
            			new Object[]{nCont,name,adress,phoneNumber,mobilePhone,codPost1,codPost2,freg,email,bornDate});	

            ResultSet rs = query.select("SELECT MAX(nClient) FROM client");
            int nextId = -1;
			if(rs.next()){
				nextId = rs.getInt(1);
			}
          
            Iterator<Car> itCar = lstCar.iterator();

            while (itCar.hasNext())
                query.insert("insert into carowner (matricula, nCont) values (?,?)", new Object[]{itCar.next().getMatricula(),nextId});

            query.close();

            return aux;

        } catch (SQLException e) {
            query.close();
            e.printStackTrace();
        }

        return false;
    }

    public boolean update(int nClient, int nCont, String name, String adress, int codPost1,
            int codPost2, String freg, int phoneNumber, Integer mobilePhone, String email, ArrayList<Car> lstCar, Date bornDate) throws UnsupportedOperationException {


        query.open();

        try {

        	query.update("UPDATE client SET nCont = ?, nameClient = ?, adressClient = ?, phoneClient = ? , mobileClient = ?, " +
        			"codPost1 = ?, codPost2 = ?, freg = ?, email = ?, bornDate = ? where nClient = ?", 
        			new Object[]{nCont,name,adress,phoneNumber,mobilePhone,codPost1,codPost2,freg,email,bornDate, nClient});

            query.delete("delete from carowner where nCont = " + nClient);

            Iterator<Car> itCar = lstCar.iterator();

            while (itCar.hasNext())
                query.insert("insert into carowner (matricula, nCont) values (?,?)", new Object[]{itCar.next().getMatricula(),nClient});


            query.close();

        } catch (SQLException e) {
            query.close();
            e.printStackTrace();
            return false;
        }

        return true;
    }

    /**
     * @param nCont Codigo do cliente a remover
     * @return Retorna o numero de linhas afectadas, retorna -1 caso exista algum erro
     * */
    public int remove(int nCont) {
        int ret = -1;

        try {

            query.open();

            ret = query.delete("delete from client where nCont = " + nCont);

            query.close();

        } catch (SQLException e) {
            query.close();
        }

        return ret;

    }

    public int countRecords(int nCont) {
        int count = 0;
        ResultSet rs;
        try {

            query.open();
            if (nCont > 0) {
                rs = query.select("select count(*) from Client where nCont = "+nCont);
            } else {
                rs = query.select("select count(*) from Client");
            }

            if (rs.next()) {
                count = rs.getInt(1);
            }

            query.close();

        } catch (SQLException e) {
            query.close();
        }

        return count;
    }

    public int lastClient(){
    	
    	int ret = -1;
    	
    	try {
    		
    		query.open();  	
			ResultSet rs = query.select("SELECT MAX(nClient) FROM client");
			
			if(rs.next()){
				ret = rs.getInt(1);
			}
			
			query.close();
			
			return ret;
    	
    	} catch (SQLException e) {
			query.close();
			e.printStackTrace();
    	}
		
    	return ret;
    	
    }
    
    /**
     * @param nCont Numero de Contribuinte a pesquisar
     * @return Retorna um objecto do tipo Client, com o Cliente selecionado, caso n�o exista retorna NULL
     * @since V2.5
     * */
    public Client select(int nCont) {
        Client lst = null;
        Mark m = new Mark();
        Model mo = new Model();

        ArrayList<Car> lstCar = new ArrayList<Car>();

        try {

            query.open();

            ResultSet rs = query.select("SELECT car.* FROM carowner INNER JOIN car ON car.matricula = carowner.matricula where nCont = "+nCont);

            while (rs.next()) {
                lstCar.add(new Car(rs.getString("matricula"), rs.getString("VIN"), m.select(rs.getInt("idMarca")),
                        mo.select(rs.getInt("idModelo")), rs.getDate("dataFabrico"), rs.getInt("yearMake"), rs.getString("tipoMotor"),
                        rs.getInt("cc"), rs.getString("fuel"), null));
            }

            rs = query.select("select * from Client where nCont = "+ nCont);

            if (rs.next()) {
                lst = new Client(rs.getInt("nClient"),rs.getInt("nCont"), rs.getString("nameClient"), rs.getString("adressClient"),
                        rs.getInt("codPost1"), rs.getInt("codPost2"), rs.getString("freg"),
                        rs.getInt("phoneClient"), rs.getInt("mobileClient"), rs.getString("email"), lstCar, rs.getDate(("bornDate")));
            }

            query.close();

        } catch (SQLException e) {
        	e.printStackTrace();
            query.close();
        }

        return lst;
    }

    /**
     * @return Retorna uma LinkedList com objectos do tipo Mark
     * @see LinkedList
     * @since V 1.5
     * */
    public ArrayList<Client> select() {

        ArrayList<Client> lst = null;
        ResultSet rs;

        try {

            query.open();
            rs = query.selectPrepared("select * from client order by nameClient ASC", null);
            
            if(rs.last()){ //cria a lista com o tamanho exacto!
            	lst = new ArrayList<Client>(rs.getRow());
            	rs.beforeFirst();
            }
            
            while (rs.next()) {

                lst.add(new Client(rs.getInt("nClient"),rs.getInt("nCont"), rs.getString("nameClient"), rs.getString("adressClient"),
                        rs.getInt("codPost1"), rs.getInt("codPost2"), rs.getString("freg"), rs.getInt("phoneClient"),
                        rs.getInt("mobileClient"), rs.getString("email"), null, rs.getDate("bornDate")));
            }

            query.close();

        } catch (SQLException e) {
            query.close();
            e.printStackTrace();
        }

        return lst;
    }
         
    public ArrayList<Client> select(String name) {

		ArrayList<Client> lst = null;
		ResultSet rs;
		
		try {
		
		    query.open();
		    rs = query.select ("select * from client where nameClient like '%"+ name +"%'");
		    
		    if(rs.last()){ //cria a lista com o tamanho exacto!
		    	lst = new ArrayList<Client>(rs.getRow());
		    	rs.beforeFirst();
		    }
		    
		    while (rs.next()) {
		
		        lst.add(new Client(rs.getInt("nClient"),rs.getInt("nCont"), rs.getString("nameClient"), rs.getString("adressClient"),
		                rs.getInt("codPost1"), rs.getInt("codPost2"), rs.getString("freg"), rs.getInt("phoneClient"),
		                rs.getInt("mobileClient"), rs.getString("email"), null, rs.getDate("bornDate")));
		    }
		
		    query.close();
		
		} catch (SQLException e) {
		    query.close();
		    e.printStackTrace();
		}
		
		return lst;
    }
    //verificar o uso
    public ArrayList<Client> selectCont(int nCont) {

        ArrayList<Client> lst = new ArrayList<Client>();
        ArrayList<Car> lstCar;

        Mark m = new Mark();
        Model mo = new Model();

        ResultSet rs, rsCar;

        try {

            query.open();
            rs = query.select("select * from client where nCont like '"+ nCont +"%' order by nameClient ASC");

            while (rs.next()) {

                rsCar = query.select("SELECT car.* FROM carowner INNER JOIN car ON car.matricula = carowner.matricula WHERE nCont = "+rs.getInt("nCont") );

                lstCar = new ArrayList<Car>();

                while (rsCar.next()) {
                    lstCar.add(new Car(rsCar.getString("matricula"), rsCar.getString("VIN"), m.select(rsCar.getInt("idMarca")),
                            mo.select(rsCar.getInt("idModelo")), rsCar.getDate("dataFabrico"), rsCar.getInt("yearMake"), rsCar.getString("tipoMotor"),
                            rsCar.getInt("cc"), rsCar.getString("fuel"), null));
                }

                lst.add(new Client(rs.getInt("nClient"),rs.getInt("nCont"), rs.getString("nameClient"), rs.getString("adressClient"),
                        rs.getInt("codPost1"), rs.getInt("codPost2"), rs.getString("freg"), rs.getInt("phoneClient"),
                        rs.getInt("mobileClient"), rs.getString("email"), lstCar, rs.getDate("bornDate")));
            }

            query.close();

        } catch (SQLException e) {
        	e.printStackTrace();
            query.close();
        }

        return lst;
    }
    
    public Client selectByNClient(int nClient) {
        Client lst = null;
        Mark m = new Mark();
        Model mo = new Model();

        ArrayList<Car> lstCar = new ArrayList<Car>();

        try {

            query.open();

            ResultSet rs = query.select("SELECT car.* FROM carowner INNER JOIN car ON car.matricula = carowner.matricula where nCont = "+nClient);

            while (rs.next()) {
                lstCar.add(new Car(rs.getString("matricula"), rs.getString("VIN"), m.select(rs.getInt("idMarca")),
                        mo.select(rs.getInt("idModelo")), rs.getDate("dataFabrico"), rs.getInt("yearMake"), rs.getString("tipoMotor"),
                        rs.getInt("cc"), rs.getString("fuel"), null));
            }

            rs = query.select("select * from Client where nClient = "+nClient);

            if (rs.next()) {
                lst = new Client(rs.getInt("nClient"),rs.getInt("nCont"), rs.getString("nameClient"), rs.getString("adressClient"),
                        rs.getInt("codPost1"), rs.getInt("codPost2"), rs.getString("freg"),
                        rs.getInt("phoneClient"), rs.getInt("mobileClient"), rs.getString("email"), lstCar, rs.getDate(("bornDate")));
            }

            query.close();

        } catch (SQLException e) {
        	e.printStackTrace();
            query.close();
        }

        return lst;
    }

    public ArrayList<Client> selectByCar(String matricula){
		
   	 ArrayList<Client> lst = null;

        try {

            query.open();

            ResultSet rs = query.select("SELECT client.* FROM carowner INNER JOIN client ON client.nClient = carowner.nCont where matricula = '" + matricula + "'");

            if(rs.last()){ 
            	lst = new ArrayList<Client>(rs.getRow());
    			rs.beforeFirst();  
    		}
            
            while (rs.next()) {
                lst.add(new Client(rs.getInt("nClient"),rs.getInt("nCont"), rs.getString("nameClient"), rs.getString("adressClient"),
                        rs.getInt("codPost1"), rs.getInt("codPost2"), rs.getString("freg"), rs.getInt("phoneClient"),
                        rs.getInt("mobileClient"), rs.getString("email"), null, rs.getDate("bornDate")));
            }

            
            query.close();

        } catch (SQLException e) {
        	e.printStackTrace();
            query.close();
        }

        return lst;
   	
   }
    
    public int compareTo(Object o) {
       return nCont - ((Client)o).getnCont();
    }
}

Seria otimo uma ajudinha!!! :smiley:

Quem diz que não? Até onde eu sei, dividir em camadas é um dos poucos tópicos que absolutamente todos concordam.

Que problemas?

Que problemas?
[/quote]

Vamos considerar um exemplo mais concreto!
Problemas de lentidão a carregar todos os carros para o TableModel.
No meu caso eu faço uma pesquisa ou por matricula, mas na altura de voltar a meter todos os carros no table model, tenho uma de espera de 2 a 3 segundos, o pior é que só estamos a falar de 90 registos na base de dados :?

Ainda para mais implementei com PreparedStatements e o não consegui reduzir o tempo.
Existe alguma forma de se conseguir otimizar?
TableModel dos carros

package TableModels;

import java.sql.Date;

public class CarTableModel extends AbstractTableModel{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private String[] header = {"Matricula", "Marca", "Modelo" ,"Nº Chassi", "Tipo Motor", "Data Matricula",
		"Ano Fabrico", "Cilindrada" , "Combustivel"};
	private ArrayList<Car> list;
	
	public CarTableModel(){
		list = new ArrayList<Car>();
	}
	
	public CarTableModel(ArrayList<Car> list){
		this.list= list;
	}
	
	public ArrayList<Car> getList(){
		return list;
	}
	
	public Car getObject(int idx){
		return list.get(idx);
	}
	
	@Override
	public int getColumnCount() {
		return header.length;
	}

	@Override
	public int getRowCount() {
		if(list != null)
			return list.size();
		return 0;
	}

	@Override
	public Object getValueAt(int line, int column) {
		Car c = list.get(line);
		
		switch(column){
			case 0: return c.getMatricula();
			case 1: return c.getMarca().getMark();
			case 2: return c.getModelo().getModel();
			case 3: return c.getVIN();
			case 4: return c.getTypeMotor();
			case 5: return c.getFabrico();
			case 6: return c.getYear();
			case 7: return c.getCc();
			case 8: return c.getFuel();
		}
		return null;
	}
	
	@Override
	public void setValueAt(Object aValue, int line, int column){
		
		Car c = list.get(line);
		
		switch(column){
			case 0: c.setMatricula((String) aValue);
			case 1: c.setMarca((Mark) aValue);
			case 2: c.setModelo((Model)aValue);
			case 3: c.setVIN((String) aValue);
			case 4: c.setTypeMotor((String) aValue);
			case 5: c.setFabrico((Date) aValue);
			case 6: c.setYear((Integer)aValue);
			case 7: c.setCc((Integer)aValue);
			case 8: c.setFuel((String) aValue);
		}
	}

	public void updateRows(ArrayList<Car> c){
		if(c!=null){ 
			this.list = c;
		 	fireTableRowsInserted(0, c.size());
		}
	}
	
	public void addRow(Car m){
		list.add(m);
		fireTableRowsInserted(list.size()-1, list.size()-1);
	}
	
	public void removeRow(int index){
		list.remove(index);
		fireTableRowsDeleted(index, index);
	}
	
	public void removeAll(){
		int end = list.size();
		list = new ArrayList<Car>();
		fireTableRowsInserted(0, end);
	}
	
	@Override
	public String getColumnName(int columnIndex){
		return header[columnIndex];
	}
	
	@Override   
    public boolean isCellEditable(int rowIndex, int columnIndex){   
        return false;   
    }
	
	 public Class<?> getColumnClass(int c) {  		 
		 if(c == 5) return java.sql.Date.class;
		 return getValueAt(0, c).getClass();

	 }  

}

Código de ligação dos carros a base de dados

package DataManagement;

import AutoGestExceptions.ImpossibleInsertException;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

public class Car extends BaseDataManagement implements Comparable<Object>{

    private String matricula;
    private String VIN;
    private Mark marca;
    private Model modelo;
    private Date fabrico;
    private String typeMotor;
    private int cc;
    private int year;
    private String fuel;
    private ArrayList<Client> owner;

    /**
     * @param matricula
     * @param vin
     * @param marca
     * @param modelo
     * @param fabrico
     * @param owner
     */
    public Car(String matricula, String vin, Mark marca, Model modelo,
            Date fabrico, int anoFabrico, String typeMotor, int cc, String fuel, ArrayList<Client> lst){
        super();
        this.matricula = matricula;
        VIN = vin;
        this.marca = marca;
        this.modelo = modelo;
        this.fabrico = fabrico;
        this.typeMotor = typeMotor;
        this.cc = cc;
        year = anoFabrico;
        this.fuel = fuel;
        this.owner = lst;
    }

    public Car() {
        super();
        this.owner = new ArrayList<Client>();
    }

    public String getFuel() {
		return fuel;
	}

	public void setFuel(String fuel) {
		this.fuel = fuel;
	}

	/**
     * @return the matricula
     */
    public String getMatricula() {
        return matricula;
    }

    /**
     * @param matricula the matricula to set
     */
    public void setMatricula(String matricula) {
        this.matricula = matricula;
    }

    /**
     * @return the VIN
     */
    public String getVIN() {
        return VIN;
    }

    /**
     * @param vin the VIN to set
     */
    public void setVIN(String vin) {
        VIN = vin;
    }

    /**
     * @return the marca
     */
    public Mark getMarca() {
        return marca;
    }

    /**
     * @param marca the marca to set
     */
    public void setMarca(Mark marca) {
        this.marca = marca;
    }

    /**
     * @return the modelo
     */
    public Model getModelo() {
        return modelo;
    }

    /**
     * @param modelo the modelo to set
     */
    public void setModelo(Model modelo) {
        this.modelo = modelo;
    }

    /**
     * @return the fabrico
     */
    public Date getFabrico() {
        return fabrico;
    }

    /**
     * @param fabrico the fabrico to set
     */
    public void setFabrico(Date fabrico) {
        this.fabrico = fabrico;
    }

    /**
     * @return the typeMotor
     */
    public String getTypeMotor() {
        return typeMotor;
    }

    /**
     * @param typeMotor the typeMotor to set
     */
    public void setTypeMotor(String typeMotor) {
        this.typeMotor = typeMotor;
    }

    /**
     * @return the cc
     */
    public int getCc() {
        return cc;
    }

    /**
     * @param cc the cc to set
     */
    public void setCc(int cc) {
        this.cc = cc;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    /**
     * @return the owner
     */
    public ArrayList<Client> getOwner() {
        return owner;
    }

    /**
     * @param owner the owner to set
     */
    public void setOwner(ArrayList<Client> owner) {
        this.owner = owner;
    }

    public boolean insert(String matricula, String vin, Mark marca, Model modelo,
            Date fabrico, int anoFabrico, String tipoMotor, int cc, String fuel) throws ImpossibleInsertException {

        try {

            query.open();

            ResultSet rs = query.select("select count(*) from car  where matricula = '" + matricula + "'");

            rs.next();
            if (rs.getInt(1) > 0) {
                throw new ImpossibleInsertException();
            }
            
            boolean aux = query.insert("insert into car(matricula, vin, idMarca, idModelo, tipoMotor, dataFabrico, cc, yearMake, fuel) "
                     + "values (?,?,?,?,?,?,?,?,?)", new Object[]{matricula,vin,marca.getIdMark(),modelo.getIdModel(),tipoMotor,fabrico,cc,anoFabrico,fuel});

             
            query.close();

            return aux;

        } catch (SQLException e) {
            query.close();
            e.printStackTrace();
        }

        return false;
    }

    public boolean update(String matricula, String vin, Mark marca, Model modelo,
            Date fabrico, int anoFabrico, String tipoMotor, int cc, String fuel) {

    	boolean aux = false;
    	
        try {

            query.open();

             aux = query.update("UPDATE car SET vin = ?, idMarca = ? , idModelo = ?, tipoMotor = ?, dataFabrico = ?"
                + " , cc = ?, yearMake = ?, fuel = ? where matricula = ?",
                new Object[]{vin,marca.getIdMark(),modelo.getIdModel(),tipoMotor,fabrico,cc,anoFabrico,fuel,matricula});

            query.close();

        } catch (SQLException ex) {
            query.close();
            ex.printStackTrace();
        }
        return aux;
    }

    public int countRecords(String matricula) {

        int ret = 0;

        try {

            ResultSet rs;
            query.open();

            if (matricula.equals("")) {
                rs = query.select("select count(*) from car");
            } else {
                rs = query.select("select count(*) from car where matricula = '" + matricula + "'");
            }

            if (rs.next()) {
                ret = rs.getInt(1);
            }

            query.close();

        } catch (SQLException ex) {
            query.close();
        }
        return ret;
    }

    /**
     * @param VIN - N.� de chassi do carro a remover
     * @return Retorna o numero de linhas afectadas, retorna -1 caso exista algum erro
     * */
    public int remove(String matricula) {
        int ret = -1;

        try {

            query.open();

            ret = query.delete("delete from car where matricula = '" + matricula + "'");

            query.close();

        } catch (SQLException e) {
            query.close();
        }

        return ret;

    }

    /**
     * @param VIN - N.� do chassi do carro a pesquisar
     * @return Retorna um objecto do tipo Car, com o carro selecionado
     * @since V2.5
     * */
    public Car select(String matricula) {
        Car lst = null;
        ArrayList<Client> listClient = new ArrayList<Client>();
        
        try {

            query.open();

            ResultSet rs = query.select("SELECT client.* FROM carowner INNER JOIN client ON carowner.nCont = client.nClient WHERE matricula = '" + matricula + "'");
            while (rs.next()) {
                listClient.add(new Client(rs.getInt("nClient"),rs.getInt("nCont"), rs.getString("nameClient"), rs.getString("adressClient"),
                        rs.getInt("codPost1"), rs.getInt("codPost2"), rs.getString("freg"), rs.getInt("phoneClient"), rs.getInt("mobileClient"), rs.getString("email"), null, rs.getDate("bornDate")));
            }

            rs = query.select("select * from car where matricula = '" + matricula + "'");

            if (rs.next()) {
            
                Model mo = new Model();
                mo = mo.select(rs.getInt("idModelo"));

                lst = new Car(rs.getString("matricula"), rs.getString("VIN"), mo.getMark(),
                        mo, rs.getDate("dataFabrico"), rs.getInt("yearMake"), rs.getString("tipoMotor"),
                        rs.getInt("cc"), rs.getString("fuel"), listClient);
  
            }
            query.close();

        } catch (SQLException e) {
        	e.printStackTrace();
            query.close();
        }

        return lst;
    }

    public ArrayList<Car> selectMat(String matricula){
    	ArrayList<Car> lstCar = new ArrayList<Car>();
    	ResultSet rs;
    	
        Model mo = new Model();
    	
    	query.open();
    	
    	try {
		
    		rs = query.select("SELECT * FROM car WHERE matricula like '"+matricula+"%'");
    		while (rs.next()) {

    			mo = mo.select(rs.getInt("idModelo"));
			  
			    lstCar.add(new Car(rs.getString("matricula"), rs.getString("VIN"), mo.getMark(),
                        mo, rs.getDate("dataFabrico"), rs.getInt("yearMake"), rs.getString("tipoMotor"),
                        rs.getInt("cc"), rs.getString("fuel"), null));
    		
    		}
			
			query.close();
		} catch (SQLException e) {
			query.close();
			e.printStackTrace();
		}
    	    	
    	return lstCar;
    }
    
     /**
     * @return Retorna uma LinkedList com objectos do tipo Model
     * @see LinkedList
     * @since V 1.5
     * */
    public ArrayList<Car> select() {

        ArrayList<Car> lst = null;
        ResultSet rs;

        Model mo = new Model();

        try {

            query.open();
            rs = query.selectPrepared("select * from car", null);

            if(rs.last()){ //cria a lista com o tamanho exacto!
            	lst = new ArrayList<Car>(rs.getRow());
            	rs.beforeFirst();
            }
            
            while (rs.next()) {
            	mo = mo.select(rs.getInt("idModelo"));
            	
                lst.add(new Car(rs.getString("matricula"), rs.getString("VIN"), mo.getMark(),
                        mo, rs.getDate("dataFabrico"), rs.getInt("yearMake"), rs.getString("tipoMotor"),
                        rs.getInt("cc"), rs.getString("fuel"), null));
            
            }

            query.close();

        } catch (SQLException e) {
        	e.printStackTrace();
            query.close();
        }

        return lst;
    }

    
    public ArrayList<Car> selectByClient(int idClient){
    	
    	ArrayList<Car> lstCar = null;
    	ResultSet rs;
        Model mo = new Model();
    	
    	query.open();
    	
    	try {
		 
    		rs = query.select("SELECT * FROM carowner INNER JOIN car ON car.matricula = carowner.matricula WHERE nCont = "+idClient);
    		
    		if(rs.last()){ 
    			lstCar = new ArrayList<Car>(rs.getRow());
    			rs.beforeFirst();  
    		}
    	
    		while (rs.next()) {
    			
    			mo = mo.select(rs.getInt("idModelo"));
			    
    			lstCar.add(new Car(rs.getString("matricula"), rs.getString("VIN"), mo.getMark(),
                        mo, rs.getDate("dataFabrico"), rs.getInt("yearMake"), rs.getString("tipoMotor"),
                        rs.getInt("cc"), rs.getString("fuel"), null));
    		
			   
    		}
			
			query.close();
		} catch (SQLException e) {
			query.close();
			e.printStackTrace();
		}
    	    	
    	return lstCar;
    }
    
    public int compareTo(Object o) {
        return matricula.compareTo( ((Car)o).getMatricula() );
    }
}

Cumps, Tiago
Agradeço muito toda a atenção!! :smiley:

Eu retiraria esse if aqui:

if(rs.last()){ lstCar = new ArrayList<Car>(rs.getRow()); rs.beforeFirst(); }

Pois o ArrayList cresce sozinho, vc não precisa dar um valor inicial para ele. Também é um a operação cara locomover-se assim pelos resultsets.

Além disso, eu rodaria esse código num profiler. Já carreguei tabelas com milhares de registros sem esses problemas de performance.

[quote=ViniGodoy]Eu retiraria esse if aqui:

if(rs.last()){ lstCar = new ArrayList<Car>(rs.getRow()); rs.beforeFirst(); }

Pois o ArrayList cresce sozinho, vc não precisa dar um valor inicial para ele. Também é um a operação cara locomover-se assim pelos resultsets.

Além disso, eu rodaria esse código num profiler. Já carreguei tabelas com milhares de registros sem esses problemas de performance.[/quote]

Eu posso tirar esse código. Mas o que me foi explicado foi que cada vez que o ArrayList cresce sozinho ele volta a copiar todos os dados para um novo ArrayList. Ou explicaram-me mal?

Gostei da ideia do profiler, gostava só que me desse umas luzes sobre isso. Ou um sitio onde possa aprender a lidar com PROFILERS!
Obrigado pela ajuda! :smiley:

É isso mesmo.

Mas essa cópia é feita através de uma chamada a uma função de memória (memcpy) que é rapidíssima. Muito mais rápida do que percorrer o banco.
Além disso, “todos os dados” refere-se apenas a ponteiros de objetos (4 bytes por objeto), independente de quanta coisa tenha dentro de sua classe.

Tem vários links sobre o profiler aqui: http://profiler.netbeans.org/

É isso mesmo.

Mas essa cópia é feita através de uma chamada a uma função de memória (memcpy) que é rapidíssima. Muito mais rápida do que percorrer o banco.
Além disso, “todos os dados” refere-se apenas a ponteiros de objetos (4 bytes por objeto), independente de quanta coisa tenha dentro de sua classe.

Tem vários links sobre o profiler aqui: http://profiler.netbeans.org/[/quote]

Bem pelo que entendo o profiler serve somente para ver o tempo que determinadas partes do código demoram a executar e para ver onde falha a performance do código. Que me dá uma enorme ajuda! Vou pesquisar sobre o PROFILER, para ver o que encontro para o eclipse. :wink:

Cumps, Tiago

Isso mesmo, exatamente a informação que você precisa. Assim você descobre qual método ou classe é que está gerando o atraso.