티스토리 뷰
반응형
목적
JPA를 통해 개발할시 대용량 Insert 방법 구현
- JPA Batch
- JDBC Batch
예제소스
https://github.com/devHjlee/devHjBlog/tree/main/springJpaBulk
Enity ID 전략에따라 구현하는 방법
- ID 직접할당 : JPA, JDBC Batch
- IDENTITY : JDBC Batch
- Hibernate 에서는 IDENTITY 전략에 대해서는 Batch Insert를 비활성화시켜놨는데 새로 할당할 Key에 대해 미리 알수 없기 때문이다.
- SEQUENCE : 데이터베이스 시퀀스를 사용해 식별자를 조회해오고 조회된 식별자를 엔티티에 할당하는방법(Mysql 불가능) JPA, JDBC Batch
- TABLE : 키생성용 테이블을 통해 시퀀스전략을 흉내내는 전략 JPA, JDBC Batch
개발환경
- IDE : IntelliJ
- Jdk : OpenJdk 1.8
- DB : Mysql 8.0
- gradle
- spring boot : 2.7.8
- spring-boot-starter-data-jpa
- mysql-connector-j
프로젝트 구조

예제 소스
IdentityBatchTable
- IDENTITY 전략
@Entity
@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class IdentityBatchTable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column
private String name;
}
NoIdentityBatchTable
- 기본ID 전략
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class NoIdentityBatchTable {
@Id
long id;
@Column
String name;
@Builder
public NoIdentityBatchTable(long id, String name){
this.id = id;
this.name = name;
}
}
IdentityBatchRepository
- IDENTITY 전략을 사용한 IdentityBatchTable 을 bulkInsert 하기위해 JDBCTemplate 에서 제공해주는 BatchUpdate 구현 클래스
@Repository
@RequiredArgsConstructor
public class IdentityBatchRepository {
private final JdbcTemplate jdbcTemplate;
@Transactional
public void saveAll(List<IdentityBatchTable> identityBatchTables) {
String sql = "INSERT INTO identity_batch_table (name) " +
"VALUES (?)";
jdbcTemplate.batchUpdate(sql,
identityBatchTables,
2000,
(PreparedStatement ps, IdentityBatchTable identityBatchTable) -> {
ps.setString(1, identityBatchTable.getName());
});
}
}
Test Code
public class InsertTest {
@Autowired
NoIdentityBatchTableRepository noIdentityBatchTableRepository;
@Autowired
IdentityBatchTableRepository identityBatchTableRepository;
@Autowired
IdentityBatchRepository identityBatchRepository;
@Test
public void noIdentityJPABatch(){
List<NoIdentityBatchTable> noIdentityBatchTables = new ArrayList<NoIdentityBatchTable>();
for(int i = 1; i < 20000; i++){
noIdentityBatchTables.add(NoIdentityBatchTable.builder().id(i).name("C"+i).build());
}
noIdentityBatchTableRepository.saveAll(noIdentityBatchTables);
}
@Test
public void identityJPABatch(){
List<IdentityBatchTable> identityBatchTables = new ArrayList<>();
for(int i = 1; i < 20000; i++){
IdentityBatchTable identityBatchTable = IdentityBatchTable.builder().name("A"+i).build();
identityBatchTables.add(identityBatchTable);
}
identityBatchTableRepository.saveAll(identityBatchTables);
}
@Test
public void identityJDBCBatch(){
List<IdentityBatchTable> identityBatchTables = new ArrayList<>();
for(int i = 1; i < 20000; i++){
IdentityBatchTable identityBatchTable = IdentityBatchTable.builder().name("A"+i).build();
identityBatchTables.add(identityBatchTable);
}
identityBatchRepository.saveAll(identityBatchTables);
}
}
Mysql 관련 bulk Insert를 위한 application.properties 추가설정
spring.jpa.properties.hibernate.jdbc.batch_size=2000 : bulkInsert시 해당 사이즈로 끊어서 Insert
spring.datasource.url=jdbc:mysql://localhost:3306/jpa?useSSL=false&allowPublicKeyRetrieval=true&rewriteBatchedStatements=true&profileSQL=true&logger=Slf4JLogger&maxQuerySizeToLog=999999
- rewriteBatchedStatements=true : mysql 에서 bulk Insert를위한 필수 설정
- profileSQL= ture : Driver에 전송하는 쿼리를 출력
- logger=Slf4JLogger : Driver에서 쿼리 출력시 사용할 로거를 설정
- maxQuerySizeToLog=999999 : 출력할 쿼리 길이
테스트 3개 케이스 모두 Batch Size 2000으로 진행
- noIdentityJPABatch() 17초...

- identityJPABatch() 16초...

- identityJDBCBatch() 0.5초...

2만건에 대해서 이정도 시간차이가 발생하는걸보니 JPA를 사용한다고해서 JPA만 쓰면 안된다는걸...
반응형
'Spring' 카테고리의 다른 글
Spring Event 활용 (0) | 2023.03.21 |
---|---|
JPA+QueryDsl 게시판 CRUD 구현(2) (0) | 2023.03.09 |
JPA+QueryDsl 게시판 CRUD 구현(1) (0) | 2023.02.15 |
Srping Boot Quartz DB Cluster,Log 구현 (0) | 2023.01.18 |
Spring Boot zip END header not found (0) | 2022.11.02 |
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- custom Item writer
- Spring Actuator
- sse vs websocket
- CompositeItemWriter
- 업비트 웹소켓
- WebSocketClient
- tomcat gzip
- cacheevict
- actuator prometheus grafana
- interceptor 예제
- 프라이빗 저장소
- Enum ==
- spring redis cache
- SpringBatch 5.1.1
- nginx gzip
- okhttp3 websocket
- nvWebSocket
- spring boot jpa crud
- Enum equals
- redis cache
- spring boot redis cache
- 업비트 웹소켓 자바
- JdbcBatchItem
- Spring boot Actuator
- spring boot gzip
- spring boot jpa
- spring security
- AWS 클라우드 환경
- Enum Equals ==
- codecommit repository
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
글 보관함