엔티티만으로는 데이터베이스에 데이터를 저장하거나 조회 할 수 없다. 데이터 처리를 위해서는 실제 데이터베이스와 연동하는 JPA 리포지터리가 필요하다. 리포지터리는 엔티티에 의해 생성된 데이터베이스 테이블에 접근하는 메서드들(예: findAll, save 등)을 사용하기 위한 인터페이스이다. 데이터 처리를 위해서는 테이블에 어떤 값을 넣거나 값을 조회하는 등의 CRUD(Create, Read, Update, Delete)가 필요하다. 이 때 이러한 CRUD를 어떻게 처리할지 정의하는 계층이 바로 리포지터리이다.
엔티티는 데이터베이스 테이블과 매핑되는 자바 클래스를 말합니다. spring-boot-starter-data-jpa 의존성을 추가하고 @Entiy 어노테이션을 붙이면 테이블과 자바 클래스가 매핑이 됩니다. 그래서 JPA에서 '하나의 엔티티 타입을 생성한다'라는 의미는 '하나의 클래스를' 작성한다는 의미가 됩니다. 엔티티라는 용어는 때로는 클래스를 의미하는 경우도 있고, 클래스에 의해 생성된 인스턴스를 의미하는 경우가 있습니다. 정확히 얘기 하자면, 엔티티 클래스 와 엔티티 인스턴스 혹은 엔티티 객체라는 표현이 정확합니다.
이전 페이지가 없으면 비활성화 th:classappend="${!paging.hasPrevious} ? 'disabled'" 다음 페이지가 없으면 비활성화 th:classappend="${!paging.hasNext} ? 'disabled'" 이전 페이지 링크 th:href="@{|?page=${paging.number-1}|}" 다음 페이지 링크 th:href="@{|?page=${paging.number+1}|}" 페이지 리스트 루프 th:each="page: ${#numbers.sequence(0, paging.totalPages-1)}" 현재 페이지와 같으면 active 적용 th:classappend="${page == paging.number} ? 'active'"
화면에서 전달받은 입력 값을 검증하려면 Spring Boot Validation 라이브러리가 필요하다. (... 생략 ...) dependencies { (... 생략 ...) implementation 'org.springframework.boot:spring-boot-starter-validation' } (... 생략 ...) "Spring Boot Validation"을 설치하면 다음과 같은 애너테이션들을 사용하여 입력 값을 검증할 수 있다. 항목설명 @Size 문자 길이를 제한한다. @NotNull Null을 허용하지 않는다. @NotEmpty Null 또는 빈 문자열("")을 허용하지 않는다. @Past 과거 날짜만 가능 @Future 미래 날짜만 가능 @FutureOrPresent 미래 또는..
서비스가 필요한 이유는 무엇일까? 모듈화 예를들어 어떤 컨트롤러가 여러개의 리포지터리를 사용하여 데이터를 조회한후 가공하여 리턴한다고 가정해 보자. 이러한 기능을 서비스로 만들어 두면 컨트롤러에서는 해당 서비스를 호출하여 사용하면 된다. 하지만 서비스로 만들지 않고 컨트롤러에서 구현하려 한다면 해당 기능을 필요로 하는 모든 컨트롤러가 동일한 기능을 중복으로 구현해야 한다. 이러한 이유로 서비스는 모듈화를 위해서 필요하다. 보안 컨트롤러는 리포지터리 없이 서비스를 통해서만 데이터베이스에 접근하도록 구현하는 것이 보안상 안전하다. 이렇게 하면 어떤 해커가 해킹을 통해 컨트롤러를 제어할 수 있게 되더라도 리포지터리에 직접 접근할 수는 없게 된다. 엔티티 객체와 DTO 객체의 변환 우리가 작성한 Question..
타임리프의 자주 사용하는 속성에는 다음 3가지 유형이 있다. 이 3가지 유형만 알아도 여러 기능을 충분히 만들 수 있다. 1. 분기문 속성 분기문 속성은 다음과 같이 사용한다. th:if="${question != null}" 위의 경우 question 객체가 null 이 아닌 경우에 해당 엘리먼트가 표시된다. 2. 반복문 속성 반복문은 반복횟수만큼 해당 엘리먼트를 반복하여 표시한다. 반복문 속성은 자바의 for each 문과 유사하다. th:each="question : ${questionList}" 반복문은 다음과 같이 사용할 수도 있다. th:each="question, loop : ${questionList}" 추가한 loop 객체를 이용하여 루프 내에서 다음과 같은 속성을 사용할수 있다. loo..