본문 바로가기
김영한 스프링/게시판 클론코딩

게시판 클론코딩 CRUD 까지

by hoshi03 2023. 10. 3.

application.properties 설정

# 서버 포트 설정
server.port=8082

# database 연동 설정
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/board?serverTimezone=Asia/Seoul&characterEncoding=UTF-8
spring.datasource.username=board
spring.datasource.password=1111
spring.thymeleaf.cache=false

# spring data jpa 설정
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.open-in-view=false
spring.jpa.show-sql=true
# ddl auto를 update에서 create로 변경, 아예 덮어씌우는 방식
spring.jpa.hibernate.ddl-auto=create

mysql에서 db, 계정 생성 후 권한 부여

create database board;
create user board@localhost identified by '1234';
grant all privileges on board.* to board@localhost;

 

컨트롤러 패키지를 만들고 컨트롤러를 등록

컨트롤러에 GetMapping 어노테이션으로 등록한 메서드는 return 하는 string의 이름에 해당하는 html을 templates 폴더에서 찾아서 화면에 띄워준다 

 

RequsetMapping 어노테이션에 /board 를 해두면 기본으로 board 하위의 주소로 찾아간다

 

save.html에 action은 /board/save로 찾아가고 method는 post로 해서 postmapping으로 받게 한다

만약 컨트롤러에서 getmapping이나 postmapping 같은 매핑류가 같은 이름으로 중복되면 ambiguous 에러가 발생하는 일이 일어나니 중복하지 말자

 

save.html에서 보내는 데이터를 @RequestParam("boardWriter") String boardWriter 으로 받을 수도 있지만

dto를 만들어서 받는 방식을 사용하자

 

글을 쓸때 필요한 속성들이 많다, 하나씩 보내기엔 너무 많으니 dto에 필드로 넣어두고 lombok의 어노테이션으로

필드들의 생성자,게터,세터 등을 편하게 만들어주자

 

save.html에서 보낸걸 @ModelAttribute BoardDTO boardDTO 형태로 BoardDTO 객체를 받아오자

save.html의 name과 필드 값이 동일하면 스프링에서 알아서 세팅해준다

 

값을 저장할 저장소를 만들어주자. entity 패키지에 BoardEntity 클래스를 만들었다

엔티티는 db의 테이블과 같은 기능을 한다, 사용하기 위해서는 @Entity 어노테이션을 붙여준다

 

생성, 수정 시간을 저장할 BaseEntity를 만들어주고 boardEntitiy에 상속해준다

 

repository 패키지를 생성하고 BoardRepository 인터페이스를 JpaRepository를 상속해서 작성한다

JpaRepository를 사용할때는 사용할 엔티티와 pk의 속성을 넣어준다

 

위에서 만든 dto와 엔티티를 이용할 service 클래스를 만들고 생성자 주입을 이용해서 boardservice를 관리한다

service에서는 dto - > entitiy나 entitiy -> dto 변환 작업을 빈번하게 한다

엔티티는 db에 직접 저장하는 부분이라 엔티티까지는 사용자에게 보여주지 않고

컨트롤러에서는 dto를 받아서 사용, 리포지토리에서는 entity를 사용하는 걸로 이해했다

 

BoardEntity 클래스에는 dto를 받아서 entitiy로 변환하는 toSaveEntity 메서드를 작성

이제 스프링을 실행하고 save를 하면 db에 boardEntity에서 설정한 이름의 테이블에 입력한 값이 들어가는걸 볼 수 있다! 

 

글 목록을 가져오기 위해 컨트롤러에서는 db에서 전체 데이터를 가져와야 한다, model 객체를 사용해서 db에서 가져온다index.html에 글 목록을 보여줄 listReq 온클릭을 만들고 컨트롤러에 findAll메서드를 만들어서

db에서 전체 게시글을 가져와서 list.html에 보여지게 한다

dto -> 엔티티를 할때는 service에서 toentitiy로 변환해서 db에 저장햇고

반대로 엔티티에서 dto로 변환해서 가져오는건 dto 객체에서 가져온다

 

특정 게시물 클릭했을때 조회수 증가, 그 게시물 반환하기

특정 게시물을 클릭하면 그 id와 연결되게 컨트롤러에 getmapping으로 해당 id의 값을 가져오는 findById 메서드, 조회수를 증가시키는 updateHits 메서드를 만들어보자

 

findByID 메서드는 boardSerive에 optional을 이용해 널이 아니면 해당 dto를 entitiy에서 가져와서 리턴하는 방식으로 만들면 되고 

updateHits 메서드는 기본 쿼리문을 작성해줘야 하기에 BoardRepository 인터페이스에 특정 id일때 boardHits를 늘려주는 메서드를 작성한다.

 

 게시물 수정

게시물을 수정하는 것도 컨트롤러에서는 id와 모델을 받아와서 처리한다

수정 페이지인 update.html에서는 id나 조회수등 사용자에게 보여줄 필요가 없는 정보는 hidden 속성으로 숨겨두었다 

컨트롤러에 update 메서드를 작성해서  model을 받아서  업데이트를 하게 해주고 그 기능을 service에서 구현한다

Repository에 update 메서드를 기본으로 제공해주진 않으니 만들어보자!

스프링 jpa는 save 메서드 하나로 id 포함 여부에 따라서 update기능과 insert 기능을 둘 다 구현 가능하다

id를 넣어주지 않은 save는 insert가 되고 id를 넣어준 save는 update가 된다

boardservice에 id를 포함해서 업데이트하는 update 메서드를 만들고 repository에 dto를 엔티티로 변환해서 저장하기 위해서 toUpdateEntity 메서드를 boardEntity에 작성해준다

 

인텔리제이에서도 업데이트 쿼리를 확인할 수 있다

 

 게시물 삭제

삭제는 생각보다 간단하게 처리된다

@PathVariable로 id를 받아서 해당 id를 boardService.delete를 호출해 삭제하게 하고 목록 페이지로 리다이렉트 한다

boardService의 delete 메서드도 간단하게 boardRepository.deleteById(id); 형태로 기본으로 잇는 deleteById 메서드를 사용하면 된다