~~ jdbcUrl: jdbc:mysql://localhost:3306/one?serverTimezone=Asia/Seoul&rewriteBatchedStatements=true
spring:
jpa:
properties:
hibernate.jdbc.batch_size: 100
hibernate.order_inserts: true
hibernate.order_updates: true
위와 같이 설정한 후에 saveAll을 사용하면 된다.
이 경우는 bulk insert가 비활성화 되기 때문에 JdbcTemplate으로 수행해야 한다.
이유는 JPA는 insert할 row의 pk를 한번 또는 여러번에 걸쳐 채번하여 쿼리를 완성시킨후에 insert를 수행하는데
autoincrement 전략은 채번을 하기 위해서는 각각의 row의 insert를 수행해줘야 하기 때문이다.
~~
@Transactional(readOnly = false)
public void bulkMerge(List<SurveyReportSheet> surveyReportSheets) {
String sql = "INSERT INTO tb_pinesurvey_survey_report_sheet (report_key, question_id, answer_id, answer_essay) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE answer_essay = ?";
getJdbcTemplate().batchUpdate(sql, new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
SurveyReportSheet surveyReportSheet = surveyReportSheets.get(i);
ps.setLong(1, surveyReportSheet.getId().getReportKey());
ps.setInt(2, surveyReportSheet.getId().getQuestionId());
ps.setInt(3, surveyReportSheet.getId().getAnswerId());
ps.setString(4, surveyReportSheet.getAnswerEssay());
ps.setString(5, surveyReportSheet.getAnswerEssay());
}
@Override
public int getBatchSize() {
return surveyReportSheets.size();
}
});
entityManager.clear();
}
~~
GenerationType.TABLE 방식을 사용하면 된다.
채번 할때 select를 하여 성능 손실이 발생한다는 단점이 있지만.
이렇게 사용하는 것이 어떤 DB에서도 작동하여서 호환성이 좋다.
@Entity
@EntityListeners(AuditingEntityListener.class)
/*
* name = (Required) A unique generator name that can be referenced by one or more classes to be the generator for id values.
* table = (Optional) Name of table that stores the generated id values.
Defaults to a name chosen by persistence provider
* pkColumnValue = (Optional) The primary key value in the generator table that distinguishes this set of generated values from others that may be stored in the table.
Defaults to a provider-chosen value to store in the primary key column of the generator table
* allocationSize = (Optional) The amount to increment by when allocating id numbers from the generator.
*/
@TableGenerator(
name = "seq_survey",
table = "tb__seq",
pkColumnValue = "seq_survey",
allocationSize = 50)
@Table(name = "tb_survey")
public class Survey implements Serializable, Comparable<Survey> {
/* ############################################# Mybatis Generator 생성 at 20230323_112501 ############################################# */
@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "seq_survey")
@NotNull
@Column(name = "survey_key", nullable = false)
private Long id;
@NotNull
@Column(name = "survey_title", nullable = false, length = 100)
private String surveyTitle;
@NotNull
@Column(name = "survey_desc", nullable = false, length = 500)
private String surveyDesc;
@NotNull
@Column(name = "survey_type", nullable = false, length = 20)
private String surveyType;
@NotNull
@Column(name = "survey_status", nullable = false, length = 20)
private String surveyStatus;
@NotNull
@Column(name = "start_at", nullable = false)
private Instant startDt;
@NotNull
@Column(name = "end_at", nullable = false)
private Instant endDt;
@NotNull
@Column(name = "visible_yn", nullable = false, length = 1)
private String visibleYn;
@NotNull
@CreatedDate
@Column(name = "created_at", nullable = false)
private Instant regDt;
@NotNull
@LastModifiedDate
@Column(name = "updated_at", nullable = false)
private Instant modDt;
}