본문 바로가기
Back-End/Spring

[spring boot] 간단한 방명록 만들기 [1편]

by LeeGangEun 2022. 5. 20.

프로젝트 환경 설정

 

프로젝트 생성

  • Spring boot(IntelliJ-ultimate 버전이 아니면 스프링 부트 스타터를 사용 -> https://start.spring.io)
  • 사용 기능(라이브러리) :
    1. Lombok
    2. Spring Boot DevTools
    3. Spring Web
    4. Thymeleaf 
    5. Spring Data JPA 
    6. Querydsl (프로젝트 생성시 따로 선택이 불가능하며 maven에서 가져와 수작업으로 build.grade에 넣어줘야함)
    7. MariaDB
    8. BootStrap
  • 프로젝트 설정
    Name : Guestbook
    Group : org.zerock
    JDK : Java11
    Laanguage : Java
    Type : Gradle
    Packge : War

 

build.grade

    plugins {
        id 'org.springframework.boot' version '2.6.7'
        id 'io.spring.dependency-management' version '1.0.11.RELEASE'
        id 'java'
        id 'war'
        id 'com.ewerk.gradle.plugins.querydsl' version '1.0.10'
    }

    group = 'org.zerock'
    version = '0.0.1-SNAPSHOT'
    sourceCompatibility = '11'

    configurations {
        compileOnly {
            extendsFrom annotationProcessor
        }
    }

    repositories {
        mavenCentral()
    }

    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'
        // https://mvnrepository.com/artifact/org.mariadb.jdbc/mariadb-java-client
        implementation group: 'org.mariadb.jdbc', name: 'mariadb-java-client', version: '2.7.1'
        // https://mvnrepository.com/artifact/org.thymeleaf.extras/thymeleaf-extras-java8time
        implementation group: 'org.thymeleaf.extras', name: 'thymeleaf-extras-java8time', version: '3.0.4.RELEASE'
        // https://mvnrepository.com/artifact/com.querydsl/querydsl-jpa
        implementation group: 'com.querydsl', name: 'querydsl-jpa', version: '5.0.0'
        // https://mvnrepository.com/artifact/com.querydsl/querydsl-apt
        implementation group: 'com.querydsl', name: 'querydsl-apt', version: '5.0.0'



    }

    tasks.named('test') {
        useJUnitPlatform()
    }

    def querydslDir = "$buildDir/generated/querydsl"

    querydsl {
        jpa = true
        querydslSourcesDir = querydslDir
    }

    sourceSets {
        main.java.srcDir querydslDir
    }

    configurations {
        compileOnly {
            extendsFrom annotationProcessor
        }
        querydsl.extendsFrom compileClasspath
    }

    compileQuerydsl {
        options.annotationProcessorPath = configurations.querydsl
    }

 

application.properties

server.port=8181  // 포트번호 변경
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.datasource.url=jdbc:mariadb://localhost:3306/bootex
spring.datasource.username=bootuser
spring.datasource.password=bootuser

spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.show-sql=true

spring.thymeleaf.cache=false // thymeleaf 업데이트시 서버 재시작을 안해줘도 됨

 

프로젝트 기본 구조

 

GuestbookController

@Controller
@RequestMapping("/guestbook")
@Log4j2
public class GuestbookController {

    @GetMapping("/list")    // localhost:8181/guestbook/list 접속 시 매핑된다.
    public String list(){
       log.info("listpage...");  // 스프링은 System.out.println을 권장하지 않는다. log.info() 성능이 더 좋음
       return "/guestbook/list";  // 폴더내에 있는 /guestbook/list/ 페이지를 보여준다.
    }

 

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>

 

BaseEntity

@MappedSuperclass // 이 어노테이션이 적용된 클래스는 테이블로 생성되지 않는다.
@EntityListeners(value = {AuditingEntityListener.class})
@Getter
abstract class BaseEntity {
    
    @CreatedDate  // 생성할때 날짜가 들어감
    @Column(name ="regdate", updatable = false) //업데이트를 할수 없음(수정금지)
    private LocalDateTime regDate; // 작성일
    
    @LastModifiedDate // 수정할때 날짜가 들어감
    @Column(name ="moddate")
    private LocalDateTime modDate; // 수정일
}

@MappedSuperClass 어노테이션으로 인해 여기서 테이블이 생성되지 않고,
실제 테이블은 BaseEntity클래스를 상속한 Entity의 클래스로 DB 테이블이 생성된다.

Guestbook

@Entity // 테이블을 만드는 어노테이션
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Guestbook  extends BaseEntity {

    @Id // 기본키 설정 (자동 index 생성)
    @GeneratedValue(strategy = GenerationType.IDENTITY) //autoIncrement기능 자동으로 번호 증가 
    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;
    
    // 수정 할때 필요한 코드
    public void changeTitle(String title){
        this.title = title;
    }
    public void changeContent(String content){
        this.content = content;
    }
}

@Entity 클래스로 인해 테이블이 생성되고 이름을 지정하지 않으면 class 이름으로 생성된다.
JPA의 Table 생성 방법이다 ! 
SQL 중심의 개발에서 벗어나
객체 지향적인 코드를 지향한다.

GuestbookRepository

package org.zerock.guestbook.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
import org.zerock.guestbook.entity.Guestbook;

// JPA상속받아 CRUD기능이 가능하게 함 !
// Querydsl을 상속받아 동적 쿼리 처리도 보다 편하게 가능
public interface GuestbookRepository extends JpaRepository<Guestbook, Long>
, QuerydslPredicateExecutor<Guestbook>{
}

 

GuestbookDTO

@Builder
@NoArgsConstructor
@AllArgsConstructor
@Data
public class GuestbookDTO {

    private Long gno;
    private String title;
    private String content;
    private String writer;
    private LocalDateTime regDate, modDate;
}

 

GuestbookService

public interface GuestbookService {
	Long register(GuestbookDTO dto);
}

 

GuestbookServiceImpl

@Service  // 스프링 빈으로 처리되도록 어노테이션 부여
@Log4j2
@RequiredArgsConstructor
public class GuestbookServiceImpl implements GuestbookService{

    @Override
    public Long register(GuestbookDTO dto){
    	return null;
    }
}

 

여기까지가 기본적인 프로젝트 구조이다.