2012-03-12 41 views
8

Tôi muốn lặp qua các tài liệu trong MongoDB. Về cơ bản đây là tình huống. Tôi có một số JTextfields mà tôi muốn cư trú từ MongoDB. Vì vậy, mỗi lần người dùng nhấp vào nút Tiếp theo, một bản ghi mới phải được tìm nạp và hiển thị nó trong JTextField. Đây là mã của tôi:Lặp qua các tài liệu trong 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 

Tuy nhiên, nó không hoạt động. Nó chỉ hiển thị bản ghi đầu tiên mỗi lần tôi nhấn nút tiếp theo. Nếu tôi thay đổi

if(curs.hasNext()) { 

để

while(curs.hasNext()) { 

Nó chỉ hiển thị các bản ghi cuối cùng. Giúp đỡ xin vui lòng?

+0

hãy đặt tên lớp học của bạn bắt đầu bằng chữ cái viết hoa –

+0

Tôi sẽ ghi nhớ điều đó. Cảm ơn –

Trả lời

12

Như Kevin đã đề cập, vấn đề là bạn đang tìm nạp một con trỏ mới trên mỗi lần nhấn nút, vì vậy nó luôn bắt đầu lại. Có hai cách tiếp cận tiềm năng sẽ khắc phục vấn đề này.

  • Tìm nạp con trỏ một lần và di chuyển qua con trỏ tiếp theo. Để làm điều này, bạn tạo một trường con trỏ và tìm con trỏ trong hàm tạo của người nghe.

    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 
    
  • Giải pháp thay thế tiếp theo là để giữ một đếm có bao nhiêu mục đã được lấy ra, và cập nhật số lượng bỏ qua của con trỏ:

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

Phương pháp đầu tiên có khả năng là nhanh hơn một chút . Mongo có thể thực hiện phép lặp này bằng cách sử dụng một cây chuyển đổi đơn (ngược với nhiều đối với phương thức thứ hai).

Cách tiếp cận thứ hai không giữ con trỏ mở giữa các lần nhấp nút. Loại điều này là quan trọng đối với khả năng mở rộng trên các ứng dụng web giữa các yêu cầu, nhưng có thể không quan trọng nhiều với một ứng dụng gui (đặc biệt là nếu số lượng người dùng đồng thời nhỏ hơn).

Một ưu điểm lớn khác của phương pháp thứ hai là bạn có thể quay ngược lại - DBCursor không có phương pháp previous(), vì vậy bạn sẽ cần sử dụng phương pháp này nếu bạn thêm nút Trước đó.

Một số điều khác mà bạn có lẽ nên làm:

  • Thêm một lớp về mình để GUI xử lý mã sự kiện của bạn và mã truy cập dữ liệu MongoDB của bạn không được như vậy khá cao cùng. Điều này sẽ giúp bạn tiết kiệm một loạt các rắc rối nếu bạn di chuyển đến một cơ sở dữ liệu khác (có lẽ không), hoặc thêm một nút trước đó tích hợp với cùng một truy vấn (có lẽ nhiều khả năng).

  • Hãy nhớ đóng con trỏ khi bạn đã hoàn tất.DBCursor việc triển khai bị rò rỉ và cần phải được làm sạch bằng lược đồ thời gian chờ nếu bạn không đóng chúng một cách rõ ràng. Điều này đặc biệt đúng nếu bạn không hoàn toàn lặp qua toàn bộ tập kết quả. Điều này cũng cho cá thể Mongo, nhưng bạn sẽ chỉ cần một cá thể duy nhất trong số đó cho toàn bộ ứng dụng.

+0

Cảm ơn bạn Sean. Tôi sử dụng DBCursor foo = coll.find(). Skip (count) .limit (1); đếm ++; để sửa lỗi này. Kính trọng –

+0

Btw, làm cách nào để tôi triển khai nút trước? –

+0

@Mozammil: Tóm lại: sử dụng phương pháp thứ hai, nhưng trừ khỏi biến đếm, thay vì thêm vào nó. –

3

Vấn đề là bạn đang tìm nạp một con trỏ mới mỗi lần. Vì vậy, nó chỉ cho thấy kỷ lục đầu tiên. Tôi cho rằng bạn có nhiều trường văn bản, nếu bạn muốn thực hiện tất cả khởi tạo trong một hàm, bạn sẽ cần phải hoạt động trên một mảng các trường văn bản, không phải là một trường duy nhất. Hoặc, nếu ý định là gọi actionPerformed nhiều lần (một lần cho mỗi textField) thì bạn nên duy trì một số trạng thái (ví dụ: con trỏ) giữa các cuộc gọi đến actionPerformed. Tuy nhiên, tôi không làm nhiều việc lập trình GUI nên tôi không chắc nó là chính xác dựa trên đoạn mã bạn đã cung cấp.

+0

Cảm ơn bạn. Điều này đã giúp rất nhiều :) –

Các vấn đề liên quan