我想循环遍历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
然而,它不起作用。每次按下一个按钮时,它只显示第一条记录。如果我改变
if(curs.hasNext()) {
到
while(curs.hasNext()) {
它仅显示最后一条记录。请帮忙?
答案 0 :(得分: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
下一个选择是保持已检索的项目数,并更新光标的跳过次数:
DBCursor foo = coll.find().skip(count).limit(1);
count++;
//use one value from the cursor as before
第一种方法可能会稍快一些。 Mongo可以使用单个树遍历来执行此迭代(与第二种方法的许多迭代相反)。
第二种方法不会在按钮点击之间保持光标打开。这类事情对于请求之间的Web应用程序的可伸缩性很重要,但对于gui应用程序可能并不重要(特别是如果并发用户的数量较小)。
第二种方法的另一大优势是你可以倒退 - DBCursor
没有previous()
方法,所以如果你添加了一个上一个按钮,你需要使用这种方法
你应该做的其他一些事情:
添加一个间接层,以便您的GUI事件处理代码和MongoDB数据访问代码不会高度耦合。如果您移动到另一个数据库(可能不太可能),或者添加一个与同一查询集成的前一个按钮(可能更有可能),这将为您节省大量麻烦。
请记住在完成光标后关闭光标。 DBCursor
实现泄漏,如果没有显式关闭它们,需要使用超时方案进行清理。如果您没有完全遍历整个结果集,则尤其如此。这也适用于Mongo实例,但您只需要整个应用程序中的一个。
答案 1 :(得分:3)
问题是你每次都要获取一个新光标。所以它只显示第一条记录。我假设你有多个文本字段,如果你想在一个函数中进行所有初始化,你需要操作一个文本字段数组,而不是一个文本字段。或者,如果打算多次调用actionPerformed(每个textField一次),那么你应该在调用actionPerformed之间保持一些状态(例如光标)。我不做很多GUI编程,所以根据你提供的代码片段,我不确定哪个是正确的。