- application, build.gradle 설정
디자인 제작
- 정적 html 제작
- 화면에 맞춰 DB 설계
스프링 부트 세팅
3. 화면에 맞춰 controller 제작
4. 테이블에 맞춰 entity 제작
5. entity 맞춰 repository 제작
6. service로 화면에 필요한 작업 및 데이터 생성
7. controller에서 service 결과 받아서 화면에 뿌리기
application은 yml과 properties 두 가지로 설정 가능
보통은 yml을 많이 사용한다.
build.gradle에서 dependencies 마리아DB 설정 후 우클릭하여 리로드 필수
spring:
thymeleaf:
cache: false
datasource:
url: jdbc:mariadb://localhost:3306/hr
driverClassName: org.mariadb.jdbc.Driver
username: root
password: 1234
jpa:
defer-datasource-initialization: true
open-in-view: false # 트랜잭션 범위 밖에서 영속성 컨텍스트를 유지할지 여부
database-platform: org.hibernate.dialect.MariaDBDialect
hibernate:
ddl-auto: none # create-drop, update, validate, none
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
implicit-strategy: org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
show-sql: true
properties:
hibernate:
format_sql: true
servlet:
multipart:
max-request-size: 10MB
max-file-size: 10MB
plugins {
id 'java'
id 'org.springframework.boot' version '3.1.1'
id 'io.spring.dependency-management' version '1.1.0'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
java {
sourceCompatibility = '17'
}
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'
runtimeOnly 'org.mariadb.jdbc:mariadb-java-client'
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.named('test') {
useJUnitPlatform()
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.x-button {
background-color: whitesmoke;
color: red;
font-weight: 600;
cursor: pointer;
}
</style>
<title>Document</title>
</head>
<body>
<div>
<input type="text" placeholder="새 지역">
<button>추가</button>
</div>
<div>
<ul>
<li>
<span>1. 유럽</span>
<span class="x-button">X</span>
</li>
<li>
<span>2. 아시아</span>
<span class="x-button">X</span>
</li>
<li>
<span>3. 아메리카</span>
<span class="x-button">X</span>
</li>
</ul>
</div>
</body>
</html>
package com.example.hr1.domain.main.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;
import com.example.hr1.domain.main.dto.ResMainDTO;
import com.example.hr1.domain.main.service.MainService;
@Controller
public class MainController {
// /(루트)에 접근 시 경로
@GetMapping("/")
// Mapping을 기반으로 함수를 실행 시키기 때문에
// controller의 함수 이름은 중요하지 않다
public ModelAndView mainPage(){
ModelAndView modelAndView = new ModelAndView();
// template 폴더 안에 main/main 위치로 보냄
modelAndView.setViewName("main/main");
return modelAndView;
}
}
package com.example.hr1.model.regions.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
// DB 테이블명 + Entity
// 엔티티임을 명시
@Entity
// DB의 테이블과 연동
@Table(name = "regions")
@NoArgsConstructor
@AllArgsConstructor
@Getter
// 엔티티에서 setter는 꼭 필요할 때만, 직접 만드는 것 추천
// toString도 직접 만드는 것 추천
public class RegionsEntity {
// 기본키(PK)에 @Id를 붙임
@Id
// DB의 컬럼명과 연동
// 컬럼의 속성을 맞춰주는 것이 좋다
@Column(name = "region_id", nullable = false, unique = true)
private Integer regionId;
// nullable : default = true
// unique : default = false
@Column(name = "region_name")
private String regionName;
@Override
public String toString() {
return "RegionsEntity [regionId=" + regionId + ", regionName=" + regionName + "]";
}
}
package com.example.hr1.model.regions.repository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.example.hr1.model.regions.entity.RegionsEntity;
@Repository
public interface RegionsRepository extends JpaRepository<RegionsEntity, Integer>{
// 기본적으로 findAll() 메소드가 내장되어 있어
// 아무것도 생성하지 않아도 전부 찾아오기는 가능
// 메소드 이름을 인식하여 자동으로 만들어줌
// 특정 엔티티 단일 데이터 가져오기
// select * from regions where region_id = ?
RegionsEntity findByRegionId(Integer regionID);
// region_name으로 데이터 가져오기
// RegionsEntity findByRegionName(String regionName);
// region_name은 유니크 속성이 false이기 때문에 여러개를 가져올 수 있다
// List 타입으로 가져와야 함
List<RegionsEntity> findByRegionName(String regionName);
// region_id와 region_name이 둘 다 조건에 맞을 때 == 단일 값
// find : select * from regions
// by : where
// and : and
RegionsEntity findByRegionIdAndRegionName(Integer regionID, String regionName);
}
package com.example.hr1.domain.main.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.hr1.domain.main.dto.ResMainDTO;
import com.example.hr1.model.regions.entity.RegionsEntity;
import com.example.hr1.model.regions.repository.RegionsRepository;
// 약속
// entity 객체는 Service에서 빠져나가지 못한다
// entity -> dto
@Service
public class MainService {
// IoC 컨테이너에서 RegionsRepository 타입의 객체를 가져옴
// 의존성 주입 DI
@Autowired
private RegionsRepository regionsRepository;
// 데이터를 한꺼번에 담아서 넘겨주기 위해 Entity를 DTO로 바꾸는 메소드
public List<ResMainDTO> getMainPageData(){
List<RegionsEntity> regionsEntityList = regionsRepository.findAll();
List<ResMainDTO> resMainDTOList = regionsEntityList
.stream()
.map((regionsEntity) -> ResMainDTO.fromEntity(regionsEntity))
.toList();
return resMainDTOList;
// return regionsEntityList;
}
}
package com.example.hr1.domain.main.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;
import com.example.hr1.domain.main.dto.ResMainDTO;
import com.example.hr1.domain.main.service.MainService;
@Controller
public class MainController {
// 후에 작성할 MainService (Entity -> DTO)
@Autowired
private MainService mainService;
@GetMapping("/")
// Mapping을 기반으로 함수를 실행 시키기 때문에
// controller의 함수 이름은 중요하지 않다
public ModelAndView mainPage(){
ModelAndView modelAndView = new ModelAndView();
List<ResMainDTO> resMainDTOList = mainService.getMainPageData();
// html로 값 넘겨주기
modelAndView.addObject("resMainDTOList", resMainDTOList);
modelAndView.setViewName("main/main");
return modelAndView;
}
}
/ (메인페이지)
DB에서 유저의 id와 이름을 받아와 출력
/post
DB에서 게시물 정보를 받아와 출력
링크
https://drive.google.com/file/d/1c_SPZlj4Vs2pScsL_4MAryItxN9Y3FCY/view?usp=drive_link
Entity를 만들 때 DB와 연동할 수 있는 어노테이션
@Id, @Column등을 사용할 수 있게 만들어주는 라이브러리
스프링 2버전에서는 javax를 사용했지만,
3버전 부터는 jakarta를 사용
RegionsEntity.java
package com.example.hr1.model.regions.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
// DB 테이블명 + Entity
// 엔티티임을 명시
@Entity
// DB의 테이블과 연동
@Table(name = "regions")
@NoArgsConstructor
@AllArgsConstructor
@Getter
// 엔티티에서 setter는 꼭 필요할 때만, 직접 만드는 것 추천
// toString도 직접 만드는 것 추천
public class RegionsEntity {
// 기본키(PK)에 @Id를 붙임
@Id
// DB의 컬럼명과 연동
// 컬럼의 속성을 맞춰주는 것이 좋다
@Column(name = "region_id", nullable = false, unique = true)
private Integer regionId;
// nullable : default = true
// unique : default = false
@Column(name = "region_name")
private String regionName;
@Override
public String toString() {
return "RegionsEntity [regionId=" + regionId + ", regionName=" + regionName + "]";
}
}