스부2회차

황선영·2023년 10월 26일
0

확실히 스프링 하위단계인 서블릿부터 머리싸매고 공부한다음에 2회독 해보니 구조가 쉽게 파악되고 이해도 빨리 된것 같다.


jpa는 java persistence api. 인터페이스임.따라서 구현하느 실제 클래스가 있어야 멀 할수가 있음->하이버네이트..

@Column :

  • 엔티티의 속성(프라이빗 변수들)은 테이블의 컬럼명과 일치하는데 컬럼의 세부설정 위해 쓰는 애너테이션.
  • length는 컬럼길이설정, columnDefiniton은 컬럼 속성 정의.
  • columnDefinition = "TEXT" 는 글자수 제한X

@ManyToOne :

  • 상속관계에서 사용. 해당 엔티티의 속성과 , 엔티티가 서로 연결된다.
    (실제 db에선 foreign key관계가 생성된다.)

@OneToMany(mappedBy = "question", cascade = CascadeType.REMOVE)

  • Question 엔티티에 answerList속성위의 애너테이션.
    mappedBy 엔 답변엔티티에서 질문엔티티를 참조한 속성명 을 써야한다.
    cascade는 질문삭제하면 달린답변도 다 삭제되도록 하는거.

public interface QuestionRepository extends JpaRepository<Question, Integer>

  • < , > : 리포지터리의 대상이되는 엔티티의 타입과, 해당 엔티티의 primary key타입 을 지정해야한다.

JpaRepository는 엔티티들을 리스트로 자동저장해주는 기능? -> X아니다.

  • 해당 인터페이스의 여러 메서드중, findAll()이란 메서드를 사용하면 db에있는 모든 엔티티를 리스트로 가져오는거임(이 메서드는 db테이블의 모든 레코드를 조회하고, 각 레코드를 엔티티 객체로 매핑하여 리스트로 반환함)
  • 엔티티 객체를 db에서 읽기,쓰기,수정 및 삭제 하는데 사용되는 spring data jpa의 기능을 제공. 이 인터페이스는 jpa를 기반으로 동작하며, db와의 상호작용을 단순화하고 쿼리를 작성하기 쉽게 해줌
  • 다양한 crud/create, read, update, delete 연산을 제공

@RequiredArgsConstructor
private final QuestionRepository questionRepository;

  • @RequiredArgsConstructor : 롬복이 제공하는 애너테이션. final이 붙은 속성을 포함하는 생성자를 자동으로 생성해준다.
  • final이란 변수,메소드,클래드에 사용될 수 있는 '한정자'
  • 해당 요소에 대한 변경이 허용X, 해당 변수는 '한번만초기화'될 수 있음
  • 변수에 값을 할당 한 후에는 더이상 그 변수에 새로운값 대입할 수 없다
  • 즉 변수의 내용이 한 번 설정되면 이후엔 변경이 안된단뜻
  • 프로그램의 여러 부분에서 변수값을 예상치않게 변경하는 버그를 방지하기 위함.

@Autowired VS @Requiredargsconstructor

  • autowired : -> 'bean객체 자동주입' new 안해도됨.
    - 스프링프레임워크에서 의존성주입 수행하는데 사용. 스프링은 클래스 간의 의존성을 관리하고 필요한 해주는데 이때 이 애너테이션이 사용된다.이 어노테이션이 선언된 필드나 생성자에 해당하는 빈 객체가 자동으로 주입됩니다.

  • requiredargsconstructor : -> 'final 필드의 생성자 자동추가'
    - 롬복 라이브러리에서 제공하는 애너테이션. 클래스의 필드에 대한 해준다. 즉 생성자 메서드를 자동으로 추가해준다. 해당 클래스의 모든 파이널 필드에 대한 매개변수를 갖고있다,...,?

요약하자면, @Autowired는 의존성 주입을 위해 사용되고, @RequiredArgsConstructor는 Lombok을 사용하여 final 필드에 대한 생성자를 자동으로 생성하는데 사용됩니다. 이 두 어노테이션은 서로 다른 목적을 가지고 있습니다.


애네다먼차인지?


객체초기화랑 객체생성이랑 다름.
객체초기화 : 객체생성과 동시에 변두들에 값 세팅 -> 생성자 역할
객체생성 : 걍 생성만 하는거

