JAVA-JIKIMI / JPA

jpa 완벽 뽀개기
0 stars 0 forks source link

[핵심 pick] 7주차 박효원 #51

Open lsucret opened 2 years ago

lsucret commented 2 years ago

상품 수정과 관련하여, 만약 상품정보를 한번에 수천건씩 수정해야 한다면?

→ batch update를 사용한다.
단일 네트워크 호출로 SQL문을 db에 보낼 수 있어 수행시간을 줄여준다.



학교와 학생을 생성

@Entity
public class School {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private long id;

    private String name;

    @OneToMany(mappedBy = "school")
    private List<Student> students;

    // Getters and setters...
}

@Entity
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private long id;

    private String name;

    @ManyToOne
    private School school;

    // Getters and setters...
}


학교를 10개 생성

@Transactional
@Test
public void whenNotConfigured_ThenSendsInsertsSeparately() {
    for (int i = 0; i < 10; i++) {
        School school = createSchool(i);
        entityManager.persist(school);
    }
    entityManager.flush();
}


(spring boot 기반인 경우) properties에 관련 설정을 추가

// batch update 설정
spring.jpa.properties.hibernate.order_updates=true
spring.jpa.properties.hibernate.batch_versioned_data=true

// batch size 정의
spring.jpa.properties.hibernate.jdbc.batch_size=5


batch update를 실행

@Transactional
@Test
public void whenUpdatingEntities_thenCreatesBatch() {
    TypedQuery<School> schoolQuery = 
      entityManager.createQuery("SELECT s from School s", School.class);
    List<School> allSchools = schoolQuery.getResultList();
    for (School school : allSchools) {
        school.setName("Updated_" + school.getName());
    }
}
// school은 총 10개이나 쿼리는 두 번만 실행된다.
"batch":true, "querySize":1, "batchSize":5, "query":["update school set name=? where id=?"], 
  "params":[["Updated_School1","1"],["Updated_School2","2"],["Updated_School3","3"],
  ["Updated_School4","4"],["Updated_School5","5"]]
"batch":true, "querySize":1, "batchSize":5, "query":["update school set name=? where id=?"], 
  "params":[["Updated_School6","6"],["Updated_School7","7"],["Updated_School8","8"],
  ["Updated_School9","9"],["Updated_School10","10"]]

주의

만약 PK 생성 전략이 GenerationType.IDENTITY 라면 hibernate가 batch insert/update를 비활성화 시키므로, PK 생성 전략이 IDENTITY가 아닌 걸로 (여기에선 GenerationType.SEQUENCE)를 사용하자.