如何从 ResultSet 获取要更新的 JTable 数据

How to get JTable data to update from ResultSet

我正在开发一个地址簿程序(只是为了练习编码),但遇到了一些障碍。 table 最初是在启动时从结果集中填充的,该结果集是通过另一个 class 的方法获得的。这是用于填充列表的方法:

protected void populateContactList( int query ) 
{
    try
    {
        ResultSetMetaData metaData;
        contactListRS = contact.contactListQuery( query );
        metaData = contactListRS.getMetaData();
        int colCount = metaData.getColumnCount();

        String[] colTitlesArray = new String[] { 
                "ContactID", "Last Name", "First Name", "Company" };

        Vector< String > colTitles = new Vector< String >();
        colTitles.addAll( Arrays.asList( colTitlesArray ) );
        Vector< Vector< Object> > data = new Vector< Vector< Object > >();

        while ( contactListRS.next() )
        {
            Vector< Object > rowVector = new Vector< Object >();
            for ( int i = 1; i <= colCount; i++ )
            {
                rowVector.add( contactListRS.getObject( i ) );
            }
            data.add( rowVector );
        }

        contactTableModel.setDataVector( data, colTitles);

        // hides col 0 (contactID) from display on jtable
        // but retains data for retrieval from table model  
        contactDisplayTable.getColumnModel().getColumn( 0 )
            .setIdentifier( "contactID" );
        TableColumn contactIDCol = contactDisplayTable.
            getColumn( "contactID" );
        contactDisplayTable.getColumnModel().removeColumn( contactIDCol );

    }
    catch ( SQLException e )
    {
        System.err.println( e );
    }
}

此方法适用于在启动时使用初始查询初始显示 ResultSet 中的数据,但在 ResultSet 作为用户搜索结果更改后,table 被清除并且不显示新数据。这是用于初始查询的方法:

protected ResultSet contactListQuery( int query )
{
    try 
    {
        if ( query == 0 )
        {   
            listQuery = conn.prepareStatement( queryArr[ query ] );
            queryRS = listQuery.executeQuery();
        }
        else if ( query == 1 )
        {               
            queryRS = searchContacts();
            queryRS.last();
        }

    }
    catch (SQLException e) 
    {
        e.printStackTrace();
    }
    return queryRS; 
}

该方法传入一个int,表示调用方法。如果它是初始查询(或另一个旨在显示完整联系人列表的调用),则传递 0,从而导致完整列表查询。否则它被传递 1,在这种情况下它调用方法 searchContacts。在任何一种情况下,它 returns 一个 ResultSet 包含从数据库到 populateContactList 方法的相同 4 个元素。下面是 searchContacts 方法:

public ResultSet searchContacts() throws SQLException
    {
        String searchLN = addressBook.getSearchLN();
        String searchFN = addressBook.getSearchFN();
        String searchCO = addressBook.getSearchCO();

        boolean checkLN = searchLN.isEmpty();
        boolean checkFN = searchFN.isEmpty();
        boolean checkCO = searchCO.isEmpty();

        int rsLength;

        try 
        {
            if ( ( checkLN ) && ( checkFN ) && ( checkCO ) )
            {
                JOptionPane.showMessageDialog( addressBook.addressBookMainJF, 
                    "All fields are empty.\nPlease enter search parameters.", "Empty Search", JOptionPane.ERROR_MESSAGE );
                return contactListQuery( 0 );
            }
            else if ( !( checkLN ) && ( checkFN ) && ( checkCO ) )
            {
                listQuery = conn.prepareStatement( queryArr[ 1 ] );
                listQuery.setString( 1, searchLN );
            }
            else if ( ( checkLN ) && !( checkFN ) && ( checkCO ) )
            {
                listQuery = conn.prepareStatement( queryArr[ 2 ] );
                listQuery.setString( 1, searchFN );
            }
            else if ( !( checkLN ) && !( checkFN ) && ( checkCO ) )
            {
                listQuery = conn.prepareStatement( queryArr[ 3 ] );
                listQuery.setString( 1, searchLN );
                listQuery.setString( 2, searchFN ); 
            }
            else if ( ( checkLN ) && ( checkFN ) && !( checkCO ) )
            {
                listQuery = conn.prepareStatement( queryArr[ 4 ] );
                listQuery.setString( 1, searchCO );
            }
            else if ( ( checkLN ) && !( checkFN ) && !( checkCO ) )
            {
                listQuery = conn.prepareStatement( queryArr[ 5 ] );
                listQuery.setString( 1, searchFN );
                listQuery.setString( 2, searchCO );
            }
            else if ( !( checkLN ) && ( checkFN ) && !( checkCO ) )
            {
                listQuery = conn.prepareStatement( queryArr[ 6 ] );
                listQuery.setString( 1, searchLN );
                listQuery.setString( 2, searchCO );
            }
            else if ( !( checkLN ) && !( checkFN ) && !( checkCO ) )
            {
                listQuery = conn.prepareStatement( queryArr[ 7 ] );
                listQuery.setString( 1, searchLN );
                listQuery.setString( 2, searchFN );
                listQuery.setString( 3, searchCO );
            }
            else 
            {
                JOptionPane.showMessageDialog( addressBook.addressBookMainJF, 
                    "Error processing search.\nPlease try again.", "Search Error", JOptionPane.ERROR_MESSAGE );
            }

            searchRS = listQuery.executeQuery();
            searchRS.last();
            rsLength = searchRS.getRow();

            if ( rsLength < 1 )
            {
                return contactListQuery( 0 );
            }
        } 
        catch ( SQLException e ) 
        {

            e.printStackTrace();
        }
        searchRS.first();
        return searchRS;
    }

显然,此方法确定哪些字段包含用户输入,将用户输入填充到相应的查询中,执行查询和 returns ResultSet。在任何情况下,ResultSet 中都包含与完整列表查询相同的 4 个元素。

我测试了结果集中是否包含查询后的数据,如果有匹配,它总是包含。我还进行了检查以确保将 ResultSet 返回给 populateContactList 方法,事实确实如此。我相信问题出在 populateContactList 方法中的某个地方,我只是无法弄清楚问题出在哪里。我的一个理论是 table 可能需要通过 contactTableModel.fireTableDataChanged(); 刷新,我在 populateContactList 方法的不同点尝试过,但这并没有解决问题。也许有类似的东西可以工作我没有想到?

我意识到这需要看很多东西,我只是希望任何愿意提供帮助的人都能够看到所有涉及的代码,而不必猜测它可能是什么样子。对此提供的任何帮助将不胜感激。如果其中任何内容看起来很业余或者冗长,我提前道歉。只是想对这个问题做到彻底和准确。

我自己想出来的。显然,在 searchContacts 方法中的 catch 块之前的最后一点是抛出东西。我删除了这个位:

searchRS.last(); 
rsLength = searchRS.getRow();
if ( rsLength < 1 ) 
{ 
    return contactListQuery( 0 ); 
}  

现在可以正常使用了。只需要想出另一种方法来处理空的搜索结果 RS,但我可能可以使用 JOptionPane 来解决这个问题,以通知用户没有找到结果。