Цикл документов в MongoDB - PullRequest
8 голосов
/ 12 марта 2012

Я хочу просмотреть документы в 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()) {

Отображает только последнюю запись. Помогите, пожалуйста?

Ответы [ 2 ]

12 голосов
/ 12 марта 2012

Как упоминал Кевин, проблема в том, что вы нажимаете новый курсор при каждом нажатии кнопки, поэтому он всегда начинается заново. Есть два возможных подхода, которые помогут решить эту проблему.

  • Получите курсор один раз и двигайтесь по нему, когда нажимается следующий. Для этого вы делаете курсор полем и извлекаете курсор в конструкторе слушателя.

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

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

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

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

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

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

3 голосов
/ 12 марта 2012

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

...