본문 바로가기

Spring Boot 수업 정리

Spring Boot 2일차

스프링 부트로 게시판을 만들기위해 워크스페이스를 하나 새로만들어서 

application.properties 부터 설정 

spring.application.name=spring

server.port=8090

# 타임리프 캐싱 끄기. 새로고침 반영 설정
spring.thymeleaf.cache=false
spring.thymeleaf.enabled=true
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html

# DB 설정
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.jdbc-url=jdbc:mysql://localhost:3306/bootdb
spring.datasource.username=springUser
spring.datasource.password=mysql

# mybatis
mybatis.mapper-locations=classpath:/mappers/*.xml
mybatis.configuration.map-underscore-to-camel-case=true

타임리프(Thymeleaf) 레이아웃

● Thymeleaf  th:block을 이용하면 레이아웃을 만들고 특정한 페이지에서는 필요한 부분만을 작성하는 방식으로 개발이 가능.
 레이아웃 기능을 위해서 별도의 라이브러리가 필요
 nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect
 templates layout 폴더를 생성하고 레이아웃을 위한 layout1.thml 작성
 - layout xmlns(네임스페이스) 설정
- 코드 중간에 layout:fragment 속성을 이용하여 해당 영역은 나중에 다른 파일에서 해당 부분만을 개발할 수 있음.
- 하단 두곳에서 content, script 지정
- 새로운 화면을 작성할 때는 layout1.html을 그대로 활용하면서 ‘content / script’ 중 원하는 영역만을 작성할 수 있음.

 

ex)

 header.html

<!DOCTYPE html>
<html lang="en"
      xmlns:th="http://www.thymeleaf.org">

<div th:fragment="header">
  <h1>Header Area</h1>
</div>

 

footer.html

<!DOCTYPE html>
<html lang="en"
      xmlns:th="http://www.thymeleaf.org">

<div th:fragment="footer">
  <h5>Footer Area</h5>
</div>

 

index.html

<!DOCTYPE html>
<html lang="en"
      xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultrap.net.nz/thymeleaf/layout">
<head>
  <meta charset="UTF-8">
  <title>My Thymeleaf Test</title>
  <!--/* 부트스트랩 css js 링크 연결 */-->
  <link rel="stylesheet" th:href="@{/dist/css/bootstrap.min.css}">
  <script th:src="@{/dist/js/bootstrap.bundle.min.js}"></script>
</head>
<body>

<!-- /* th:replace="조각 파일의 경로 :: 이름" */ -->
<div th:replace="~{fragments/header :: header}"></div>

<div layout:fragment="content"></div>

<div th:replace="~{fragments/footer :: footer}"></div>
</body>
</html>

 

이런식으로 만들어주면 화면에 header와 footer가 index에 들어가는걸 볼 수 있다

content는 조각이므로 layout에 맞는 원하는 조각으로 바꿔주면서 사용할 수 있음


스프링부트로 게시판을 만들어보는 작업을 해보자.

● 일단 DB와 게시판테이블 부터 생성 

bootdb 생성해주고

보드 테이블생성 

create table board(
bno bigint auto_increment,
title varchar(200) not null,
writer varchar(200) not null,
content text,
reg_date datetime default now(),
primary key(bno));

 

Spring에서 했던거처럼 config부터 mapper까지 만들어줄건데 DAO는 이름을 repository로 만듬.

 

DB와의 연결을 위해 DataBaseConfig부터 설정해주어야함

@PropertySource("classpath:/application.properties")
@Configuration
public class DataBaseConfig {

    @Autowired
    private ApplicationContext applicationContext;

    @Value("${mybatis.mapper-locations}")
    private String mapperLocations;


    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public HikariConfig hikariConfig(){

        return new HikariConfig();
    }

    @Bean
    public DataSource dataSource() throws Exception{

        return new HikariDataSource(hikariConfig());
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean =
                new SqlSessionFactoryBean();

        sqlSessionFactoryBean.setDataSource(dataSource);
        /* mybatis-config.xml 존재할 경우. */
       /* sqlSessionFactoryBean.setConfigLocation(
                applicationContext.getResource("classpath:/mybatis-config.xml")
        );*/

        sqlSessionFactoryBean.setMapperLocations(
                new PathMatchingResourcePatternResolver().getResources(mapperLocations)
        );
        return sqlSessionFactoryBean.getObject();
    }

    @Bean
    public org.apache.ibatis.session.Configuration mybatisConfig(){
        return new org.apache.ibatis.session.Configuration();
    }

    @Bean
    public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory){
        return new SqlSessionTemplate(sqlSessionFactory);
    }

}

 

● 설정이 끝나면 DB구성에맞게 BoardVO 를 만들어주는데 lombok에 Bulider까지 어노테이션해준다 객체를 스트링으로 만들어주는 기능.

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Builder
public class BoardVO {
    private long bno;
    private String title;
    private String writer;
    private String content;
    private String regDate;
}

 

