1. 프로젝트 생성
2. build.gradle -> dependencies 에 코드 추가
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.projectlombok:lombok'
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
//여기부터 2줄 추가
compile group: 'org.mariadb.jdbc', name: 'mariadb-java-client'
compile group: 'org.thymeleaf.extras', name: 'thymeleaf-extras-java8time'
}
3. application.properties 에 코드 추가
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.datasource.url=jdbc:mariadb://localhost:3307/bootex
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.show-sql=true
spring.thymeleaf.cache=false
4. resources -> static 폴더 안에 복사
5. templates -> layout 폴더 아래에 basic.html , layout.html 파일 생성
basic.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<th:block th:fragment="setContent(content)">
<head>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<title>Simple Sidebar - Start Bootstrap Template</title>
<title>Simple Sidebar - Start Bootstrap Template</title>
<!-- Bootstrap core CSS -->
<link th:href="@{/vendor/bootstrap/css/bootstrap.min.css}" rel="stylesheet">
<!-- Custom styles for this template -->
<link th:href="@{/css/simple-sidebar.css}" rel="stylesheet">
<!-- Bootstrap core JavaScript -->
<script th:src="@{/vendor/jquery/jquery.min.js}"></script>
<script th:src="@{/vendor/bootstrap/js/bootstrap.bundle.min.js}"></script>
</head>
<body>
<div class="d-flex" id="wrapper">
<!-- Sidebar -->
<div class="bg-light border-right" id="sidebar-wrapper">
<div class="sidebar-heading">Start Bootstrap </div>
<div class="list-group list-group-flush">
<a href="#" class="list-group-item list-group-item-action bg-light">Dashboard</a>
<a href="#" class="list-group-item list-group-item-action bg-light">Shortcuts</a>
<a href="#" class="list-group-item list-group-item-action bg-light">Overview</a>
<a href="#" class="list-group-item list-group-item-action bg-light">Events</a>
<a href="#" class="list-group-item list-group-item-action bg-light">Profile</a>
<a href="#" class="list-group-item list-group-item-action bg-light">Status</a>
</div>
</div>
<!-- /#sidebar-wrapper -->
<!-- Page Content -->
<div id="page-content-wrapper">
<nav class="navbar navbar-expand-lg navbar-light bg-light border-bottom">
<button class="btn btn-primary" id="menu-toggle">Toggle Menu</button>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-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 ml-auto mt-2 mt-lg-0">
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Dropdown
</a>
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Something else here</a>
</div>
</li>
</ul>
</div>
</nav>
<div class="container-fluid">
<th:block th:replace = "${content}"></th:block>
</div>
</div>
<!-- /#page-content-wrapper -->
</div>
<!-- /#wrapper -->
<!-- Menu Toggle Script -->
<script>
$("#menu-toggle").click(function(e) {
e.preventDefault();
$("#wrapper").toggleClass("toggled");
});
</script>
</body>
</th:block>
</html>
layout.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<th:block th:fragment="setContent(content)">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<style>
* {
margin: 0;
padding: 0;
}
.header {
width:100vw;
height: 20vh;
background-color: aqua;
}
.content {
width: 100vw;
height: 70vh;
background-color: lightgray;
}
.footer {
width: 100vw;
height: 10vh;
background-color: green;
}
</style>
<div class="header">
<h1>HEADER</h1>
</div>
<div class="content" >
<th:block th:replace = "${content}">
</th:block>
</div>
<div class="footer">
<h1>FOOTER</h1>
</div>
</body>
</th:block>
</html>
6. GuestbookController 클래스 생성
package com.example.chapter4.controller;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/guestbook")
@Log4j2
public class GuestbookController {
@GetMapping({"/", "/list"})
public String list(){
log.info("list..................");
return "/guestbook/list";
}
}
7. list.html 파일 생성
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<th:block th:replace="~{/layout/basic :: setContent(~{this::content})}">
<th:block th:fragment="content">
<h1>GuestBook List Page</h1>
</th:block>
</th:block>
8. BaseEntity 생성
package com.example.chapter4.Entity;
import lombok.Getter;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.Column;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import java.time.LocalDateTime;
//객체의 입장에서 공통 매핑 정보가 필요할때 사용
//테이블로 생성되지않음 -> 실제 테이블은 BaseEntity를 상속한 엔티티 클래스로 생성
@MappedSuperclass
//엔티티 객체에 어떠한 변화가 일어나는 것을 감지하는 리스너
@EntityListeners(value = {AuditingEntityListener.class})
@Getter
abstract class BaseEntity {
@CreatedDate
//updateable = false : 해당 엔티티 객체를 DB에 반영할 때 regdate 칼럼 값은 변경 X
@Column(name="regdate", updatable = false)
private LocalDateTime regDate;
@LastModifiedDate
@Column(name="moddate")
private LocalDateTime modDate;
}
9. Chapter4Application 클래스 코드 추가
package com.example.chapter4;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
@SpringBootApplication
//AuditingEntityListener 활성화
@EnableJpaAuditing
public class Chapter4Application {
public static void main(String[] args) {
SpringApplication.run(Chapter4Application.class, args);
}
}
10. Guestbook 클래스 추가
package com.example.chapter4.Entity;
import lombok.*;
import javax.persistence.*;
@Entity
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Guestbook extends BaseEntity{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long gno;
@Column(length = 100, nullable = false)
private String title;
@Column(length = 1500, nullable = false)
private String content;
@Column(length = 50, nullable = false)
private String writer;
}
11. 프로젝트 실행
'IntelliJ > Spring boot' 카테고리의 다른 글
[Springboot]게시판 만들기 3장 서비스 계층과 DTO - hoyhi (0) | 2021.04.26 |
---|---|
[Springboot]게시판 만들기 2장 Querydsl 설정 및 테스트 - hoyhi (0) | 2021.04.25 |
[Spring boot] Entitiy, DTO, VO 차이 -hoyhi-tistory (0) | 2021.04.03 |
Spring Model 객체 (0) | 2021.02.21 |
스프링부트 프로젝트 생성 (0) | 2021.02.21 |