camp-us 캠핑장 커뮤니티 프로젝트-3(JPA 셋업)

김상운(개발둥이)·2022년 2월 5일
0

camp-us

목록 보기
3/6
post-thumbnail

개요

3주차는 1, 2 주차에 작성한 기능명세서, API 문서, DB 명세서를 바탕으로 실제 프로젝트를 개발을 진행하는 주차이다. 따라서 개발이 본격적으로 시작된다.

엔티티 클래스 개발

먼저 DB 명세를 기반으로 엔티티 클래스 개발을 시작하였다.

application.yml

spring:
  datasource:
    url: jdbc:mysql://DB이름.RDS주소:3306/campus?serverTimezone=Asia/Seoul&characterEncoding=UTF-8
    username: username
    password: password
    driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:
    hibernate:
      ddl-auto: update
    properties:
      hibernate:
        format_sql: true
        default_batch_fetch_size: 100

logging.level:
  org.hibernate.SQL: debug

DB 는 aws MySql RDS를 사용하였다.

Member

package couch.camping.domain.member.entity;

import lombok.*;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import java.util.Collection;

@Entity
@Getter @Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Member implements UserDetails {
    //uid
    @Id
    private String username;
    @Column
    private String email;
    @Column
    private String nickname;



    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public String getPassword() {
        return null;
    }

    @Override
    public String getUsername() {
        return username;
    }

    @Override
    public boolean isAccountNonExpired() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean isAccountNonLocked() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean isEnabled() {
        // TODO Auto-generated method stub
        return false;
    }
}

Notification

package couch.camping.domain.notification.entity;


import couch.camping.domain.base.BaseTimeEntity;
import couch.camping.domain.member.entity.Member;
import couch.camping.domain.review.entity.Review;
import lombok.*;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.*;

@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Getter @Setter
@Builder
@EntityListeners(AuditingEntityListener.class)
public class Notification extends BaseTimeEntity {

    @Id @GeneratedValue
    @Column(name = "notification_id")
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "member_id")
    private Member member;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "review_id")
    private Review review;

    private boolean isChecked;

}

Review

package couch.camping.domain.notification.entity;


import couch.camping.domain.base.BaseTimeEntity;
import couch.camping.domain.member.entity.Member;
import couch.camping.domain.review.entity.Review;
import lombok.*;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.*;

@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Getter @Setter
@Builder
@EntityListeners(AuditingEntityListener.class)
public class Notification extends BaseTimeEntity {

    @Id @GeneratedValue
    @Column(name = "notification_id")
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "member_id")
    private Member member;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "review_id")
    private Review review;

    private boolean isChecked;

}

ReviewLike

package couch.camping.domain.reviewlike.entity;

import couch.camping.domain.base.BaseTimeEntity;
import couch.camping.domain.member.entity.Member;
import couch.camping.domain.review.entity.Review;
import lombok.*;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.*;

@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Getter @Setter
@Builder
@EntityListeners(AuditingEntityListener.class)
public class ReviewLike extends BaseTimeEntity {

    @Id @GeneratedValue
    @Column(name = "review_like_id")
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "review_id")
    private Review review;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "member_id")
    private Member member;
}

Camp

package couch.camping.domain.camp.entity;

import lombok.*;

import javax.persistence.*;

@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Getter
@Setter
@Builder
public class Camp {

    @Id @GeneratedValue
    @Column(name = "camp_id")
    private Long id;

    @Column(name = "like_cnt")
    private Integer like;

    private Integer rate;

    private String facltNm;
    private String lineIntro;

    @Lob
    private String intro;

    @Lob
    private String featureNm;
    private String induty;
    private String lctCl;
    private String doNm;
    private String sigunguNm;
    private String addr1;
    private Float mapX;
    private Float mapY;
    private String tel;

    @Lob
    private String direction;
    private String homepage;

    @Lob
    private String resveUrl;
    private String resveCl;
    private Integer autoSiteCo;
    private Integer glampSiteCo;
    private Integer caravSiteCo;
    private Integer sitedStnc;
    private Integer indvdlCaravSiteCo;
    private String glampInnerFclty;
    private String caravInnerFclty;
    private String operPdCl;
    private String operDeCl;
    private String trlerAcmpnyAt;
    private String caravAcmpnyAt;
    private Integer toiletCo;
    private Integer swrmCo;
    private Integer wtrplCo;
    private String brazierCl;
    private String sbrsCl;
    private String sbrsEtc;
    private String posblFcltyCl;
    private String posblFcltyEtc;
    private Integer fireSensorCo;
    private Integer extshrCo;
    private String themaEnvrnCl;
    private String eqpmnLendCl;
    private String animalCmgCl;
    private String tourEraCl;
    private String firstImageUrl;

}

CampLike

package couch.camping.domain.camplike.entity;

import couch.camping.domain.base.BaseTimeEntity;
import couch.camping.domain.camp.entity.Camp;
import couch.camping.domain.member.entity.Member;
import lombok.*;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.*;

@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Getter
@Setter
@Builder
@EntityListeners(AuditingEntityListener.class)
public class CampLike extends BaseTimeEntity {

    @Id @GeneratedValue
    @Column(name = "camp_like_id")
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "camp_id")
    private Camp camp;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "member_id")
    private Member member;
}

BaseTimeEntity

package couch.camping.domain.base;

import lombok.Getter;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.Column;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import java.time.LocalDateTime;

@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class BaseTimeEntity {

    @Column(updatable = false)
    @CreatedDate
    private LocalDateTime createdDate;

    @LastModifiedDate
    private LocalDateTime lastModified;
}

BaseEntity

package couch.camping.domain.base;

import lombok.Getter;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.Column;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;

@MappedSuperclass
@Getter
@EntityListeners(AuditingEntityListener.class)
public class BaseEntity extends BaseTimeEntity {

    @CreatedBy
    @Column(updatable = false)
    private String createdBy;

    @LastModifiedBy
    private String lastModifiedBy;
}

BaseTimeEntity 의 경우 data jpa 기능을 사용하여 생성, 수정 시간을 위한 엔티티 클래스이며, BaseEntity의 경우 data jpa와 spring security 기능을 사용하여 작성자와 수정자를 자동으로 매핑시킨다.

JPA 의 상속은 부모 클래스가 @Entity 어노테이션을 가지고 있거나 또는 @MappedSuperclass 어노테이션을 가지고 있어야 상속이 가능하다. @Entity 클래스를 상속할 경우 super-sub 타입으로 관계가 맺어지고 위의 BaseEntity와 BaseTimeEntity의 경우 해당 클래스의 필드 값만 데이터베이스에 매핑하여 사용한다.

엔티티 클래스의 @NoArgsConstructor(access = AccessLevel.PROTECTED) 기본 생성자를 protected 로 설정한 이유는, hibernate의 경우 proxy를 사용하여 호출하기 때문에 private이 아닌 protectd로 설정하였다.

배포

카우치 코딩 스터디의 경우 배포를 heroku를 사용한다. heroku는 front-end, back-end, database 등 모든 서비스가 하나의 서버에서 모놀리틱하게 이루어진다. 하지만 프론트의 oAuth와 백엔드의 oAuth 기능을 테스트하는 과정을 테스트하기 위해 aws의 ec2와 rds를 사용하여 배포를하였다. 추후 aws 환경에서 git actions 를 통해 ci/cd 를 추가할 예정이다.

깃허브: https://github.com/Couch-Coders/6th-camp_us-be

profile
공부한 것을 잊지 않기 위해, 고민했던 흔적을 남겨 성장하기 위해 글을 씁니다.

0개의 댓글