[Spring Boot] JPA + Thymeleaf로 간단한 Web 구현하기

아는벌·2023년 3월 9일
0

web (2)

목록 보기
16/20

application.yml

# application.yml
spring:
  h2:
    console:
      enabled: true
      path: /h2-console

  datasource:
    url: jdbc:h2:tcp://localhost/~/test
    username: sa
    password:
    driver-class-name: org.h2.Driver

  jpa:
    show-sql: true
    hibernate:
      ddl-auto: create
    properties:
      hibernate:
      "[format_sql]": true

logging.level:
  "[org.hibernate.SQL]": debug

이전 게시물들을 기반으로 기본 설정을 했고.. 대신 JPA 기본 셋팅에서 application.yml 파일에서 이전 게시물의 persistence의 코드를 수정하였다.(이번엔 web기반으로 할 예정이니까!)

완성된 디렉토리 구조이다.

  • Board 클래스 - 엔티티 클래스로 DB의 Board 엔티티를 정의한 클래스
  • BoardRepository - 엔티티에 의해 생성된 DB에 접근하는 JPA 메소드 사용하기 위한 인터페이스
  • BoardService
    - 핵심 비즈니스 로직을 처리 후 controller에 전달
    - DB 접근 필요 시 BoardRepository를 통하여 처리
    - 이전의 DAO 역할을 수행
  • BoardController - 외부의 요청을 받고 service를 통해 처리 한 후 뷰 모델 객체를 반환하는 역할
  • templates/board 디렉토리의 파일 - view에 해당

Entity 클래스

@Entity
@Table(name="BOARD", uniqueConstraints = {@UniqueConstraint(columnNames = "seq")})
@Data
public class Board {
    @Id
    @GeneratedValue
    @Column(name = "SEQ")
    private Long seq;
    private String title;
    private String writer;
    private String content;
    private Date writeDate = new Date();
    private int cnt = 0;
}

domain 디렉토리에 Board라는 엔티티 클래스를 생성한다.
BOARD 테이블은 SEQ를 PK로 하고 이것은 유니크 키다.
그외에도 BOARD 테이블은 title, writer, content, writeDate, cnt를 가진다. private Date writeDate = new Date(); private int cnt = 0;은 디폴트값으로 바로 설정하기 위해 코드에 박아뒀다.

Repository

@Repository
public interface BoardRepository extends CrudRepository<Board, Long> {
}

CrudRepository<T, Id>
T - 엔티티 클래스명, Id - 엔티티 클래스의 PK의 자료형

CRUD 관련 기능을 제공하는 인터페이스인 CrudRepository를 상속받는 BoardRepository 인터페이스를 생성한다.
Entity에 의해 생성된 DB에 접근하는 메소드들을 사용하기 위한 인터페이스로 JPA에서 기본적으로 제공하는 메소드를 사용할 수 있게 한다.

Service

@RequiredArgsConstructor
@Service
public class BoardService {
    @Autowired
    private BoardRepository boardRepository;

    public void persist(Board board){
        boardRepository.save(board);
    }
    public List<Board> selectAll(){
        return (List<Board>) boardRepository.findAll();
    }
}

비즈니스 로직을 처리하는 곳으로 @Service를 명시한다.
DB 접근이 필요하다면 BoardRepository에게 요청한다. 이때 @Autowired를 통해 BoardRepository를 자동으로 주입시켜줘야한다!

Controller

@Controller
@Slf4j
public class BoardController {
    @Autowired
    BoardService boardService = new BoardService();

    @GetMapping("/board/list")
    public String boardList(Model model){
        List<Board> list = boardService.selectAll();
        log.info("list ==> "+list.toString());
        model.addAttribute("list",list);
        return "board/list";
    }

    @GetMapping("/board/input")
    public String boardInput(){
        return "board/input";
    }

    @PostMapping("/board/input")
    public String boardInputProc(Board board){
        boardService.persist(board);
        return "redirect:/board/list";
    }
}

웹에서 온 요청을 받아 service를 통해 처리하는 곳으로 @Controller 어노테이션을 명시한다. @GetMapping, @PostMapping 어노테이션으로 url에 따른 요청을 처리하고 뷰 파일을 반환한다.

View

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>게시판</h1>
<hr/>
<p><a th:href="@{/board/input}">글쓰기</a></p>
<hr/>
<table th:border="1">
    <tr>
        <th th:text="seq" th:width="50"></th>
        <th th:text="title" th:width="200"></th>
        <th th:text="writer" th:width="80"></th>
    </tr>
    <tr th:each="board : ${list}">
        <td th:text="${board.seq}"></td>
        <td th:text="${board.title}"></td>
        <td th:text="${board.writer}"></td>
    </tr>
</table>
</body>
</html>

board/list.html 파일이다. BoardController - boardList 메소드 안의 model.addAttribute("list",list); 으로 DB 접근 결과인 list를 list로 받는다.

 <tr th:each="board : ${list}">
        <td th:text="${board.seq}"></td>
        <td th:text="${board.title}"></td>
        <td th:text="${board.writer}"></td>
    </tr>

thymeleaf를 사용하여 list의 내용을 화면에 보여준다.

Git

https://github.com/EunbiAn/webkit-backend/tree/master/springboot_jpa_web_day28

0개의 댓글