循环遍历MongoDB中的文档

8 java loops documents mongodb

我想循环遍历MongoDB中的文档.基本上就是这种情况.我有一些JTextfields,我想从MongoDB填充.因此,每次用户单击"下一步"按钮时,都必须获取新记录并将其显示在JTextField中.这是我的代码:

public class nextstud implements ActionListener
{
    public void actionPerformed(ActionEvent e) {
        try {
            Mongo s = new Mongo();
            DB db = s.getDB( "omrs1" );
            DBCollection coll = db.getCollection("Student") ;

            DBCursor curs = coll.find();

            if(curs.hasNext()) {
                DBObject o = curs.next();
                String fname = (String) o.get("Firstname") ; 
                String lname = (String) o.get("Lastname") ; 
                String sid = (String) o.get("StudentID") ; 
                String prg = (String) o.get("Programme") ;
                String lvl = (String) o.get("Level") ;

                txtfname.setText(fname) ; 
            }

            btndelstud.setEnabled(true); 
            btnbkstud.setEnabled(true) ;
            btnfwdstud.setEnabled(true);

        } catch (UnknownHostException x) {
            x.printStackTrace();
        } catch (MongoException x) {
            x.printStackTrace();
        }
    }
} // end class
Run Code Online (Sandbox Code Playgroud)

但是,它不起作用.每次按下一个按钮时,它只显示第一条记录.如果我改变了

if(curs.hasNext()) {
Run Code Online (Sandbox Code Playgroud)

while(curs.hasNext()) {
Run Code Online (Sandbox Code Playgroud)

它仅显示最后一条记录.请帮忙?

Sea*_*lly 12

正如凯文所说,问题是你在按下每个按钮时都会获得一个新光标,所以它总是重新开始.有两种可能的方法可以解决这个问题.

  • 获取光标一次,并在按下下一步时移动光标.为此,您将光标设为一个字段,并在侦听器的构造函数中获取光标.

    public class Nextstud implements ActionListener {
        private DBCursor curs;
        public Nextstud() {
            Mongo s = new Mongo();
            DB db = s.getDB( "omrs1" );
            DBCollection coll = db.getCollection("Student") ;
    
            curs = coll.find();
        }
    
        public void actionPerformed(ActionEvent e) {
            try {
                if(curs.hasNext()) {
                    DBObject o = curs.next();
                    String fname = (String) o.get("Firstname") ; 
                    String lname = (String) o.get("Lastname") ; 
                    String sid = (String) o.get("StudentID") ; 
                    String prg = (String) o.get("Programme") ;
                    String lvl = (String) o.get("Level") ;
    
                    txtfname.setText(fname) ; 
                }
    
                btndelstud.setEnabled(true); 
                btnbkstud.setEnabled(true) ;
                btnfwdstud.setEnabled(true);
            } catch (UnknownHostException x) {
                x.printStackTrace();
            } catch (MongoException x) {
                x.printStackTrace();
            }
        }
    } // end class
    
    Run Code Online (Sandbox Code Playgroud)
  • 下一个选择是保持已检索的项目数,并更新光标的跳过计数:

    DBCursor foo = coll.find().skip(count).limit(1);
    count++;
    //use one value from the cursor as before
    
    Run Code Online (Sandbox Code Playgroud)

第一种方法可能会稍快一些.Mongo可以使用单个树遍历来执行此迭代(与第二种方法的许多迭代相反).

第二种方法不会在按钮单击之间保持光标打开.这类事情对于请求之间的Web应用程序的可伸缩性很重要,但对于gui应用程序可能并不重要(特别是如果并发用户的数量较小).

第二种方法的另一大优势是你可以倒退 - DBCursor没有previous()方法,所以如果你添加一个Previous按钮,你需要使用这种方法.

你应该做的其他一些事情:

  • 添加一个间接层,以便您的GUI事件处理代码和MongoDB数据访问代码不是那么高度耦合.如果您移动到另一个数据库(可能不太可能),或者添加一个与同一查询集成的前一个按钮(可能更有可能),这将为您节省大量麻烦.

  • 记得在完成光标后关闭光标.DBCursor实现泄漏,如果没有显式关闭它们,需要使用超时方案进行清理.如果您没有完全遍历整个结果集,则尤其如此.这也适用于Mongo实例,但是您只需要为整个应用程序中的一个实例.