localhost:8080/ (메인페이지 - 글 있는 곳 아님)
localhost:8080/user/{userId}/post
localhost:8080/user/1
localhost:8080/user/{userId}/post/{postId}
localhost:8080/user/{userId}/category/{title}
Visit
id
userId
totalCount
createDate
updateDate
방문자 수는 얼마나 잡아야할까?
마리아 디비의 가장 큰 숫자 타입이 bigint 타입이다.
마리아 디비에서 bigint 타입은 jpa에서 Long을 사용해주면 된다.
package site.metacoding.blogv3.domain.visit;
import java.time.LocalDateTime;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import site.metacoding.blogv3.domain.user.User;
@EntityListeners(AuditingEntityListener.class)
@Entity
public class Visit {
// User 회원가입시 방문자 카운트 0으로 초기화 해두자.
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(length = 100000000, nullable = false)
private Long totalCount;
@JoinColumn(name = "userId")
@ManyToOne
private User user;
@CreatedDate
private LocalDateTime createDate;
@LastModifiedDate
private LocalDateTime updateDate;
}
User
id
username
password
createDate
updateDate
해시 알고리즘은 암호화하면 복호화할 수 없는 단방향 암호화 알고리즘이다.
그래서 비밀번호를 까먹었다고 하면 알려줄 수 없어서 초기화해야 한다.
이메일이나 전화번호가 있어야 초기화된 비밀번호를 알려줄 수 있다.
이메일을 만들어주자.
SHA 알고리즘으로 만들지 않으면 시큐리티가 거부한다.
package site.metacoding.blogv3.domain.user;
import java.time.LocalDateTime;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
@EntityListeners(AuditingEntityListener.class)
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(length = 20, nullable = false, unique = true)
private String username;
// 1234 -> SHA256(해시 알고리즘) 사용해서 암호화 -> AB4524GDUF3AE -> 이렇게 안하면 시큐리티가 거부
@Column(length = 20, nullable = false)
private String password;
@Column(length = 60, nullable = false)
private String email;
@CreatedDate
private LocalDateTime createDate;
@LastModifiedDate
private LocalDateTime updateDate;
}
Post
id
title
content
thumnail
userId
categoryId
createDate
updateDate
이미지 업로드하는데 정책이 여러 가지가 있다.
내가 a.png를 넣었는데 다른 사람이 또 a.png를 넣으면 충돌이 일어난다.
우리는 UUID를 사용했는데
a_1.png, a_2.png로 넘버링하는 정책도 있다.
혹은 날짜로 넘버링하는 정책도 있다.
a_20220407_000001.png
혹은 날짜로 폴더를 생성하여 넘버링 하는 정책도 있다.
20220407
a_00001.png
a_00002.png
정책의 종류가 많은데 UUID가 가장 편하다.
UUID 때문에 파일 이름의 길이가 길어지니까 length를 넉넉히 잡아준다.
package site.metacoding.blogv3.domain.post;
import java.time.LocalDateTime;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import site.metacoding.blogv3.domain.category.Category;
import site.metacoding.blogv3.domain.user.User;
@EntityListeners(AuditingEntityListener.class)
@Entity
public class Post {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(length = 60, nullable = false)
private String title;
@Lob // 4GB
@Column(nullable = true)
private String content;
@Column(length = 200, nullable = false)
private String thumnail;
@JoinColumn(name = "userId")
@ManyToOne
private User user;
@JoinColumn(name = "categoryId")
@ManyToOne
private Category category;
@CreatedDate
private LocalDateTime createDate;
@LastModifiedDate
private LocalDateTime updateDate;
}
Love
id
postId
userId
createDate
updateDate
id postId userId
1 1 3
2 1 3
3 1 2
한 사람이 두 번 이상 좋아요 할 수는 없지만
하나의 게시글에 여러 개의 좋아요가 있을 수는 있다,
이것도 묶어서 유니크 제약조건을 줘야겠다.
package site.metacoding.blogv3.domain.Love;
import java.time.LocalDateTime;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import site.metacoding.blogv3.domain.post.Post;
import site.metacoding.blogv3.domain.user.User;
@EntityListeners(AuditingEntityListener.class)
@Entity
@Table(uniqueConstraints = {
@UniqueConstraint(name = "love_uk", columnNames = { "postId", "userId" })
})
public class Love {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@JoinColumn(name = "postId")
@ManyToOne
private Post post;
@JoinColumn(name = "userId")
@ManyToOne
private User user;
@CreatedDate
private LocalDateTime createDate;
@LastModifiedDate
private LocalDateTime updateDate;
}
Category
id
title
userId
createDate
updateDate
카테고리 타이틀 자체가 유니크해버리면 다른 사람은 그 타이틀에 글을 쓰지 못하기 때문에
어떤 사람의 타이틀이라고 유저와 타이틀을 묶어서 유니크 제약조건을 걸어야 한다.
여러 개의 컬럼을 유니크하게 관리하기 위해서는
Table 어노테이션을 붙여준다.
package site.metacoding.blogv3.domain.category;
import java.time.LocalDateTime;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import site.metacoding.blogv3.domain.user.User;
@EntityListeners(AuditingEntityListener.class)
@Entity
@Table(uniqueConstraints = {
@UniqueConstraint(name = "category_uk", columnNames = { "title", "userId" })
})
public class Category {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
// UTF-8 (가변 인코딩 : 영어 1Byte, 한글 3Byte)
@Column(length = 60, nullable = false)
private String title;
@JoinColumn(name = "userId")
@ManyToOne
private User user;
@CreatedDate
private LocalDateTime createDate;
@LastModifiedDate
private LocalDateTime updateDate;
}
[출처]
https://cafe.naver.com/metacoding
메타 코딩 유튜브
https://www.youtube.com/c/%EB%A9%94%ED%83%80%EC%BD%94%EB%94%A9