【问题标题】:What is the best practices of insertOrUpdate operation using Spring jdbcTemplate?使用 Spring jdbcTemplate 进行 insertOrUpdate 操作的最佳实践是什么?
【发布时间】:2014-04-08 15:36:06
【问题描述】:

假设我们有一个 REST 服务,接受来自经理的销售订单列表。 (我们知道 managerId 并且他发送的所有订单都相同)

class SalesOrder {
   String id;
   String managerId;
   //some other data
}

而且这项服务必须:

if SalesOrder not exists - save object
if object exists - update it

使用 Spring jdbcTemplate 保存或更新此列表的最有效方法是什么(就使用 db 而言)?

我考虑的第一种方法是:

public void saveOrUpdate(Iterable<SalesOrder> orders, String managerId) {
    Set<String> presentInDbOrderIds = findOrderIds(managerId);

    List<SalesOrder> ordersToInsert = new ArrayList<>();
    List<SalesOrder> ordersToUpdate = new ArrayList<>();

    for (SalesOrder ord : orders) {
        if(presentInDbRecOrderHeaderIds.contains(ord.getId())) {
            ordersToUpdate.add(ord);
        } else {
            ordersToInsert.add(ord);
        }
    }

    batchInsertOrders(recOrdersToInsert);
    batchUpdateOrders(recOrdersToUpdate);
}

第二个:

public void saveOrUpdate(Iterable<SalesOrder> orders) {
    for (SalesOrder ord : orders) {
        if(!update(ord)) { // returns true if object was updated
            save(ord);
        }
    }
}

更新:

实际上(在我的情况下)每个订单都有一个 orderLines 集合,它们必须经过相同的过程,所以我正在寻找最轻松的方式(到 DB)来完成这个操作。

【问题讨论】:

  • 在批量更新中,框架将遍历值并使用内部准备好的语句设置器

标签: java spring jdbctemplate


【解决方案1】:

让您自行检查是否需要检查或更新并不是一个好主意。如果在你准备好 findOrderIds() .. 等之后另一个线程修改了 DB 中的数据怎么办。我不知道你是否实现了同步。

此外,如果您为整个过程添加同步,您将添加额外的块。 DB 处理更好的同步和索引数据。

我将使用这样的批处理准备语句:

class SalesOrder {
    String id;
    String managerId;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getManagerId() {
        return managerId;
    }

    public void setManagerId(String managerId) {
        this.managerId = managerId;
    }

}

public void saveOrUpdate(List<SalesOrder> orders, String managerId) {
    String example_query = "insert into table(id, managerID,col2) values (?,?,?) on duplicate key update managerID= ? , col2 =?";
    final int batchSize = 500;

    for (int j = 0; j < orders.size(); j += batchSize) {
        final List<SalesOrder> pickedOrders = orders.subList(j,
                j + batchSize > orders.size() ? orders.size() : j + batchSize);
        getJdbcTemplate().batchUpdate(example_query, new BatchPreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                SalesOrder order = pickedOrders.get(i);
                ps.setString(1, order.getId());
                ps.setString(2, order.getManagerId());
                // so on
            }
            @Override
            public int getBatchSize() {
                return pickedOrders.size();
            }
        });

    }

} 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多