● 이후 매퍼까지만들어서 연결하는거는 Spring과 동일하지만 다른점은 DAO역할을 하는 Repository에는 어노테이션을 매퍼로 붙혀주어야함.

@Mapper
public interface BoardMapper {

    int register(BoardVO boardVO);
}

 

● 게시글을 등록하는 register를 만들기위해 헤더를 네비게이션 바로 일단 구성을해주고 일단 Register와 list까지만 구현해놓음.

<!DOCTYPE html>
<html lang="en"
      xmlns:th="http://www.thymeleaf.org">

<div th:fragment="header" >
  <nav class="navbar navbar-expand-lg bg-body-tertiary">
    <div class="container-fluid">
      <a class="navbar-brand" href="/">Boot</a>
      <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>
      <div class="collapse navbar-collapse" id="navbarSupportedContent">
        <ul class="navbar-nav me-auto mb-2 mb-lg-0">
          <li class="nav-item">
            <a class="nav-link" href="/board/register">BoardRegister</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="/board/list">BoardList</a>
          </li>
        </ul>
      </div>
    </div>
  </nav>
</div>

 

register.html 페이지에 header와 footer를 레이아웃으로 넣어주고 content안에 영역을 만들어서 form태그안에 정보를 기입할 수 있게해주고 경로와 post 방식을 설정해줌.

<!DOCTYPE html>
<html lang="en"
      xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultrap.net.nz/thymeleaf/layout"
      layout:decorate="~{layout/layout}">

<div layout:fragment="content" class="container-md">
  <h1>Boot Register Page</h1>

    <div>
        <form action="/board/register" method="post">
        <div class="mb-3">
          <label for="t" class="form-label">Title</label>
          <input type="text" class="form-control" id="t" name="title" placeholder="title...">
        </div>
        <div class="mb-3">
          <label for="w" class="form-label">Writer</label>
          <input type="text" class="form-control" id="w" name="writer" placeholder="writer...">
        </div>
        <div class="mb-3">
          <label for="c" class="form-label">Content</label>
          <textarea class="form-control" id="c"  name="content" cols="10" rows="3"></textarea>
        </div>
        <button type="submit" class="btn btn-primary">register</button>
        </form>

    </div>
</div>

 

● 컨트롤러에서  GetMapping으로 register 경로에맞게 이동할 수 있게 설정해주고 register 페이지안에서 입력한 제목, 작성자, 내용의 정보를 전송받아와 BoardVO 객체안에 넣어서 매퍼까지 쭉연결해주어서 DB안에 넣을 수 있도록 함.

Spring에서 계속 했던 내용이므로 자세한 코드는 생략 Spring 게시글참고.

    @GetMapping("/register")
    public String register(){

        return "/board/register";
    }

    @PostMapping("/register")
    public String register(BoardVO boardVO){
        log.info(">>> boardVO >> {}", boardVO);

        int isOk = bsv.register(boardVO);

        return "/board/register";
    }

 

● 게시글 list를 보기위해 화면부터 구성

<div layout:fragment="content">
    <div class="container-md">
        <table class="table table-hover">
            <thead>
            <tr>
                <th scope="col">번호</th>
                <th scope="col">제목</th>
                <th scope="col">글쓴이</th>
                <th scope="col">작성일</th>
            </tr>
            </thead>
            <tbody>
                <tr th:each="bvo:${list}">
                    <td>[[${bvo.bno }]]</td>
                    <td>[[${bvo.title }]]</td>
                    <td>[[${bvo.writer }]]</td>
                    <td>[[${bvo.regDate }]]</td>
                </tr>
            </tbody>
        </table>
    </div>
</div>

 

  컨트롤러에서 db에서 getList를 매퍼까지 연결해서 가져와서 Model에 addAttribute해서 리스트를 보내주면 끝

    @GetMapping("/list")
    public String list(Model m){

        List<BoardVO> list = bsv.getList();

        m.addAttribute("list",list);

        log.info(">>> list > {}" ,list);

        return "/board/list";
    }

 

  테스트용 게시글을 insert해보기위해 test에서 ApplicationTests에 들어가서 메인 실행클래스를 설정해주고

원하는 숫자만큼 추가해보는게 가능.

@SpringBootTest(classes = Application.class)
class ApplicationTests {

	@Autowired
	private BoardMapper boardMapper;

	@Test
	void contextLoads() {
		for(int i=0; i<300; i++){
			BoardVO boardVO = BoardVO.builder()
					.title("test title" + i)
					.writer("tester" +((int)(Math.random()*100)+1))
					.content("test content" + i)
					.build();
			boardMapper.register(boardVO);
		}
	}
}

 

'Spring Boot 수업 정리' 카테고리의 다른 글

Spring boot 6일차  (1) 2024.11.19
Spring Boot 5일차  (1) 2024.11.18
Spring Boot 4일차  (0) 2024.11.15
Spring boot 3일차  (3) 2024.11.14
Spring Boot 1일차  (0) 2024.11.13