게시판 만들기 => CRUD 과정 구현
Create, Read, Update, Delete
🔸 HTML 요소인 form 태그에 담긴 데이터
🔸 폼데이터는 서버로 전송하고 controller가 이를 객체(DTO)에 담아 받음
🔸 어디로 보낼지(action) + 어떻게 보낼지(method) form 태그에 포함되어있어야 함
🔸 src/main/resources/templates에 articles 이름의 디렉토리 생성
🔸 articles 디렉토리에 new.mustache 파일 생성
🔸 bootstrap에서 form 검색 후 복사
🔸 main/java/com.example.firstProject/controller 디렉토리에 ArticleController 파일 생성
[ArticleController]
[new.mustache]
[결과]
🔸 (HTML 변경)
🔸 mustache 파일의 form 태그에 action과 method 추가
🔸 action은 어디로 보낼지, method는 어떻게 보낼지 결정
🔸 controller에 메소드 추가
🔸 이때 annotation이 GetMapping이 아니라 PostMapping => 앞에서 생성한 mustache 파일에서 post로 전송했기 때문
🔸 PostMapping의 주소는 앞의 mustache에서 action으로 보낸 주소와 일치해야함
🔸 데이터를 객체로 받아야하므로 DTO 필요
🔸 main/java/com.example.firstProject에 dto 디렉토리 생성 (controller와 같은 레벨에 존재)
🔸 dto 디렉토리에 ArticleForm 이름의 자바 클래스 파일 생성
🔸 해당 dto/ArticleForm이 데이터를 받아올 그릇 역할
🔸 2개의 데이터를 가져올 것이므로 private으로 변수 지정 후 생성자 생성 (마우스 우클릭해 Generate -> Constructor)
🔸 데이터를 잘 받았는지 확인하기 위해서 toString 메소드 생성 (마우스 우클릭해 Generate -> toString)
🔸 controller에서 PostMapping으로 받은 메소드의 파라미터에 DTO를 넣어야함
🔸 데이터 값을 보기 위해 파라미터.toString()으로 변환해 출력
[dto/ArticleForm]
[controller/ArticleController]
🔸 mustache 내의 input 태그와 textarea 태그 내에 dto의 필드명과 동일한 이름이 name으로 지정되어야 함 => data가 dto와 연결되어 전달
<input type="text" class="form-control" name="title">
<textarea class="form-control" rows="3" name="content"></textarea>
[templates/articles/new.mustache]
[controller/ArticleController]
[dto/ArticleForm]
[페이지&결과]
[전송전페이지]
[전송후페이지]
🔸 위까지의 과정은 client -> server 까지의 과정. 하지만 이 데이터가 DB까지 연결되야 함
🔸 데이터를 관리하는 창고로 H2 사용
🔸 스프링부트는 자바를 사용하지만 데이터베이스는 자바가 아닌 SQL 사용 => JPA가 자바를 SQL로 바꿔주며 데이터 관리에 필요한 여러 기능 제공
🔸 JPA의 핵심 도구는 entity와 repository
자바 객체(DTO)를 DB가 잘 이해할 수 있게 규격화된 객체로 만듬
entity는 repository를 통해 DB에 전달 및 처리
Controller에서 데이터를 객체로 받은 메소드에 작성
Article이라는 타입에 entity 반환
Article article = form.toEntity();
[entity/Article]
Article saved = articleRepository.save(article);
private ArticleRepository articleRepository;
[ArticleController]
main/java/com.example.firstProject에 repository 디렉토리 생성 후 ArticleRepository 이름의 interface 파일 생성: repository를 직접 생성할 수도 있지만, JPA가 제공하는 인터페이스 사용
(repository) extends CrudRepository<관리대상 entity, 관리대상 entity의 대표값의 타입> => 해당 프로젝트에서 관리 대상 entity는 Article, 관리 대상 entity의 대표값은 @Id로 annotation한 것이므로 타입은 Long.
위를 통해 crud(생성, 읽기, 수정, 삭제) 기능을 별도의 코드 작성 없이 사용 가능
[repository/ArticleRepository]
save는 CrudRepository의 기본 기능이므로 오류 없이 사용 가능
ArticleController에 있는 ArticleRepository 위에 @Autowired를 하면 객체 생성을 하지 않아도 스프링부트가 미리 생성해놓은 객체를 가져와 자동 연결시킴
[controller/ArticleController]
[entity/Article]
[repository/ArticleRepository]
[실제 데이터 전송]
ㄴcontroller에서 dto, entity, repository를 출력한 것이 차례대로 나타남 (ArticleForm -> Article(entity) -> Article(repository))
🔸 DB에 저장된 데이터는 테이블이라는 틀에 관리
🔸 이전에 우리가 구현한 entity Article
🔸 CRUD는 DB 내에서 SQL 언어로 처리되는데, Insert(create), Select(read), Update(update), Delete(delete기능)
🔸src/main/java/resources/application.properties에 아래 코드 작성 => H2 DB를 웹 콘솔로 접근 허용
spring.h2.console.enabled=true
🔸 웹브라우저에 localhost:8080/h2-console로 검색
🔸 JDBC URL이라는 데이터베이스 접근 주소가 매번 바뀌기 때문에 찾아서 수정해야함 => IntelliJ 콘솔에서 ctrl+F 누른 후 jdbc 검색 => jdbc:h2:mem:a2212fad-07c4-4602-a375-c88ccdfbba9d 와 같이 jdbc부터 끝까지 복사
🔸 JDBC URL 붙여넣기 후 연결 완료
🔸 ARTICLE 클릭하면 SQL문으로 SELECT * FROM ARTICLE 나타남:ARTICLE 테이블에 있는 모든 것 조회 => Run 눌러 실행
🔸 위에는 현재 데이터가 없다고 뜨는데 이유는 memory에 저장되기 때문에 서버를 재시작하면 이전의 데이터가 모두 삭제됨
🔸 localhost:8080/articles/new에서 데이터 전송 후 table 확인
🔸 하나 더 추가
🔸 직접 작성해 DB에 추가 가능 => 이때 큰 따옴표(")가 아닌 작은 따옴표(') 사용해야함
insert into article(id, title, content)
values(3, 'cccc', '3333')
🔸 정상적으로 성공
🔸 테이블 조회
select * from article
🔸 코드를 간소화시켜주는 라이브러리
🔸 getter(), setter(), constructor(), toString() 등 필수 메소드의 반복을 간소화할 수 있음
🔸 로깅 기능을 통해 println도 개선(리팩토링)할 수 있음
🔸 리팩토링: 코드의 구조와 성능을 개선하는 작업, 로깅은 프로그램의 수행 과정을 기록으로 남기는 것
🔸 기존 코드: controller, dto, entity, repository
🔸 목표: 롬복을 통해 코드 간소화 & println 메소드를 로깅으로 변환
🔸 (코끼리 아이콘) build.gradle의 dependencies가 중요 => 라이브러리 존재
🔸 dependencies 안에 아래 코드 추가 후 위의 코끼리 버튼 클릭해 인터넷으로부터 해당 라이브러리 다운받아옴
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
🔸 오른쪽 Gradle 클릭하면 추가된 라이브러리 확인 가능
🔸 Help > Find action > plugins 검색 후 Marketplace 클릭 후 lombok 검색 및 설치 => 현재 IntelliJ는 롬복이 자체 내장되어있어 설치할 필요 X
🔸 실제 서버에서 println으로 검증하면 기록 남지도 않고 서버 성능에도 악영향을 미치므로 절대 사용 X => logging 사용
🔸 로깅: 서버에서 일어나는 모든 일을 모두 기록
🔸 controller에서 주로 사용하며 @Slf4j annotation 사용
🔸 롬복: 기존 코드에는 생성사와 toString 메소드가 존재
1. 생성자 코드 삭제 -> public class ArticleForm {} 위에 @AllArgsConstructor 작성
2. toString 메소드 삭제 -> public class ArticleForm {} 위에 @ToString 작성
이후 잘 동작하는지 테스트
🔸 로깅:
1. @Slf4j annotation 작성
2. println 코드 삭제 후 log.info()
3. info의 파라미터로 출력을 원하는 값(println의 파라미터와 동일) 넣기
[기존dto]
[롬복 사용 dto]
[기존 entity]
[롬복 사용 entity]
🔸 @Slf4j annotation 사용
[기존 Controller] => 오타 존재. 아래의 logging 사용 controller의 주석 처리된 값이 맞음
[logging 사용 Controller]
🔸 logging으로 기록할 경우 앞의 시간과 같은 추가 정보도 나타남