2013-07-25 67 views
5

Tôi cần ngủ đông để tạo sql như thế này INSERT INTO table_a (a_id, a_name) VALUES (5, 'a5'),(6, 'a6');.cách tạo HQL sẽ tạo SQL để chèn nhiều giá trị vào một câu lệnh?

Với sql như thế bạn có thể thêm 2 hàng với 1 câu lệnh. Tôi có thể lấy

a_id, a_name 

------------------ 
5  a5 
6  a6 

Khi ở chế độ ngủ đông, khi bạn lưu tập hợp một đến nhiều mối quan hệ, hibernate sẽ chèn với nhiều tuyên bố chèn. Điều này sẽ gây ra nếu bạn chèn 1000 hàng tới 1 bảng với HQL sẽ dẫn đến một cái gì đó như thế này:

INSERT INTO scoring.table_a (`a_id`, `a_name`) VALUES (1, 'a'); 
INSERT INTO scoring.table_a (`a_id`, `a_name`) VALUES (2, 'a'); 
.... 
... 
.. 
INSERT INTO scoring.table_a (`a_id`, `a_name`) VALUES (1000, 'a'); 

Và thời gian trôi qua là:

Executed 1,000 queries; elapsed time (seconds) - Total: 0.78, SQL query: 0.78, Building output: 0 

Và khi tôi thử nghiệm với cùng một giá trị, sử dụng SQL INSERT INTO table_a (a_id, a_name) VALUES (5, 'a'),(6, 'a'),(),...,...,(1000, 'a'); sẽ dẫn đến thời gian trôi qua như thế này:

Query 1 of 1, Rows read: 0, Elapsed time (seconds) - Total: 0.02, SQL query: 0.02, Building output: 0 

kết quả của thử nghiệm của tôi là, 1 tuyên bố 1000 giá trị (0.02s) sẽ vào khoảng 39 lần nhanh hơn hơn 1000 câu lệnh chèn với mỗi giá trị có 1 giá trị (0,78) như hibernate. Vì vậy, có một cách để làm cho HQL mà tạo ra SQL như thế để chèn hoặc có thể cập nhật cũng có. Hoặc điều này có nghĩa là chúng ta phải ghi đè lên phương ngữ ngủ đông?

Cảm ơn bất kỳ gợi ý

Trả lời

0

Bạn có thể thiết lập hibernate.jdbc.batch_size tài sản cho một giá trị khác không. Nó sẽ cho phép Hibernate sử dụng hàng loạt INSERT. Hãy xem a official documentation.

Các mã sau đây là một ví dụ làm thế nào để sử dụng chèn hàng loạt JDBC qua Hibernate:

Session session = sessionFactory.openSession(); 
Transaction tx = session.beginTransaction(); 
for (int i=0; i < 10000; i++) { 
    RecordA record = new RecordA(.....); 
    session.save(record); 
    if (i % BATCH_SIZE == 0) { // BATCH_SIZE is your choice, but equal to property 
     //flush a batch of inserts and release memory: 
     session.flush(); 
     session.clear(); 
    } 
} 
tx.commit(); 
session.close(); 

Nó cũng thảo luận ở đây: Hibernate batch size confusion

+1

Theo như tôi biết, cài đặt batch_size là vấn đề tối ưu hóa bộ nhớ để giảm thiểu vòng lặp mà không bị rò rỉ bộ nhớ. ** chèn vẫn nằm trong nhiều câu lệnh trong một giao dịch **. do đó batch_size không phải là giải pháp ở đây. Nhưng cảm ơn anyway .. – Angga

+0

Như đã lưu ý trong [Hibernate batch size confused] (http://stackoverflow.com/questions/6687422/hibernate-batch-size-confusion), 'hibernate.jdbc.batch_size' cho phép sử dụng JDBC2 API tính năng kết hợp ** các câu lệnh INSERT ** liên tiếp với ** chữ ký giống hệt nhau ** (bảng & cols) vào một câu lệnh có nhiều ** nếu khóa chính không phải là ** 'GenerationType.Identity'. –

+0

có, và ** các câu lệnh INSERT liên tiếp ** khác với ** câu lệnh INSERT đơn **. và như tôi đã nói trước đây trong bình luận của tôi, ** chèn vẫn còn trong nhiều tuyên bố trong một giao dịch **. – Angga

0

HQL chỉ hỗ trợ các INSERT INTO ......... CHỌN .........; không có cơ hội để viết INSERT INTO ……… GIÁ TRỊ, ý tôi là khi viết truy vấn chèn, chúng tôi cần chọn giá trị từ bảng khác, chúng tôi không thể chèn các giá trị của riêng mình theo cách thủ công. (see documentationthis)