在JDBC应用程序中向前和向后移动ResultSet游标

时间:2013-04-04 18:41:43

标签: java jdbc

我正在开发一个Stock Inventory System软件,该软件使用JDBC ODBC连接连接到Ms Sql服务器。我想将结果集光标移动到下一行和后一行。连接工作,程序可以从数据库中检索字段,因此没有问题。

我这里的代码是一个标有“下一步”的按钮。 当您单击此按钮时,它应移动到数据库中的下一行并从该行检索数据。检索到的数据应显示在“textfields”中。问题是当我点击下一步时没有任何反应?

    private void NextBtnActionPerformed(java.awt.event.ActionEvent evt) {                                        
    try {
        Class.forName("sun.jdbc.odbc.JdbcOdbc");
        Connection con;
        con = DriverManager.getConnection("jdbc:odbc:StockInventory","sa","123");           

        Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);
        String query = "select * from Stocktbl";

        ResultSet rs; 
        rs = stmt.executeQuery(query); 


        if(!rs.isLast()) {
            rs.next();

            TxtStockid.setText(rs.getString("StockId"));
            TxtItem.setText(rs.getString("ItemName"));
            TxtQuantity.setText(rs.getString("Quantity"));
            TxtUnitprice.setText(rs.getString("UnitPrice"));
            TxtNetprice.setText(rs.getString("NetPrice"));
            TxtUnitweight.setText(rs.getString("UnitWeight"));
            TxtNetweight.setText(rs.getString("Netweight"));
            TxtDescription.setText(rs.getString("Description"));
        }

        rs.close();
        stmt.close();
        con.close();




    } 
    catch (SQLException ex) 
    {
        Logger.getLogger(StockScr.class.getName()).log(Level.SEVERE, null, ex);
    }
    catch (ClassNotFoundException ex) 
    {
        Logger.getLogger(StockScr.class.getName()).log(Level.SEVERE, null, ex);
    }       
}

以下是该程序的其余编码,“下一步”按钮被添加到此面板中。

