AbstractTableModel que recebe dados de ResultSetMetaData

Olá amigos, sou novo aqui e fiquei em dúvida de onde colocar o tópico, pois é sobre jtable e banco, entao acabei colocando aqui mesmo em interface gráfica.
Bom, é um trabalho de faculdade…vms ao meu problema. Tenho essas duas classes como exemplo, que foram tiradas do livro do Deitel. A classe extends AbstractTabelModel e os métodos dela já são preenchidos com os ResultSetMetaData e a outra é o Jframe que vai chamar a tabela.

Mas minha dúvida é a seguinte, numa aplicação MVC, essa classe AbstractTableModel fica na View, não poderia ter esses ResultSet? Eu teria que preencher a jtable na View, mas sei como fazer os métodos da tabela recebem o resultado dos dados que vem do banco. Assim, a aplicação fica sendo genérica, pois só mudo o nome do banco e funciona para todos.

package br.projeto.view;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.List;

import javax.swing.table.AbstractTableModel;

public class OfResultSetTableModelTeste extends AbstractTableModel{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	private Connection connection;
	private java.sql.Statement statement;
	private ResultSet resultSet;
	private ResultSetMetaData metaData;
	private int numberOfRows;
	private boolean connectedToDatabase = false;
	
	public OfResultSetTableModelTeste(String driver,String url, String username, String password, String query) throws ClassNotFoundException, SQLException{
		Class.forName(driver);
		connection = DriverManager.getConnection(url,username,password);
		statement =  connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
		
		connectedToDatabase = true;
		setQuery(query);
	}

	public void setQuery(String query) throws SQLException {
		if(connectedToDatabase){
			resultSet = ((java.sql.Statement) statement).executeQuery(query);
			
			metaData = resultSet.getMetaData();
			resultSet.last();
			numberOfRows = resultSet.getRow();
			
			fireTableStructureChanged();
		}
		
	}

	public Class<?> getColumnClass(int column){
		if(connectedToDatabase)
			try{
				String className = metaData.getColumnClassName(+1);
				
				return Class.forName(className);
			}
			catch(Exception exception){
				exception.printStackTrace();
			}
		return Object.class;
	}
	
	public int getColumnCount() {
		if(connectedToDatabase){
			try{
				return metaData.getColumnCount();
			}
			catch(SQLException sqlException){
				sqlException.printStackTrace();
			}
		}
		return 0;
	}

	public String getColumnName(int column){
		if(connectedToDatabase){
			try{
				return metaData.getColumnName(column+1);
			}
			catch(SQLException sqlException){
				sqlException.printStackTrace();
			}
		}
		return "";
	}
	
	public int getRowCount() {
		if(connectedToDatabase){
			return numberOfRows;
		}
		return 0;
	}

	public Object getValueAt(int row, int column) {
		if(connectedToDatabase){
			try{
				resultSet.absolute(row+1);
				
				return resultSet.getObject(column+1);
			}
			catch(SQLException sqlException){
				sqlException.printStackTrace();
			}
		}	
		return "";
	}
	
	public void disconnectFromDatabase(){
		if(!connectedToDatabase){
			return;
		}
		try{
			statement.close();
			connection.close();
		}
		catch(SQLException sqlException){
			sqlException.printStackTrace();
		}
		finally{
			connectedToDatabase = false;
		}
	}

}

package br.projeto.view;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.sql.SQLException;

import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.ScrollPaneConstants;

public class DisplayQueryResultsTeste extends JFrame{

	private static final long serialVersionUID = 1L;
	static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
	static final String DATABASE_URL = "jdbc:mysql://localhost:3306/agendadb";
	static final String USERNAME = "root";
	static final String PASSWORD = "discograph1";
	
	static final String DEFAULT_QUERY = "select * from contatos";
	
	private ResultSetTableModelTeste tableModel;
	private JTextArea queryArea;
	
	public DisplayQueryResultsTeste(){
		super("Displaying Query Results");
		try{
			tableModel = new ResultSetTableModelTeste(JDBC_DRIVER, DATABASE_URL, USERNAME, PASSWORD, DEFAULT_QUERY);
			
			queryArea = new JTextArea(DEFAULT_QUERY,3,10);
			queryArea.setWrapStyleWord(true);
			queryArea.setLineWrap(true);
			
			JScrollPane scrollPane = new JScrollPane(queryArea, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
			
			JButton submitButton = new JButton("Submit query");
			
			Box box = Box.createHorizontalBox();
			box.add(scrollPane);
			box.add(submitButton);
			
			JTable resultTable = new JTable(tableModel);
			
			add(box,BorderLayout.NORTH);
			add(new JScrollPane(resultTable), BorderLayout.CENTER);
			
			submitButton.addActionListener(new ActionListener() {
				
				public void actionPerformed(ActionEvent event) {
					try{
						tableModel.setQuery(queryArea.getText());
					}
					catch(SQLException sqlException){
						JOptionPane.showMessageDialog(null, sqlException.getMessage(), "Database error", 
								JOptionPane.ERROR_MESSAGE);
						try{
							tableModel.setQuery(DEFAULT_QUERY);
							queryArea.setText(DEFAULT_QUERY);
						}
						catch(SQLException sqlException2){
							JOptionPane.showMessageDialog(null, sqlException2.getMessage(), "Database error", 
									JOptionPane.ERROR_MESSAGE);
							
							tableModel.disconnectFromDatabase();
							System.exit(1);
						}//fim cacth interno
					}//fim catch externo
				}//fim action performed
			});
			setSize(500,250);
			setVisible(true);	
		}//fim try
		catch(ClassNotFoundException classNotFound){
			JOptionPane.showMessageDialog(null, "MySQL driver not found", "Driver not found", 
					JOptionPane.ERROR_MESSAGE);
			
			System.exit(1);
		}//fim catch
		catch(SQLException sqlException){
			JOptionPane.showMessageDialog(null, sqlException.getMessage(), "Database error", 
					JOptionPane.ERROR_MESSAGE);	
			tableModel.disconnectFromDatabase();
			System.exit(1);
		}
		setDefaultCloseOperation(DISPOSE_ON_CLOSE);
		
		addWindowListener(
				new WindowAdapter()
				{
					public void windowClosed(WindowEvent event)
					{
						tableModel.disconnectFromDatabase();
						System.exit(0);
					}	
				}
		);
	}

	public static void main(String[] args){
		new DisplayQueryResultsTeste();
	}
}

Não sei fui claro e se alguém pode me dar alguma dica…
Vlw.

Bom, se você está pensando em fazer isso bem organizado e MVC mesmo, comece tirando toda a parte de conexão da sua view. Quem deve se preocupar em conectar, fazer a busca dos dados e retornar para o usuário não é a view. Esta somente deve saber como apresentar estes dados pro usuário, a partir de uma interface…

O que realmente você quer mostrar nesta tabela? Eu sugiro você criar uma classe sua que receba estes dados e então o seu model somente sabe como manipular este objeto… A grosso modo, deixe tudo o que é “java.sql.*” somente a cargo da DAO (Model).

O AbstractTableModel não é uma classe da View, mas sim, do Model. Na verdade, o Swing usa um modelo MVC simplificado, portanto, o TableModel faz também parte das vias do controller (a função de controller é simplificada pois não há uma camada intermediária entre o model e a view).

De qualquer forma, é o que o Kiko falou. Se você quer seguir o modelo mais adequadamente, seria bom estruturar o seu projeto em camadas. DAOs para acesso a dados, classes de negócio para o model, etc…