인증 orm
User 객채만들기

이렇게 안되는 이유
암호화를 할 경우 (해쉬 )그럼 12자가 가볍게 넘기 때문이다.
그래서 저 어노에티션은 안붙이는게 좋다
연관 관계를 맺어야 수정을 한번만 할 수 있다
@ManyToOne
@ManyToOne
어노테이션은 다대일(N:1) 관계를 나타내며, 이 경우에는 여러 개의 엔티티가 하나의 엔티티에 매핑됩니다.여기서
User
엔티티가 @ManyToOne
관계로 user
필드로 매핑됩니다. user
필드는 User
엔티티의 객체를 참조합니다.그리고
user
필드에 대한 매핑은 user_id
컬럼으로 이루어집니다. 컬럼명은 변수명_
으로 자동으로 설정됩니다.빌드업 패턴
빌더는 복잡한 객체들을 단계별로 생성할 수 있도록 하는 생성 디자인 패턴입니다.
자기 자신을 return한다(자기자신 = 객체)
public class User {
private Integer id;
private String username;
private String password;
private String email;
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", email='" + email + '\'' +
'}';
}
public static User builder(){
return new User();
}
public User id(int id){
this.id=id;
return this;
}
public User username(String username){
this.username=username;
return this;
}
public User password(String password){
this.password=password;
return this;
}
public User email(String email){
this.email=email;
return this;
}
public static void main(String[] args){
User user = User.builder().id(1).username("ssar");
User user2 = User.builder().id(2).username("cos").password("1234");
User user3 = User.builder().username("love").password("1234").id(3);
System.out.println(user);
System.out.println(user2);
System.out.println(user3);
}
}

장점
생성자를 안만들어도 된다.(생성자를 만들면 생성자에 들어갈 수 있고 없는게 있는데 그럼 그때마다 생성자를 만들어야된다.)
순서에 상관없다
사용하는 이유는 =추후에 값을 바꾸기 위해 쓰는 패턴이 아니라 초기에 값을 설정할 때 쓰기 위한 패턴
integer사용해야하는 이유는
게시글 상세보기
학습목표
- Eager (연관된 객체에 값을 채워준다)
- Lazy (연관된 객체에 값을 채워주지 않는다)
- Lazy Loading
- Object Relation Mapping
- 직접 조인
EAGER
조인만하는게 아니라 단어뜻 그대로 열정적으로 채워준다 보니
만약 보드를 조회하는 쿼리를짜서 던지면 USER를 조회하는 쿼리도 발동 돼 총 두 번 된다.
package shop.mtcoding.blog.user;
import jakarta.persistence.*;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.CreationTimestamp;
import java.sql.Timestamp;
@NoArgsConstructor
@Data
@Table(name = "user_tb")
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(unique = true)
private String username;
private String password;
private String email;
@CreationTimestamp//ps를 -> db로 갈때 날짜로 주입 됨
private Timestamp createdAt;
@Builder
public User(Integer id, String username, String password, String email, Timestamp createdAt) {
this.id = id;
this.username = username;
this.password = password;
this.email = email;
this.createdAt = createdAt;
}
}

public Board findById(int id){
//id, title, content, user_id(이질감), created_at;
Board board = em.find(Board.class, id);
return board;
}
Board를 조회하면user_id를 User 객체의 필드 id에 담아서 board 객체를 만들어준다.

조인을 안하는 lAZY
package shop.mtcoding.blog.board;
import jakarta.persistence.*;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.CreationTimestamp;
import shop.mtcoding.blog.user.User;
import shop.mtcoding.blog.util.MyDateUtil;
import java.sql.Timestamp;
@NoArgsConstructor
@Data
@Table(name = "board_tb")
@Entity
public class Board {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String title;
private String content;
// @JoinColumn(name = "user_id")
@ManyToOne(fetch = FetchType.LAZY)//연관 관계로 본다
private User user; //user_id 변수명(객체)_객체 필드 명(칼럼)
@CreationTimestamp//ps를 -> db로 갈때 날짜로 주입 됨
private Timestamp createdAt;
public String getTime(){
return MyDateUtil.timestampFormat(createdAt);
}
}

@Test
public void findById(){
//given
int id =1;
//when
boardRepository.findById(id);
}

public Board findByIdJoinUser(int id){
Query query = em.createQuery("select b from Board b join fetch b.user u where b.id = :id", Board.class);
query.setParameter("id", id);
return (Board) query.getSingleResult();
}
EAGER 대신 LAZY를 사용하는 이유
LAZY로 설정하고
조인이 필요 할 때 직접 JOINQUERY를 짠다.
왜냐하면 EAGER로 할경우에 디폴트가 JOIN으로 되기때문에 화면에 불 필요한곳 (게시글 목록보기에 USER객체의 해당하는 필드가 필요없다)JOIN을 하기때문이다.
LAZY loding
LAZY상태에서 연관된 객체의 PK아닌 필드 값을 접근을 하면 지연 로딩이 된다.
이거 사용하지 말고 JOIN을 하는게 더 좋음
@Test
public void findById_test() {
int id = 1;
System.out.println("start - 1");
Board board = boardRepository.findById(id);
System.out.println("start - 2");
System.out.println(board.getUser().getId());
System.out.println("start - 3");
System.out.println(board.getUser().getUsername());/
}

.getUser().getUsername()은 null 값이기 때문에 lazy loding이 일어난다.
orm
우리가 선택 해야 되는 전략.
- 결론:lazy전략을 사용하고 필요한 경우 직접 조인하자.
프로젝트 적용
join할 때 는 fetch해서 select 절을 프로젝션 해줘야 된다.
이렇게 하는 이유는 DTO를 사용 안하려고 빌드업 패턴 사용

Share article