public class StockScr extends javax.swing.JPanel {
ResultSet rs;
Connection con = null;

public StockScr() {
    initComponents();
    ShowTable();

}

void ShowTable(){
    try {
        Class.forName("sun.jdbc.odbc.JdbcOdbc");
        Connection con;
        con = DriverManager.getConnection("jdbc:odbc:StockInventory","sa","123");           

        Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
        String query = "select * from Stocktbl";           
        ResultSet rs; 
        rs = stmt.executeQuery(query);

        rs.first();
            TxtStockid.setText(rs.getString("StockId"));
            TxtItem.setText(rs.getString("ItemName"));
            TxtQuantity.setText(rs.getString("Quantity"));
            TxtUnitprice.setText(rs.getString("UnitPrice"));
            TxtNetprice.setText(rs.getString("NetPrice"));
            TxtUnitweight.setText(rs.getString("UnitWeight"));
            TxtNetweight.setText(rs.getString("Netweight"));
            TxtDescription.setText(rs.getString("Description"));

        rs.close();
        stmt.close();
        con.close();

    } 
    catch (SQLException ex) 
    {
        Logger.getLogger(StockScr.class.getName()).log(Level.SEVERE, null, ex);
    }
    catch (ClassNotFoundException ex) 
    {
        Logger.getLogger(StockScr.class.getName()).log(Level.SEVERE, null, ex);
    }        
}


public void fetchResultSet()
{

try {
    if(con==null || con.isClosed())
    {
      Class.forName("sun.jdbc.odbc.JdbcOdbc");
      con = DriverManager.getConnection("jdbc:odbc:StockInventory","sa","123");           
    }
    Statement stmt =     con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
    String query = "select * from Stocktbl";
    rs = stmt.executeQuery(query); 
  }catch(Exception ex){
     System.out.println(ex);
     Logger.getLogger(StockScr.class.getName()).log(Level.SEVERE, null, ex); 
  }

     try
     {
        if(con != null)
        {
          con.close();
        }
     }catch(Exception ex){

     }

}


private void NextBtnActionPerformed(java.awt.event.ActionEvent evt) {

try
{

 if (rs == null)
 {
    fetchResultSet();
 }

 if (rs!=null)
 {
    if (rs.next())
    {
        TxtStockid.setText(rs.getString("StockId"));
        TxtItem.setText(rs.getString("ItemName"));
        TxtQuantity.setText(rs.getString("Quantity"));
        TxtUnitprice.setText(rs.getString("UnitPrice"));
        TxtNetprice.setText(rs.getString("NetPrice"));
        TxtUnitweight.setText(rs.getString("UnitWeight"));
        TxtNetweight.setText(rs.getString("Netweight"));
        TxtDescription.setText(rs.getString("Description"));         
    }
   else
   {
      rs = null;
   }
 }
}catch(Exception ex){
  System.out.println(ex); 
  }        
}

4 个答案:

答案 0 :(得分:3)

在点击next按钮之前,您应该创建连接到数据库并仅获取一次新记录。然后使用rs.next方法中的NextBtnActionPerformed继续前进。

例如,您应该按如下方式调用fetchResultSet方法,并且应该在单击next按钮之前调用它。

ResultSet rs;
Connection con = null;
public void fetchResultSet()
{

   try {
        if(con==null || con.isClosed())
        {
          Class.forName("sun.jdbc.odbc.JdbcOdbc");
          con = DriverManager.getConnection("jdbc:odbc:StockInventory","sa","123");           
        }
        Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
        String query = "select * from Stocktbl";
        rs = stmt.executeQuery(query); 
      }catch(Exception ex)
      {
         System.out.println(ex);
         Logger.getLogger(StockScr.class.getName()).log(Level.SEVERE, null, ex);

         try
         {
            if(con != null)
            {
              con.close();
            }
         }catch(Exception x){}
      }
}

然后你的NextBtnActionPerformed应该是这样的:

private void NextBtnActionPerformed(java.awt.event.ActionEvent evt)
{
  try
  {
     if (rs == null)
     {
        fetchResultSet();
     }
     if (rs!=null)
     {
        if (rs.next())
        {
            TxtStockid.setText(rs.getString("StockId"));
            TxtItem.setText(rs.getString("ItemName"));
            TxtQuantity.setText(rs.getString("Quantity"));
            TxtUnitprice.setText(rs.getString("UnitPrice"));
            TxtNetprice.setText(rs.getString("NetPrice"));
            TxtUnitweight.setText(rs.getString("UnitWeight"));
            TxtNetweight.setText(rs.getString("Netweight"));
            TxtDescription.setText(rs.getString("Description"));         
        }
       else
       {
          rs = null;
       }
     }
  }catch(Exception ex){System.out.println(ex);}
}

答案 1 :(得分:2)

您需要在之前致电rs.next() ,然后致电rs.isLast()。对rs.isLast()的调用在功能方面提供的内容并不多:

if (rs.next()) {
    TxtStockid.setText(rs.getString("StockId"));
    ...

使用这种方法,您不会推进ResultSet光标,因此每次单击按钮时都会获得相同的数据。返回不同的行需要WHERE子句。如果记录总量不大,则缓存数据将是首选方法。

缓存适用于项目数量相对较小且不需要大规模扩展的情况。在这种情况下,您可以在启动时将所有数据加载到ArrayList<MyStockItem>并通过List导航,而不是进行数据库连接。 EHCache等产品可用于此目的。

答案 2 :(得分:1)

您可以在每次点击按钮时创建新的结果集。因此,新的结果集将光标放在第一个位置,这就是为什么在点击它时总是得到相同的记录。要解决这个问题,您需要创建结果集字段,然后在主类的constrcutor中填入记录,然后对此结果集进行操作。

答案 3 :(得分:0)

你应该使用

while(rs.next())  instead of if(!rs.isLast())  and then rs.next()

我不认为结果集提供了向后移动的api。问题是你为什么需要它。