배경
보통 jpa를 할 때 comment를 달기 위해서는 @Column(columnDefinition = ...) 이렇게 해야한다.
@Entity
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(columnDefinition = "varchar(10) not null comment '이름'")
private String name;
private String description;
}
코드에 주석처리로 처리 할 수 있겠지만 DB에 설명이 있기 위해서는 코멘트를 적어야한다. (혼자 개발하는게 아니니까?)
아 근데 매번 저렇게 추가하는거 귀찮은데? 어노테이션으로 comment를 달아줄 수는 없을까?
Comment Custom Annotation을 만들기
Comment annotation 만들기
mysql 기준으로 기존 컬럼에 코멘트 추가해주기 위해서는
ALTER TABLE <<테이블 이름>> MODIFY <<컬럼 이름>> <<type>> COMMENT '...'
를 해줘야한다. 그래서 @Comment(value = '...', type = 'VARCHAR(255)') 와 같이 두가지를 넣어준다.
@Target({FIELD})
@Retention(RUNTIME)
public @interface Comment {
// db comment annotation
String value() default "";
String type() default "varchar";
}
CommandLineRunner 만들기
@Configuration
public class CommentCommandLineRunner implements CommandLineRunner {
@PersistenceContext
private EntityManager entityManager;
@Resource
private JdbcTemplate jdbcTemplate;
@Resource private HibernateProperties hibernateProperties;
@Override
public void run(String... args) {
String ddlAuto = this.hibernateProperties.getDdlAuto();
if (Objects.nonNull(ddlAuto) && "update".equalsIgnoreCase(ddlAuto)) {
this.scanCommentAnnotationOnEntityAndCreate();
}
}
private void scanCommentAnnotationOnEntityAndCreate() {
EntityManagerFactory entityManagerFactory = this.entityManager.getEntityManagerFactory();
SessionFactoryImpl sessionFactory = entityManagerFactory.unwrap(SessionFactoryImpl.class);
Map<String, EntityPersister> persisterMap = sessionFactory.getMetamodel().entityPersisters();
if (Objects.nonNull(persisterMap) && persisterMap.keySet().size() > 0) {
for (Map.Entry<String, EntityPersister> entry: persisterMap.entrySet()) {
Class<?> targetClazz = entry.getValue().getMappedClass();
SingleTableEntityPersister persister = (SingleTableEntityPersister)entry.getValue();
String tableName = persister.getTableName();
Comment targetClazzAnno = targetClazz.getAnnotation(Comment.class);
if (Objects.nonNull(targetClazzAnno)) {
String sql = String.format("ALTER TABLE %s COMMENT = '%s'", tableName, targetClazzAnno.value());
this.jdbcTemplate.execute(sql);
}
for (AttributeDefinition attributeDefinition : persister.getAttributes()) {
//Property name
String propertyName = attributeDefinition.getName();
if (propertyName.equalsIgnoreCase("_identifierMapper")) {
continue;
}
Field field;
try {
field = targetClazz.getDeclaredField(propertyName);
if (Objects.nonNull(field)) {
Comment anno = field.getAnnotation(Comment.class);
if (Objects.nonNull(anno)) {
String[] columns = persister.getPropertyColumnNames(propertyName);
String sql = String.format("alter table %s MODIFY %s %s comment '%s'", tableName, columns[0], anno.type(), anno.value());
this.jdbcTemplate.execute(sql);
}
}
} catch (NoSuchFieldException ex) {
//ex.printStackTrace();
}
}
}
}
}
}
@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
public class Banner extends BaseTimeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Comment(value = "이름입니다.~", type = "VARCHAR(255)")
private String name;
@Comment(value = "설명입니다.~", type = "VARCHAR(255)")
private String description;
위 사진처럼 잘 적용되는것을 알 수 있다.
그리고 더 좋은 방법이 있을 수도 있을 것 같다.
근데 @Column(columnDefinition = ...) 이거랑 뭐가 다르냐고 하는 의견도 있네요..
참고 블로그
https://busyman.tistory.com/406
오라클 Comment 자동 생성을 위한 Custom Annotation 만들기
SpringBoot 환경에서 오라클을 사용하는데, table은 자동으로 만들어 줘서 좋은데 Comment는 자동으로 안 넣어줘 이래 저래 찾다 보니 딱히 방법이 없었다. Mysql 같은 경우, table을 만들면서 comment를 추
busyman.tistory.com
'spring boot > 기술 적용' 카테고리의 다른 글
Spring boot에 전략패턴 적용 (0) | 2022.10.10 |
---|---|
webClient 와 feignClient (0) | 2022.10.10 |
stub, mock, spy 비교 (0) | 2022.07.02 |
converter를 만들지 않고 jpa mysql에서 json 사용하기 (0) | 2022.06.28 |
fetchJoin과 pagination을 같이 사용할 때 (0) | 2022.06.24 |