1. 게시글을 저장할 Post 엔티티를 만들어준다.
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Entity
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class Post {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "POST_TITLE")
private String title;
@Column(name = "POST_CONTENT")
private String content;
@Column(name = "POST_AUTHOR")
private String author;
@Column(name = "POST_CREATE_AT")
private LocalDateTime create_at = LocalDateTime.now();
@Column(name = "POST_UPDATE_AT")
private LocalDateTime update_at = LocalDateTime.now();
@Column(name = "POST_LIKE", columnDefinition = "INTEGER DEFAULT 0")
private int like;
@Column(name = "POST_DISLIKE", columnDefinition = "INTEGER DEFAULT 0")
private int dislike;
@Column(name = "POST_VIEW", columnDefinition = "INTEGER DEFAULT 0")
private int view;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
@JsonIgnore
private User user;
public static Post dtoToEntity(SavePostDTO dto, User user) {
return Post.builder()
.title(dto.getTitle())
.content(dto.getContent())
.author(dto.getAuthor())
.like(0)
.dislike(0)
.view(0)
.user(user)
.create_at(LocalDateTime.now())
.update_at(LocalDateTime.now())
.build();
}
}
게시글은 제목, 내용, 작성자, 작성시간, 좋아요, 싫어요, 댓글이 있다.
제목, 내용은 문자열 타입으로 만들었다.
글과 작성자의 관계는 @ManyToOne으로 매핑했다.
하나의 글에 많은 댓글이 존재하니 @OneToMany로 매핑했고, 중간 테이블이 생기지 않고 연관관계의 주인을 댓글로 지정할 수 있게 mappedBy 속성을 추가해주었다.
2. 유저를 저장할 User 엔티티도 만들어준다.
package com.developer.domain.user;
@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@ToString
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@JsonIgnore
private Long id;
private String name;
private String username;
private String password;
private String email;
@ManyToMany
private Collection<Role> roles = new ArrayList<>();
}
유저의 PK가 될 ID를 AUTO_INCREMENT로 만들어준다.
유저의 닉네임은 name 필드
유저의 아이디는 username 필드
유저의 비밀번호는 password 필드
유저의 이메일은 email 필드가 될 것이다.
package com.developer.domain.user;
@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
한 사람이 여러 ROLE을 가질 수 있으니 @ManyToOne 단방향 관계로 매핑했다.
어노테이션 | 설명 |
@Entity | JPA에서 데이터베이스의 테이블과 매핑되는 클래스이다. |
@Data | 롬복의 어노테이션이며 Getter와 Setter를 제공한다. |
@NoArgsContructor | No Args 즉 인자가 없는 생성자를 만들어준다. |
@AllArgsContructor | All Args 즉 모든 필드를 인자로 갖는 생성자를 만들어준다. |
@Id | 데이터베이스의 PK에 해당한다. |
@GeneratedValue | AUTO_INCREMENT, SEQUENCE같이 테이터베이스에서 PK의 생성전략을 지정할 수 있다. MySQL을 사용하므로 AUTO_INCREMENT 방식인 IDENTITY로 지정해줬다. |
@JsonIgnore | 객체를 리턴할 때 ObjectMapper가 자동으로 Json으로 바꾸어 주는데 JsonIgnore를 설정한 필드는 Json Response에서 무시된다. |
@JsonNaming | Response를 할때 필드 작명을 스네이크 방식으로 바꾸어준다. 변수명을 카멜케이스로 사용한다면 추천한다. helloWorld -> hello_world |
3. JPA저장소 상속받기
UserRepository
package com.developer.repository;
/**
* @author Taewoo
*/
import com.developer.domain.user.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
User findByUsername(String username);
User findByName(String name);
boolean existsByUsername(String username);
boolean existsByName(String nickname);
boolean existsByEmail(String email);
}
PostRepository
package com.developer.repository;
import com.developer.domain.board.Post;
import org.springframework.data.jpa.repository.JpaRepository;
public interface PostRepository extends JpaRepository<Post, Long> {
}
RoleRepository
package com.developer.repository;
import com.developer.domain.user.Role;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* @author Taewoo
*/
public interface RoleRepository extends JpaRepository<Role, Long> {
Role findByName(String name);
}
JPA 레포지터리를 상속받는 방법은 인터페이스를 선언해주고 JpaRepository를 implemenation한다.
제네릭 타입의 첫 인자는 엔티티 객체 명이고 두번째 인자는 PK의 타입이다.
JPA는 기본적으로 CRUD 메서드를 제공해서 편하다.
이외의 쿼리메소드를 사용할수도 있고 native-query가 필요할 경우엔 JPQL을 직접 입력할 수 있다.
4. 실행 결과
-- auto-generated definition
create table user
(
id bigint auto_increment primary key,
email varchar(255) null,
name varchar(255) null,
password varchar(255) null,
username varchar(255) null
);
-- auto-generated definition
create table user_roles
(
user_id bigint not null,
roles_id bigint not null,
constraint FK55itppkw3i07do3h7qoclqd4k
foreign key (user_id) references user (id),
constraint FKj9553ass9uctjrmh0gkqsmv0d
foreign key (roles_id) references role (id)
);
-- auto-generated definition
create table post
(
id bigint auto_increment
primary key,
post_author varchar(255) null,
post_content varchar(255) null,
post_create_at datetime(6) null,
post_dislike int default 0 null,
post_like int default 0 null,
post_title varchar(255) null,
post_update_at datetime(6) null,
post_view int default 0 null,
user_id bigint null,
constraint FK72mt33dhhs48hf9gcqrq4fxte
foreign key (user_id) references user (id)
);
-- auto-generated definition
create table role
(
id bigint auto_increment
primary key,
name varchar(255) null
);
'Spring > Spring Boot' 카테고리의 다른 글
[학교 관리 프로젝트] 도메인 단위 테스트와 테스트 코드를 가독성있고 빠르게 작성하는 방법 (0) | 2022.08.31 |
---|---|
[게시판 RESTful API] - RestController와 Service를 구현해보자 (3) (0) | 2022.08.20 |
[게시판 RESTful API] - 프로젝트 세팅 (1) (0) | 2022.08.20 |
[Spring Boot] - 유효성 검증을 하는 방법과 유효성 검증 실패 시 Exception핸들링을 하는 4가지 방법을 알아보자 (0) | 2022.08.13 |
[Spring Boot, RIOT API] - Unirest로 RIOT API를 요청하고 ObjectMapper를 배워보자. (0) | 2022.08.10 |