2011-07-01 53 views
10

Mục tiêu của tôi là thực sự đổ tất cả dữ liệu của cơ sở dữ liệu vào một tệp XML. Cơ sở dữ liệu không quá lớn, khoảng 300MB. Vấn đề là tôi có một giới hạn bộ nhớ 256MB (chỉ trong JVM). Vì vậy, rõ ràng tôi không thể chỉ đọc tất cả mọi thứ vào bộ nhớ.Xử lý số lượng dữ liệu rất lớn trong MyBatis

Tôi đã giải quyết vấn đề này bằng iBatis (có nghĩa là iBatis, không phải myBatis) bằng cách gọi số getList(... int skip, int max) nhiều lần, với số tăng skip. Điều đó giải quyết vấn đề bộ nhớ của tôi, nhưng tôi không ấn tượng với tốc độ. Các tên biến cho thấy rằng phương thức thực hiện dưới mui xe là đọc toàn bộ bỏ qua tập kết quả sau đó ghi lại được chỉ định. Điều này nghe khá dư thừa với tôi (tôi không nói đó là những gì phương pháp đang làm, tôi chỉ đoán dựa trên tên biến).

Bây giờ, tôi đã chuyển sang myBatis 3 cho phiên bản tiếp theo của đơn đăng ký của mình. Câu hỏi của tôi là: là có cách nào tốt hơn để xử lý số lượng lớn dữ liệu chunk bởi chunk trong myBatis? Có anyway để làm cho myBatis đầu tiên N hồ sơ, trả lại cho người gọi trong khi vẫn giữ kết quả thiết lập kết nối mở để thời gian tiếp theo người dùng gọi getList (...) nó sẽ bắt đầu đọc từ N + 1 hồ sơ mà không làm bất kỳ "bỏ qua"?

Trả lời

7

Không, mybatis không có đầy đủ khả năng kết quả luồng chưa.

EDIT 1: Nếu bạn không cần ánh xạ kết quả lồng nhau thì bạn có thể triển khai trình xử lý kết quả tùy chỉnh để truyền kết quả. trên các phiên bản MyBatis được phát hành hiện tại. (3.1.1) Giới hạn hiện tại là khi bạn cần thực hiện ánh xạ kết quả phức tạp. NestedResultSetHandler không cho phép trình xử lý kết quả tùy chỉnh. Bản sửa lỗi có sẵn và có vẻ như hiện được nhắm mục tiêu cho 3.2. Xem Issue 577.

Tóm lại, để truyền các tập kết quả lớn bằng MyBatis bạn cần.

  1. Implement your own ResultSetHandler.
  2. Tăng kích thước tìm nạp. (như được ghi chú bên dưới bởi Guillaume Perrot)
  3. Đối với bản đồ kết quả lồng nhau, hãy sử dụng bản sửa lỗi được thảo luận trên Issue 577. Bản sửa lỗi này cũng giải quyết một số vấn đề về bộ nhớ với tập hợp kết quả lớn.
16

myBatis CÓ THỂ kết quả luồng. Những gì bạn cần là một trình xử lý kết quả tùy chỉnh. Với điều này, bạn có thể lấy từng hàng riêng biệt và ghi nó vào tệp XML của bạn. Sơ đồ tổng thể trông giống như sau:

session.select(
    "mappedStatementThatFindsYourObjects", 
    parametersForStatement, 
    resultHandler); 

Trường hợp resultHandler là một cá thể của lớp thực hiện giao diện ResultHandler. Giao diện này chỉ có một phương thức handleResult. Phương thức này cung cấp cho bạn một đối tượng ResultContext. Từ ngữ cảnh này, bạn có thể truy xuất hàng hiện đang được đọc và làm điều gì đó với nó.

handleResult(ResultContext context) { 
    Object result = context.getResultObject(); 
    doSomething(result); 
} 
+8

Câu trả lời của bạn thiếu một chi tiết quan trọng: bạn cần phải thêm @Options (fetchSize = Integer.MIN_VALUE) (hoặc tương đương XML) vào bảng sao kê của mình. Và nó không hoạt động trong MyBatis 3.0.5 (tôi đã kiểm tra với bộ phân tích bộ nhớ Eclipse). Tôi đã nâng cấp lên MyBatis 3.1.1 và bây giờ quá trình phát trực tuyến hoạt động tốt. –

2

handleResult nhận được nhiều bản ghi như truy vấn được nhận, không tạm dừng.

Khi có quá nhiều bản ghi để xử lý tôi đã sử dụng sqlSessionFactory.getSession(). GetConnection(). Sau đó, như bình thường JDBC, nhận được một tuyên bố, có được kết quả, và xử lý từng người một hồ sơ. Đừng quên đóng phiên.

0

Nếu chỉ đổ tất cả dữ liệu mà không có bất kỳ yêu cầu đặt hàng nào từ bảng, tại sao không trực tiếp thực hiện phân trang trong SQL?Đặt giới hạn cho câu lệnh truy vấn, trong đó chỉ định id bản ghi khác nhau làm bù, để tách toàn bộ bảng thành các phần, mỗi phần có thể được đọc trực tiếp vào bộ nhớ nếu giới hạn hàng là một số hợp lý.

Các sql có thể là một cái gì đó như:

SELECT * FROM resource 
    WHERE "ID" >= continuation_id LIMIT 300; 

Tôi nghĩ rằng điều này có thể được xem như một giải pháp thay thế để bạn có thể đổ tất cả các dữ liệu bằng cách khối, được thoát khỏi những vấn đề tính năng khác nhau trong mybatis, hoặc bất kỳ Persistence lớp, hỗ trợ.

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