Java 使用SQL时,我应该如何处理TableModel更新?
我的GUI包括一个Java 使用SQL时,我应该如何处理TableModel更新?,java,sql,swing,jtable,Java,Sql,Swing,Jtable,我的GUI包括一个JTable和几个表单,这些表单可能触发INSERT、UPDATE或DELETESQL查询。无论何时发生,我都希望我的表得到相应的更新。由于必须更新TableModel和远程SQL表,因此有几种方法可以继续 首先更新SQL表,然后选择修改后的数据,并调用fireTableDataChanged()这就是我目前正在做的事情。它保证表和数据库完全同步。然而,TableModel在从ResultSet提取数据之前不会更新,在我的例子中,整个过程平均需要0.5到1秒。这不算太坏,但也
JTable
和几个表单,这些表单可能触发INSERT
、UPDATE
或DELETE
SQL查询。无论何时发生,我都希望我的表得到相应的更新。由于必须更新TableModel
和远程SQL表,因此有几种方法可以继续
- 首先更新SQL表,然后
这就是我目前正在做的事情。它保证表和数据库完全同步。然而,选择修改后的数据,并调用
fireTableDataChanged()
在从TableModel
提取数据之前不会更新,在我的例子中,整个过程平均需要0.5到1秒。这不算太坏,但也不算太好ResultSet
- 同时更新它们,修改
,使之与我期望的上一个方法相匹配。这可以提高客户端的性能,因为更改几乎是即时的,SQL内容将“在后台”运行。但是我不确定是否会丢失表和数据库之间的同步,这看起来像是肮脏的方式TableModel
- 将这两种方法混合使用。也许快速的单单元格更新应该使用第二种方法,而
s和INSERT
s需要第一种方法?虽然效率更高,但感觉不一致DELETE
- 还有别的办法吗?
我应该如何进行?请分享您在这方面的经验。我喜欢您使用
SELECT
从SQL表更新JTable
的第一选择
如果您担心0.5-1秒的暂停,您可以通过以下方式混合第一个和第二个变量:立即使用“预期”结果更新表,执行SQL,然后选择修改后的数据并检查它是否与当前数据相同。我认为在大多数情况下,它们都是相同的,因此不需要更新
JTable
,但也可以获得同步的模型。我想到的第一种方法是创建AbstractTableModel
的子类,并将数据存储在其私有ArrayList
字段中。在其构造函数中,使用要在表中显示的数据查询数据库
如果向表中添加了一行,则将向数据库激发一条插入了数据的INSERT
语句
public class MyTableModel extends AbstractTableModel{
private List<Person> dataSource;
public MyTableModel(){
dataSource = new ArrayList<Person>();
//query the database then add the queried data to the dataSource,
//you should do it in the background, using SwingWorker
//call fireTableRowsInserted with proper arguments
}
@Override
public int getColumnCount() {
return 3;
}
@Override
public int getRowCount() {
return dataSource.size();
}
@Override
public Object getValueAt(int row, int col) {
Object retVal = null;
if(col == 0)dataSource.get(row).getFirstName();
else if(col == 1)dataSource.get(row).getLastName();
else if(col == 2)dataSource.get(row).getOccupation();
return retVal;
}
@Override
public void setValueAt(Object value, int row, int col){
//validate if the update is possible, if yes proceed
//update the value in the DB
//update the value in the arraylist
//call super.setValueAt(value, row, col);
}
public void addRow(Person p){
//validate if the person is insertable, if yes proceed
//INSERT the person to the DB
//add the person to the arraylist
//call fireTableRowsInserted
}
public void deleteRow(int row){
//call fireTableRowsDeleted
}
}
如果对表中的单元格进行了更新,请验证更新是否可行。如果可能,将向数据库触发更新
如果删除了一行,则会向数据库激发一条DELETE FROM
语句
public class MyTableModel extends AbstractTableModel{
private List<Person> dataSource;
public MyTableModel(){
dataSource = new ArrayList<Person>();
//query the database then add the queried data to the dataSource,
//you should do it in the background, using SwingWorker
//call fireTableRowsInserted with proper arguments
}
@Override
public int getColumnCount() {
return 3;
}
@Override
public int getRowCount() {
return dataSource.size();
}
@Override
public Object getValueAt(int row, int col) {
Object retVal = null;
if(col == 0)dataSource.get(row).getFirstName();
else if(col == 1)dataSource.get(row).getLastName();
else if(col == 2)dataSource.get(row).getOccupation();
return retVal;
}
@Override
public void setValueAt(Object value, int row, int col){
//validate if the update is possible, if yes proceed
//update the value in the DB
//update the value in the arraylist
//call super.setValueAt(value, row, col);
}
public void addRow(Person p){
//validate if the person is insertable, if yes proceed
//INSERT the person to the DB
//add the person to the arraylist
//call fireTableRowsInserted
}
public void deleteRow(int row){
//call fireTableRowsDeleted
}
}
公共类MyTableModel扩展了AbstractTableModel{
私有列表数据源;
公共MyTableModel(){
dataSource=新的ArrayList();
//查询数据库,然后将查询的数据添加到数据源,
//您应该在后台使用SwingWorker进行此操作
//使用正确的参数调用fireTableRowsInserted
}
@凌驾
public int getColumnCount(){
返回3;
}
@凌驾
public int getRowCount(){
返回dataSource.size();
}
@凌驾
公共对象getValueAt(整数行,整数列){
Object retVal=null;
if(col==0)dataSource.get(row.getFirstName();
else if(col==1)dataSource.get(row.getLastName();
else if(col==2)dataSource.get(row.getocculation();
返回返回;
}
@凌驾
public void setValueAt(对象值、整行、整列){
//验证是否可以进行更新,如果可以,请继续
//更新数据库中的值
//更新arraylist中的值
//调用super.setValueAt(value,row,col);
}
公共无效地址行(p人){
//验证此人是否可插入,如果是,则继续
//将此人插入数据库
//将此人添加到arraylist
//调用fireTableRowsInserted
}
公共void deleteRow(int行){
//调用fireTableRowsDeleted
}
}
选择修改后的数据,并使用返回的结果集创建一个新的TableModel
,这就是我目前正在做的事情。它保证表和数据库完全同步。然而,TableModel
在从ResultSet
提取数据之前不会更新,在我的例子中,整个过程平均需要0.5到1秒。这不算太坏,但也不算太好
- 错误的想法创建一个新的XxxTableModel不仅适得其反,一个XxxTableModel可以用于所有视图,对于一些JTables/jlist,只有在没有使用RowSorter或RowFilter的情况下,才需要注意,那么代码中的逻辑必须包含基于一个XxxTableModel的所有jtable的过滤排序
- 为静态数据(StandingData)创建单独的XxxTableModels
TableModel
,使之与我期望的上一个方法相匹配。这可以提高客户端的性能,因为更改几乎是即时的,SQL内容将“在后台”运行。但是我不确定是否会丢失表和数据库之间的同步,这看起来像是肮脏的方式
- 不知道,基本上,如果输入掩码(表单)中的值存储在数据库中,JTable应该被刷新,并且输入表单以默认值结束
- 可能是这样,但需要同步数据库、JTable中的镜像和输入掩码
插入
s和删除
s