Đối với hoạt động CRUD trên một tập hợp dữ liệu, nó là tốt đẹp để sử dụng một bảng trung gian. Điều này tránh được số lượng lớn các truy vấn được đặt trên các tập dữ liệu lớn.
Trước khi đưa ra đề nghị của tôi để giải quyết vấn đề, tôi muốn chỉ ra một số nhận xét tôi có vào cấu trúc của cơ sở dữ liệu:
- Các
total
lĩnh vực rõ ràng là một lĩnh vực tính toán. Những thông tin này không tốt để đưa vào cơ sở dữ liệu. Nó được tính theo yêu cầu.
- Toàn bộ tập hợp dữ liệu rõ ràng là một phần của tài liệu (hóa đơn). Vì vậy, phải có một trường trong cơ sở dữ liệu xác định duy nhất tài liệu mà dữ liệu có liên quan.
Ngoài ra, tôi muốn nói rằng các quyết định như vậy được thực hiện cho một cơ sở dữ liệu cụ thể. Trong trường hợp này, giải pháp của tôi liên quan đến mysql.
Đây là DDL của bảng mà trên đó các đoạn mã dưới chạy
CREATE TABLE `invoice` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`invoice_id` int(10) unsigned NOT NULL,
`description` varchar(255) DEFAULT NULL,
`qty` double DEFAULT NULL,
`unitprice` double DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB
Và đây là đoạn code mà làm cho các hoạt động CRUD trên một tập hợp dữ liệu sử dụng chìa khóa id tài liệu (invoce_id
).
public boolean save(long invoice_id, List<Invoice> list) throws SQLException {
try(Connection connection = getConnection()) {
try {
connection.setAutoCommit(false);
String query =
"create temporary table if not exists `invoice_tmp` (" +
"`id` int(10) unsigned NOT NULL," +
"`description` varchar(255) DEFAULT NULL," +
"`qty` double DEFAULT NULL," +
"`unitprice` double DEFAULT NULL)";
connection.createStatement().executeUpdate(query);
query = "insert into `invoice_tmp` values (?, ?, ?, ?)";
PreparedStatement statement = connection.prepareStatement(query);
for(Invoice invoice: list) {
statement.setLong(1, invoice.getId());
statement.setString(2, invoice.getDescription());
statement.setDouble(3, invoice.getQty());
statement.setDouble(4, invoice.getUnitPrice());
statement.addBatch();
}
statement.executeBatch();
statement.close();
query =
"delete invoice from invoice " +
"left join invoice_tmp on (invoice.id = invoice_tmp.id) " +
"where invoice_id = ? and invoice_tmp.id is null";
statement = connection.prepareStatement(query);
statement.setLong(1, invoice_id);
statement.executeUpdate();
statement.close();
query =
"update `invoice` " +
"join `invoice_tmp` using (`id`) " +
"set " +
"`invoice`.description = `invoice_tmp`.description, " +
"`invoice`.qty = `invoice_tmp`.qty, " +
"`invoice`.unitprice = `invoice_tmp`.unitprice";
connection.createStatement().executeUpdate(query);
query =
"insert into `invoice` (`invoice_id`, `description`, `qty`, `unitprice`) " +
"select ? as `invoice_id`, `description`, `qty`, `unitprice` from `invoice_tmp` where `id` = 0";
statement = connection.prepareStatement(query);
statement.setLong(1, invoice_id);
statement.executeUpdate();
statement.close();
connection.createStatement().executeUpdate("drop table if exists `invoice_tmp`");
connection.commit();
return true;
}
catch (Exception e) {
connection.rollback();
throw e;
}
}
}
this là dự án thử nghiệm thể hiện cách mã hoạt động.
Câu hỏi của bạn là gì? –
Chào mừng bạn đến với SO. Thông tin được cung cấp không đủ để giúp bạn. Thử in ra 'index' và' (String) tablesample.getValueAt (hàng, X) '. Bạn có thể ngạc nhiên. – c0der
Tôi đã cố gắng để đưa chỉ mục: String sql = "UPDATE hóa đơn SET mô tả =?, Qty =?, Unitprice =?" + ", total =? WHERE id =" + chỉ mục; nhưng chỉ có thể cập nhật là hàng đầu tiên và những người khác sẽ giống như hàng đầu tiên –