그냥 '생성'만 된 객체에는 변수에 값이 없으면 null,0 등이 있을텐데 그럼 객체역할을 제대로 수행하지 못할 확률이 높다. 이것을 방지하기 위해 객체생성+값세팅 해주는 생성자를 만든다. 생성자 만들면 값이 할당되어있지 않은 객체는 생성안시키도록 하는듯.


Controller -> Database 직접 접근은 보안에 좋지않음.
Controller -> Service -> Database 이렇게 해야 안전. 컨트롤러에서 리포지터리를 직접 호출하지않고, 서비스를 두어 데이터를 처리한다.

엔티티객체와 dto/data transter object 객체의 변환

  • 엔티티 클래스는, db와 직접 맞닿아 있기때문에 컨트롤러나 타임리프 같은 템플릿 엔진에 전달해 사용하는건 좋지않다
  • 컨트롤러나 타임리프에서 사용하는 데이터객체는 속성을 변경하여 비즈니스적인 요구를 처리해야함
    따라서 엔티티 클래스는 컨트롤러에서 사용하지 못하도록 설계하는게 좋음.
    그러기 위해선, 엔티티 대신 사용할 DTO클래스와 그렇게 변환하는 작업이 필요.
    -> 이작업을 바로 서비스에서 한다. 서비스는 컨트롤러와 리포지터리 중간에서 엔티티객체와 dto객체를 서로 변환하여 양방향에 전달하는 역할.

스프링의 서비스로 만들라면 그냥 클래스명위에 @Service애너테이션 붙이면됨.


URL프리픽스

예로..

questioncontroller클래스 위에
@RequestMapping("/question")
붙이고
클래스 내에서 겟매핑할때
그 뒷부분만 써주면 됨.

그러면 그 url요청은 자동으로 /question/000 이렇게 됨


폼클래스에서 ↓
@NotEmpty(message="제목은 필수항목입니다.") : 해당 값이null또는 빈 문자열을 허용하지 않음. 메시지는 검증이 실패할 경우 화면에 표시할 오류메시지.
@Size(max=200) : 최대길이가 200바이트 넘으면 안됨.
private String subject;

폼 만들고 나서, 컨트롤러에서



이렇게 변경.

  • questionCreate메서드의 매개변수를 subject, content대신 QuestionForm 의 객체로 변경
  • 사용자가 웹 브라우저에서 입력한 subject, content항목을 지닌 폼이 전송되면 , spring 프레임워크가 QuestionForm객체의 subject,content속성으로 자동으로 바인딩 한다 -> 바인딩 기능
  • 사용자가 웹 브라우저에 입력한 subject,content항목을 자동으로 QuestionForm 객체로 받아온다는 뜻


< 폼클래스 사용하는 이유 > :
화면에서 전달되는 입력값을 검증하기 위해. 혹은 바인딩 할때.

  1. 가독성 및 유지보수성 향상
  • 폼과 관련된 데이터 모델이 명확해짐
  • 폼 클래스의 필드명은(변수명) 해당 데이터의 의미를 설명할 수 있고,
    해당 메서드가 어던 데이터를 기대하는지 명확히 알 수 있음
  1. 유효성 검사 및 데이터 가공
  • 폼 클래스 내에는 필드에 대한 제약조건, 유효성검사, 데이터가공 등 로직 추가 가능
  • 컨트롤러에서 이러한 작업을 분리 함으로써, 코드가 깔끔해짐
  1. 편의성과 재사용성
  • 같은 데이터를 여러 폼에서 사용한다면 같은 폼클래스를 여러곳에서 재사용 가능
  • 추가 삭제 등의 작업이 필요할때, 폼클래스만 수정하면 된다 -??
  1. 스프링의 데이터 바인딩
  • 스프링MVC는 자동으로 바인딩 해줌 -> 즉 컨트롤러의 메서드에서 복잡한 파라미터 처리를 안해도 된다

@Valid 애너테이션 : QuestionForm의 @NotEmpty, @Size등의 검증기능이 동작함. 그리고 이어지는 BindingResult 매개변수는 @Valid 애너테이션으로 인해 검증이 수행된 결과를 의미하는 객체이다. 바인딩리저트는 반드시 벨리드 바로뒤에 위치해야함.

if문을통해, 오류가 있는경우, 다시 폼을작성하는 화면을 렌더링하게 했고
오류X -> 질문등록진행.

의존성주입 왜쓰는건지? 정확한 의미와 장점.

profile
개발필기노트

0개의 댓글