AbstractTableModel与实际SQL语句之间的正确关系是什么?

时间:2013-12-29 19:50:26

标签: java sql defaulttablemodel abstracttablemodel

表格模型与实际数据库查询之间在代码中的正确关系是什么?

在表模型中的addRow()方法内,我是否应该再调用我的数据库类,然后将该行插入数据库?我在下面的代码片段中说明了这一点。

public class MainPanel extends JPanel
{
    ...

    public MainPanel()
    {

        personTableModel = new PersonTableModel();

        personTable = new JTable(personTableModel);
        ...

        insertButton = new JButton("Insert");
        insertButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e)
            {
                String name = nameTextBox.getText();
                String address = addressTextBox.getText();

                Object[] row = { name, address };

                personTableModel.addRow(row);  // <--- Add row to model
            }
        });    
    }
}

public class PersonTableModel extends AbstractTableModel
{
    private List<Object[]> data;
    private List<String> columnNames;

    PersonDB personDB = new PersonDB();
    ...

    public void addRow(Object[] row)
    {
        // insert row into 'data'

        personDB.addPerson(row);  // <---- Call the personDB database class
    }

    ...
}

public class PersonDB
{

    public PersonDB()
    {
        // establish database connection
    }

    public addPerson(Object[] row)
    {
        // code that creates a SQL statement based on row data
        // and inserts new row into database.
    }
    ...
}

1 个答案:

答案 0 :(得分:0)

是否应该直接进行插入调用取决于某些方面:

  • 您是否希望其他进程立即访问数据?
  • 您是否担心程序崩溃而丢失重要信息?
  • 你能否确保在addRow期间持久保存的任何数据都是有意义的(程序可以在插入后直接终止)?

当然,将数据直接插入后备数据库可能是个好主意。

但请注意,addRow有两种变体,insertRow有两种变体。 DefaultTableModel通过insertRow(int, Vector)在内部指示调用,如果您想立即保留数据,这可能是唯一要覆盖的函数。

如果您喜欢DTO的提议,下面的示例可能会对您有所帮助。

Idea是将“实体”或表行表示为Java中的类。 DTO是最简单的表示,通常只包含具有相应getter和setter的字段。

实体通常可以通过EclipseLinkHibernate等ORM库进行持久化和加载。此外,对于此表应用程序,使用DTO提供了一种以干净和键入的方式存储未向用户显示的数据的方法。

DTO:

public class PersonDto {
    private Long id;
    private String name;
    private String street;

    public PersonDto() {
    }

    public PersonDto(Long id, String name, String street) {
        this.id = id;
        this.name = name;
        this.street = street;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    public static class NameColumn extends DtoTableModel.ColumnProvider<PersonDto, String> {

        public NameColumn() {
            super("Name", String.class);
        }

        @Override
        public String getValue(PersonDto dto) {
            return dto.getName();
        }

        @Override
        public void setValue(PersonDto dto, Object value) {
            dto.setName((String) value);
        }
    }

    public static class StreetColumn extends DtoTableModel.ColumnProvider<PersonDto, String> {

        public StreetColumn() {
            super("Street", String.class);
        }

        @Override
        public String getValue(PersonDto dto) {
            return dto.getStreet();
        }

        @Override
        public void setValue(PersonDto dto, Object value) {
            dto.setStreet((String) value);
        }
    }
}

基于DTO的TableModel:

import javax.swing.table.AbstractTableModel;
import java.util.ArrayList;

public class DtoTableModel<T> extends AbstractTableModel {

    private final ArrayList<T>                    rows;
    private final ArrayList<ColumnProvider<T, ?>> columns;

    protected DtoTableModel() {
        rows = new ArrayList<T>();
        columns = new ArrayList<ColumnProvider<T, ?>>();
    }

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

    @Override
    public int getColumnCount() {
        return columns.size();
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        return columns.get(columnIndex).getValue(rows.get(rowIndex));
    }

    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return true;
    }

    @Override
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
        final ColumnProvider<T, ?> column = columns.get(columnIndex);
        column.setValue(rows.get(rowIndex), aValue);
        this.fireTableCellUpdated(rowIndex, columnIndex);
    }

    @Override
    public String getColumnName(int column) {
        return columns.get(column).getTitle();
    }

    public void addColumn(ColumnProvider<T, ?> column) {
        this.columns.add(column);
        this.fireTableStructureChanged();
    }

    public void addRow(T row) {
        this.rows.add(row);
        this.fireTableRowsInserted(this.rows.size() - 1, this.rows.size() - 1);
    }

    @Override
    public Class<?> getColumnClass(int columnIndex) {
        return this.columns.get(columnIndex).getValueClass();
    }

    public static abstract class ColumnProvider<T, V> {
        private       String   title;
        private final Class<V> valueClass;

        protected ColumnProvider(String title, Class<V> valueClass) {
            this.title = title;
            this.valueClass = valueClass;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public Class<V> getValueClass() {
            return valueClass;
        }

        public abstract V getValue(T dto);

        public abstract void setValue(T dto, Object value);
    }
}

例 - “应用程序”:

import javax.swing.*;
import java.awt.*;

public class JTableTest extends JFrame {

    private final JTable jTable;

    public JTableTest() throws HeadlessException {
        super("JFrame test");
        this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);

        final GridBagLayout layout = new GridBagLayout();
        final Container contentPane = this.getContentPane();
        contentPane.setLayout(layout);

        final GridBagConstraints gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.fill = GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;

        final DtoTableModel<PersonDto> dm = new DtoTableModel<PersonDto>();
        jTable = new JTable(dm);
        dm.addColumn(new PersonDto.NameColumn());
        dm.addColumn(new PersonDto.StreetColumn());
        dm.addRow(new PersonDto(1L, "Paul", "Mayfairy Street"));
        dm.addRow(new PersonDto(2L, "Peter", "Ferdinand Street"));
        JScrollPane scrollpane = new JScrollPane(jTable);
        contentPane.add(scrollpane, gridBagConstraints);

        this.pack();
    }

    public static void main(String[] args) {
        final JTableTest jTableTest = new JTableTest();
        jTableTest.setVisible(true);
    }

}