2010-07-21 28 views
5

Tôi có một lớp mô hình nhưLàm thế nào để có được một danh sách gõ đúng từ một ReflectionDBObject

public class MyClass extends ReflectionDBObject { 
    private List<NiceAttribute> attributes;  
    ... 
} 

public class NiceAttribute extends ReflectionDBObject { 
    ... 
} 

tôi tạo ra nó trong một cách typesafe, như

List<NiceAttribute> attrs = new ArrayList<NiceAttribute>(); 
attrs.add(new NiceAttribute()); 
MyClass myClass = new MyClass(); 
myClass.setAttributes(attrs); 

sau đó lưu nó vào Mông Cổ, và lấy với một mã như

DBCollection col = ...; 
col.setObjectClass(MyClass.class) 
MyClass foundObject = (MyClass)col.findOne(); 

Nhưng vấn đề là foundObject 's attributes trở thành một danh sách của BasicDBObject. Có vẻ như một người lái xe không thể (hoặc không muốn) phát hiện một loại mục danh sách. Đây có phải là giới hạn trình điều khiển hay tôi đã bỏ lỡ điều gì đó? Điều gì sẽ là một giải pháp thanh lịch cho vấn đề này?

BTW, tôi biết về Morphia, v.v. Có thể giải quyết được vấn đề. Nhưng dự án của tôi rất nhỏ, và tôi không muốn làm phức tạp những thứ có thêm một lớp trừu tượng.

Trả lời

-1

Bạn nên sử dụng Morphia. Nó thêm hỗ trợ cho POJO và các đối tượng nhúng (và các bộ sưu tập). Nó không có bất kỳ giới hạn nào mà trình điều khiển thực hiện về việc yêu cầu các lớp của bạn trông giống như một số Map<String, Object>.

+0

nha phiến được khoảng 10-15x chậm hơn người lái xe. Bạn nên viết mã của riêng mình để thực hiện ánh xạ. –

+0

Chúng tôi có các xét nghiệm về hiệu suất trong morphia cho thấy điều này không đúng. Nếu bạn có một số bài kiểm tra cho thấy vấn đề hiệu suất này, nó sẽ là tốt nếu bạn có thể chia sẻ chúng. –

+0

Tôi đã thực sự thực hiện các thử nghiệm rất cơ bản, nơi tôi viết cùng một mục nhập khoảng 10-20k lần, sử dụng trình điều khiển, sau đó là Spring Mongo Db rồi Morphia. Driver nhanh nhất, Spring Mongo chậm hơn khoảng 2 lần và morphia chậm hơn khoảng 7-10x. Ngay cả trên một mongo với sharding bộ sưu tập thực sự (trên nhiều máy) nó vẫn còn chậm hơn. Bạn có thể dễ dàng kiểm tra điều này. –

4

Vâng, có một giải pháp, nhưng bạn sẽ không thích nó. Về cơ bản bạn có thể chỉ định lớp tương ứng cho một đường dẫn nội bộ bên trong đối tượng của bạn. Đây là những gì tôi đã làm, và nó hoạt động:

public class Release extends ReflectionDBObject { 

    //other fields omitted  

    private List<ReleaseDetailsByTerritory> releaseDetailsByTerritory = new ArrayList<ReleaseDetailsByTerritory>(); 

} 

public class ReleaseDetailsByTerritory extends ReflectionDBObject { //...} 

Bây giờ, nếu tôi chỉ đơn giản làm điều này:

releaseColl.setObjectClass(Release.class); 
    releaseColl.setInternalClass("ReleaseDetailsByTerritory.0", ReleaseDetailsByTerritory.class); 
    Release r = (Release) releaseColl.findOne(); 
    //the internal list will contain ReleaseDetailsByTerritory type objects (not DBObjects) 
    System.out.println(r.getReleaseDetailsByTerritory().get(0).getClass().getName()); 

Điều crappy ở đây là bạn có thể không (hoặc ít nhất là tôi đã không tìm thấy cách) để chỉ định lớp ánh xạ cho TẤT CẢ các phần tử của một mảng được nhúng. Bạn KHÔNG THỂ làm điều gì đó như:

releaseColl.setInternalClass("ReleaseDetailsByTerritory", ReleaseDetailsByTerritory.class); 

hoặc

releaseColl.setInternalClass("ReleaseDetailsByTerritory.*", ReleaseDetailsByTerritory.class); 

bạn có thay vì để xác định các lớp bản đồ của bất kỳ yếu tố có thể có của các mảng nhúng:

releaseColl.setInternalClass("ReleaseDetailsByTerritory.0", ReleaseDetailsByTerritory.class); 
releaseColl.setInternalClass("ReleaseDetailsByTerritory.1", ReleaseDetailsByTerritory.class); 
releaseColl.setInternalClass("ReleaseDetailsByTerritory.2", ReleaseDetailsByTerritory.class); 
Các vấn đề liên quan