spring data jpa的更新是通过save方法来实现的,通常我们会定义一个自增主键的ID,默认就是根据该ID作全量更新。
但如果我想在更新时不用ID,而是其他字段,那么只能另选他法了:
在仓库定义更新方法:
import com.wlf.order.prize.model.OrderItem; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; public interface OrderDao extends JpaRepository<OrderItem, Long> { OrderItem findByOrderId(String orderId); @Modifying @Query("update OrderItem o set o.address = ?1, o.timestamp = ?4 where o.orderId = ?2 and o.timestamp = ?3") void updateAddressByOrderId(String address, String orderId, Long oldTimestamp, Long newTimestamp); }
有几点需要注意:
1、注解,这里多了@Modifying用来告诉JPA我们是update,但是SQL我们放在@Query里;
2、SQL,这里不是你数据库中的表,而是你定义的表实体类,字段也是表实体类对应的属性;
3、参数,通过?数字的形式来告诉JPA,我们的SQL对应方法的哪个参数;
4、最后我们需要给更新加上事务,使用spring的@Transactional标注到调用该更新方法上即可:
/** * 修改订单地址 * * @param orderAddress * @param timestamp */ @Transactional public void modifyOrderAddress(OrderAddress orderAddress, Long timestamp) { if (orderAddress == null || orderAddress.getOrderId() == null || orderAddress.getOrderId().trim().equals("") || orderAddress.getAddress() == null || orderAddress.getAddress().trim().equals("")) { log.error("orderAddress is null. orderAddress : {}", orderAddress); throw new OrderException(1004, "更新订单地址时订单数据错误."); } // 先查询,已存在数据则更新 OrderItem tmp = orderDao.findByOrderId(orderAddress.getOrderId()); Long tmpTime = null; if (tmp == null) { log.error("orderAddress has not insert."); throw new OrderException(1005, "更新地址时订单尚未存在."); } // 更新数据 tmpTime = tmp.getTimestamp(); try { orderDao.updateAddressByOrderId(orderAddress.getAddress(), orderAddress.getOrderId(), tmpTime, timestamp); } catch (Exception e) { log.error("db error : {}", e.getMessage()); throw new OrderException(1020, "数据库操作失败."); } }