2012-03-12 3 views
8

Я хочу, чтобы контуры документов в MongoDB. В основном здесь ситуация. У меня есть некоторые JTextfields, которые я хочу заполнить из MongoDB. Поэтому каждый раз, когда пользователь нажимает кнопку «Далее», должна быть выбрана новая запись и отображать ее в JTextField. Вот мой код:Цитирование через документы в MongoDB

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

, пожалуйста, сделайте имена классов начинающимися с заглавной буквы –

+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 может выполнить эту итерацию, используя обход одного дерева (в отличие от многих для второго подхода).

Второй подход не удерживает курсор открытым между нажатиями кнопок. Такая вещь важна для масштабируемости веб-приложений между запросами, но может не иметь значения с помощью GUI-приложения (особенно если количество одновременных пользователей меньше).

Еще одно большое преимущество второго подхода заключается в том, что вы можете вернуться назад - DBCursor не имеет метода previous(), поэтому вам придется использовать этот подход, если вы когда-либо добавляете кнопку «Предыдущий».

Некоторые другие вещи, которые вы, вероятно, следует сделать:

  • Добавьте слой косвенности, чтобы ваш GUI код обработки событий и код доступа к данным MongoDB не совсем так сильно связаны между собой. Это сэкономит вам массу проблем, если вы перейдете в другую базу данных (возможно, маловероятно) или добавите предыдущую кнопку, которая интегрируется с тем же запросом (возможно, более вероятно).

  • Не забудьте закрыть курсор, когда закончите с ним.DBCursor утечки реализации, и их необходимо очистить с помощью схемы тайм-аута, если вы явно не закрываете их. Это особенно верно, если вы не полностью перебираете весь результирующий набор. Это относится и к экземпляру Mongo, но для всего приложения вам потребуется только один.

+0

Спасибо Шон. Я использую DBCursor foo = coll.find(). Skip (count) .limit (1); подсчитывать ++; чтобы исправить это. С уважением –

+0

Кстати, как реализовать предыдущую кнопку? –

+0

@Mozammil: В двух словах: используйте второй подход, но вычитайте из переменной count вместо добавления к нему. –

3

Проблема в том, что вы каждый раз выбираете новый курсор. Таким образом, он показывает только первую запись. Я предполагаю, что у вас есть несколько текстовых полей, если вы хотите сделать все инициализацию в одной функции, вам нужно будет работать с массивом текстовых полей, а не с одним. Или, если намерение состоит в вызове actionPerformed несколько раз (один раз для каждого текстового поля), вы должны поддерживать некоторое состояние (например, курсор) между вызовами actionPerformed. Однако я не делаю много программирования GUI, поэтому я не уверен, что правильно, на основе кода, который вы предоставили.

+0

Спасибо. Это очень помогло :) –