백엔드/Spring

Spring (2)

SeungEunii 2023. 5. 18. 00:16

JPA

 

1. Entity

 

**테이블 생성 시 실행은 잠시 멈췄다가 테이블 다 만들고 실행시켜보자 아님 문제 생김 진짜 중요함**

 

 

dto 느낌임

근데 DB에서 테이블을 만들지 않고도 테이블 생성 가능함 

 

 

먼저,

속성에서 해줘야할 게 있음

 

/*application.properties*/

spring.jpa.hibernate.ddl-auto=update

 

속성에서 update라고 해줄 경우에 내가 쓰는 DB에 테이블 생성됨

 

 

spring.jpa.hibernate.ddl-auto=validate

 

validate는 테이블 생성 후 정상 매핑되었는지 확인함 

테이블 생성 후 계속 validate로 유지

 

 

 

 

 

- Entity에서 필요한 어노테이션

 

@Data
@Entity
@Table(name = "테이블명")
@SequenceGenerator(name = "시퀀스명", sequenceName = "DB에 저장될 시퀀스명", 
				initialValue = 초기값, allocationSize = 증가값) //꼭 쓰는건 아님

 

 

@Entity는 해당 클래스를 테이블로 인식할 수 있도록 만드는 어노테이션

@Table(name = "테이블명")은 생성하고자하는 테이블, 또는 생성되어 있는 테이블 매칭함

@SequenceGenerator는 시퀀스 지정하고자 할 때 쓰임

 

 

 

 

- Entity class 내부 어노테이션

 

 

@Column 생략하면 변수명이 컬럼명이 된다

 

@Column(nullable = false) // not null
@Column(length = 200) // 200 설정
@Column(name = "id") // 컬럼명 직접지정

 

 

 

@ColumnDefault default 값 지정하는 건데

 

@Column(columnDefinition = "long default 1")

 

직접 썼을 땐  위와 같이 써야 default값이 먹혔다

@ColumnDefault로 하니 default 안됐음 그래서 위의 방식대로 한 것

 

 

 

해당 필드에 @Id 어노테이션을 붙이면 그 필드는 DB테이블의 기본키가 된다

@DateTimeFormat은 자기가 원하는 패턴으로 데이터를 입력 받아올 수 있다
@CreationTimestamp는 데이터가 추가(생성)시에만 날짜 정보 저장된다

@UpdateTimestamp는 데이터 변경시에도 날짜 정보가 변경 된다

 

 

 

@GeneratedValue시퀀스 어노테이션임

이걸 쓰기 위해선 @SequenceGenerator가 필요하다

 

@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_B1")

 

 

 

<코드>

 

@Data
@Entity
@Table(name = "MEMBER1")

public class Member1 {

    @Id //기본키
    @Column(name = "ID", length = 50)
    private String id; 

    private String pw;

    private String name;

    private int age;

    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS")
    @CreationTimestamp
    private Date regdate;
    
}

 

 

그러고 코드 실행하면

DB에 테이블이 생성되는걸 볼 수 있는데

 

 

이후엔 환경 설정으로 가서 꼭 validate로 바꿔줘야한다

 

spring.jpa.hibernate.ddl-auto=validate

 

 

 

 

2. Repository

 

Repository는 Mapper 느낌이라고 생각하면 될 것 같다

그리고 꼭 interface로 설정 해주자

 

 

- Repository에 필요한 어노테이션

 

@Repository

 

 

<코드>

@Repository 
public interface Member1Repository extends JpaRepository<Member1, String>{ 


}

 

초반 코드는 별게 없다 이게 끝이다 

 

JpaRepository<엔티티명, 엔티티의 기본키 타입> 으로 설정해주면된다.

 

 

 

JpaRepository에는 기본적인 CRUD 구현 되어있기때문에 

CRUD를 제외한 나머지는 직접 만들어야 함

 

 

그때 필요한 사이트가 

 

https://docs.spring.io/spring-data/jpa/docs/2.7.10/reference/html/#jpa.sample-app.finders.strategies

 

들어가서 참고하면 된다.

 

 

 

 

사용방법은 findBy변수명으로 주로 쓰인다고 보면 된다

 

 

<예시>

 

// 전체 조회
// SPQL => select * from member1 order by name desc;
public List<Member1> findAllByOrderByNameDesc();

// 검색
// SPQL => select * from member1 where name like '%?%' order by name desc;
public List<Member1> findByNameContainingOrderByNameDesc(String name);

 

라고 생각하면 될 것 같다 

findAll은 파라미터 필요 없음 전체를 갖고 오는거라서

find만 있을경우 파라미터 필요함 

 

 

 

전체를 가지고 오는게 아니라면 List로 해줄 필요는 없다

 

 

 

 

 

3. controller

 

controller는 항상 하던대로 해주면 된다

 

 

@Slf4j
@Controller
@RequestMapping(value = "/member1")
@RequiredArgsConstructor
public class Member1Controller {

    final String format = "Member1Controller => {}";
    final Member1Repository m1Repository; //저장소 객체 ////원래는 Service 써야하는데 생략했음

/* ----------------------------------------------------------------- */

    //회원가입
    //127.0.0.1:9090/ROOT/member1/join.do
    @GetMapping(value = "/join.do")
    public String joinGET(){
        return "/member1/join"; //templates / member1 / join.html 이동 (화면 나옴)
    }
    
    @PostMapping(value="/join.do")
    public String joinPOST(@ModelAttribute Member1 member1) {

        try {

            log.info(format, member1.toString()); //꼭 찍어보자

            //저장소 호출해서 DB에 넣기해야함 (mapper, service가 없는데도 들어가짐)
            m1Repository.save(member1); //sql문을 안쓰면 DB종류 상관없이 넘어가니깐 이런점에선 좋음
            
            return "redirect:/member1/join.do";
            
        } catch (Exception e) {
            e.printStackTrace();
            return "redirect:/home.do";
        }
        
        
    }

 

 

 

 

return "/example/join";

=> 이거는 html로 이동할 때 쓰이고 

 

 

return "redirect:/home.do";

=> 특정 HTTP응답을 통해 다른 URL로 재요청하라고 지시하는 거?

=> 음 .. 앞의 코드가 전부 실행된 후 이동해야하는 곳을 가르키는? 느낌?? 뭬?