2012-03-12 3 views
8

MongoDB에서 문서를 반복하고 싶습니다. 기본적으로 여기에 상황이 있습니다. MongoDB에서 채울 JTextfields가 있습니다. 따라서 사용자가 다음 버튼을 누를 때마다 새 레코드를 가져 와서 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 

그러나 작동하지 않습니다. 다음 버튼을 누를 때마다 첫 번째 레코드 만 표시됩니다. 내가

while(curs.hasNext()) { 

if(curs.hasNext()) { 

을 변경하는 경우 그것은 단지 마지막 레코드를 표시합니다. 도와주세요?

+0

클래스 이름은 대문자로 시작하십시오. –

+0

나는 이것을 염두에 두겠습니다. 감사합니다 –

답변

12

Kevin이 언급했듯이 문제는 각 버튼을 누를 때마다 새 커서를 가져 오는 것이므로 항상 다시 시작합니다. 이 문제를 해결할 수있는 두 가지 접근 방법이 있습니다.

  • 커서를 한 번 가져 와서 다음을 누를 때까지 이동하십시오. 이렇게하려면 커서를 필드로 만들고 수신기의 생성자에서 커서를 가져옵니다.

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

첫 번째 방법은 약간 빠른 될 가능성이 높습니다 :

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 
  • 다음 대안은 검색된 얼마나 많은 항목의 수를 유지하고, 커서의 건너 뛰기 횟수를 업데이트하는 것입니다 . Mongo는 단일 트리 탐색을 사용하여이 반복을 수행 할 수 있습니다 (두 번째 접근 방법과 달리).

    두 번째 방법은 버튼 클릭 사이에 커서를 열어 두지 않습니다. 이러한 종류의 요구 사항은 요청간에 웹 앱의 확장성에 중요하지만 GUI 애플리케이션의 경우에는 중요하지 않을 수 있습니다 (특히 동시 사용자 수가 적은 경우).

    두 번째 방법의 또 다른 큰 장점은 뒤로 이동할 수 있다는 것입니다. DBCursor에는 previous() 메서드가 없으므로 이전 단추를 추가 한 경우이 방법을 사용해야합니다.

    일부 다른 것들 당신은 아마 수행해야합니다

    • 코드를 처리하여 GUI 이벤트와 MongoDB를 데이터 액세스 코드가 꽤 높은 결합되지 않도록 간접 레이어를 추가합니다. 이렇게하면 다른 데이터베이스로 이동하거나 (아마도있을 법하지 않음) 같은 쿼리로 통합되는 이전 버튼을 추가하는 경우 (아마 더 가능성이 있음) 많은 문제를 줄일 수 있습니다.

    • 끝나면 커서를 닫아야합니다.DBCursor 구현은 누출되므로 명시 적으로 닫지 않으면 시간 초과 구성표로 정리해야합니다. 전체 결과 집합을 완전히 반복하지 않으면 특히 그렇습니다. 이것은 Mongo 인스턴스에도 적용됩니다.하지만 전체 애플리케이션에 대해 하나만 필요합니다.

  • +0

    Sean. DBCursor foo = coll.find()를 사용합니다. skip (count) .limit (1); 카운트 ++; 이 문제를 해결할 수 있습니다. 감사합니다 –

    +0

    Btw, 어떻게 이전 버튼을 구현합니까? –

    +0

    @Mozammil : 간단히 말해서 : 두 번째 접근법을 사용하지만 추가하지 말고 count 변수에서 빼십시오. –

    3

    문제는 매번 새 커서를 가져 오는 것입니다. 그래서 첫 번째 기록 만 보여줍니다. 하나 이상의 텍스트 필드가 있다고 가정합니다. 한 함수에서 모든 초기화를 수행하려면 하나의 텍스트 필드가 아닌 여러 텍스트 필드에 대해 작업해야합니다. 또는 actionPerformed를 여러 번 호출하려는 경우 (각 textField에 대해 한 번) actionPerformed에 대한 호출간에 일정 상태 (예 : 커서)를 유지해야합니다. 그러나 많은 GUI 프로그래밍을 수행하지 않으므로 제공 한 코드 스 니펫을 기반으로 올바른 코드인지 확신 할 수 없습니다.

    +0

    감사. 이것은 많은 도움이되었습니다. –