패키지 구성 기본 뼈대
- domain
-> BaseEntity.java / time같은 각 entity에서 상속받는 칼럼 가지는 추상엔티티 클래스
-> entity에 사용되는 enum 값들
-- <entity 명칭>
공통사항
1. 보통 테이블마다 생성일시, 변경일시 와 같은 column 값을 가지는데, 테이블마다 공통적으로 가지는 칼럼을 추상 클래스로 분리하여 JpaAuditing 기능을 사용하여 하위 Entity 클래스에 중복 없이 적용 가능하다.
https://charactermail.tistory.com/513
https://charactermail.tistory.com/478
@JsonInclude(Include.NON_NULL)
@Getter
@Setter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseEntity implements Serializable {
@CreatedDate
@Column(updatable = false, columnDefinition = "datetime default CURRENT_TIMESTAMP NOT NULL COMMENT '생성일자'")
private LocalDateTime createdAt;
@LastModifiedDate
@Column(columnDefinition = "datetime default CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL COMMENT '수정일자'")
private LocalDateTime updatedAt;
@Column(columnDefinition = "bit default false NOT NULL COMMENT '이용가능여부'")
private Boolean isDeleted;
}
domain class 예시
@Entity
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@DynamicInsert
@DynamicUpdate
@Where(clause = "is_deleted=false")
public class Application extends BaseEntity{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(nullable = false, updatable = false)
private Long applicationId;
@Column(columnDefinition = "varchar(12) DEFAULT NULL COMMENT '신청자'")
private String name;
@Column(columnDefinition = "varchar(13) DEFAULT NULL COMMENT '전화번호'")
private String cellPhone;
@Column(columnDefinition = "varchar(50) DEFAULT NULL COMMENT '신청자 이메일'")
private String email;
@Column(columnDefinition = "decimal(5,4) DEFAULT NULL COMMENT '금리'")
private BigDecimal interestRate;
@Column(columnDefinition = "decimal(5,4) DEFAULT NULL COMMENT '취급수수료'")
private BigDecimal fee;
@Column(columnDefinition = "datetime DEFAULT NULL COMMENT '만기'")
private LocalDateTime maturity;
@Column(columnDefinition = "decimal(15,2) DEFAULT NULL COMMENT '대출 신청 금액'")
private BigDecimal hopeAmount;
@Column(columnDefinition = "datetime DEFAULT NULL COMMENT '신청일자'")
private LocalDateTime appliedAt;
}
@Entity
@Table(name = "\"alarm\"", indexes = {
@Index(name = "user_id_idx", columnList = "user_id")
})
@Getter
@Setter
//@SQLDelete(sql = "UPDATE \"alarm\" SET deleted_at = NOW() where id=?")
//@Where(clause = "delete_at is NULL")
@TypeDef(name = "json", typeClass = JsonType.class)
public class AlarmEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
// 알람을 받은 사람
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private UserEntity user;
@Enumerated(EnumType.STRING)
private AlarmType alarmType;
// json 형태로 저장되어 있는 문자열 데이터를 Map으로 매핑합니다.
// 추후 args 값 가져올 때 AlarmArgs 클래스로 변환하는 로직 만들어야 문제 없을 것
@Type(type = "json")
@Column(columnDefinition = "json")
private Map<String, Object> args;
@Column(name = "registered_at")
private Timestamp registeredAt;
@Column(name = "updated_at")
private Timestamp updatedAt;
@Column(name = "deleted_at")
private Timestamp deletedAt;
//@PrePersist
void registeredAt(){
this.registeredAt = Timestamp.from(Instant.now());
}
//@PrePersist
void updatedAt(){
this.updatedAt = Timestamp.from(Instant.now());
}
public static AlarmEntity of(UserEntity userEntity, AlarmType alarmType, AlarmArgs args){
AlarmEntity entity = new AlarmEntity();
entity.setUser(userEntity);
entity.setAlarmType(alarmType);
Map<String, Object> argsMap = Map.of(
"fromUserId", args.getFromUserId(),
"targetId", args.getTargetId()
);
entity.setArgs(argsMap);
return entity;
}
public AlarmArgs getArgs() {
AlarmArgs args = new AlarmArgs();
args.setTargetId((Integer) this.args.get("targetId"));
args.setFromUserId((Integer) this.args.get("fromUserId"));
return args;
}
}
@Slf4j
@AllArgsConstructor
@Getter
public class Alarm {
private Integer id;
private AlarmType alarmType;
private AlarmArgs args;
private Timestamp registeredAt;
private Timestamp updatedAt;
private Timestamp deletedAt;
public static Alarm fromEntity(AlarmEntity entity){
log.info("==== Call fromEntity");
return new Alarm(
entity.getId(),
entity.getAlarmType(),
entity.getArgs(),
entity.getRegisteredAt(),
entity.getUpdatedAt(),
entity.getDeletedAt()
);
}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class AlarmArgs {
// 알람을 발생시킨 사람
private Integer fromUserId;
private Integer targetId;
}
@RequiredArgsConstructor
@Getter
public enum AlarmType {
NEW_COMMENT_ON_POST("new_comment!"),
NEW_LIKE_ON_POST("new like!"),
;
private final String alarmText;
}
'스프링 관련 > 스프링' 카테고리의 다른 글
controller (0) | 2023.01.15 |
---|---|
repository (0) | 2023.01.15 |
service (0) | 2023.01.14 |
config (0) | 2023.01.14 |
스프링 프로젝트 패키지 구조 정리 및 항목별 index url 정리 (0) | 2023.01.13 |
댓글