엔티티를 수정하려면 영속성 컨텍스트의 변경 감지 기능이나 병합을 사용하고, 삭제를 하려면 EntityManager.remove() 메소드를 사용한다.
하지만 이 방법으로 수백개 이상의 엔티티를 하나씩 처리하기에는 시간이 너무 오래걸린다.
이럴 때 여러 건을 한 번에 수정하거나 삭제하는 벌크 연산을 사용하면 된다.
//UPDATE 벌크 연산String qlString ="UPDATE Product p " +"SET p.price = p.price * 1.1 " +"WHERE p.stockAmount < :stockAmount";int resultCount = em.createQuery(qlString) .setParameter("stockAmount", 10) .executeUpdate();
벌크 연산은 executeUpdate() 메소드를 사용한다. (벌크 연산으로 영향을 받은 엔티티 건수 반환)
삭제도 같은 메소드를 사용한다.
//DELETE 벌크 연산String qlString ="DELETE FROM Product p "+"WHERE p.price < :price";int resultCount = em.createQuery(qlString) .setParameter("price", 100) .executeUpdate();
벌크 연산을 사용할 때는 벌크 연산이 영속성 컨텍스트를 무시하고 데이터베이스에 직접 쿼리한다는 점에 주의해야 한다.
벌크 연산시 발생할 수 있는 문제
//DB에 가격이 1000원인 상품A가 있다.//상품A(productA) 조회 (1000원) ...1Product productA = em.createQuery("SELECT p FROM Product p WHERE p.name = :name", Product.class) .setParameter("name", "productA") .getSingleResult();//출력 결과: 1000System.out.println("productA 수정 전 = " + productA.getPrice());//벌크 연산 수행으로 모든 상품 가격 10% 상승 ...2em.createQuery("UPDATE Product p SET p.price = p.price * 1.1").executeUpdate();//출력 결과: 1000 ...3System.out.println("productA 수정 후 = " + productA.getPrice());