프로젝트 구조
build.gradle
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "gradle.plugin.com.ewerk.gradle.plugins:querydsl-plugin:1.0.10"
}
}
plugins {
id 'java'
id 'war'
id 'org.springframework.boot' version '2.7.14'
id 'io.spring.dependency-management' version '1.1.2'
id 'com.ewerk.gradle.plugins.querydsl' version '1.0.10' // Querydsl 플러그인 추가
}
group = 'com.naya'
version = '0.0.1-SNAPSHOT'
java {
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'
runtimeOnly 'com.mysql:mysql-connector-j'
runtimeOnly 'org.mariadb.jdbc:mariadb-java-client'
annotationProcessor 'org.projectlombok:lombok'
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect'
//implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.5.6'
implementation 'javax.validation:validation-api'
implementation 'com.querydsl:querydsl-jpa:5.0.0'
}
def querydslDir = 'src/main/generated'
querydsl {
library = "com.querydsl:querydsl-apt"
jpa = true
querydslSourcesDir = querydslDir
}
sourceSets{
main{
java{
srcDirs = ['src/main/java', querydslDir]
}
}
}
compileQuerydsl{
options.annotationProcessorPath = configurations.querydsl
}
configurations {
querydsl.extendsFrom compileClasspath
}
tasks.named('test') {
useJUnitPlatform()
}
위 코드는 Gradle 빌드 스크립트 파일로, Spring Boot 프로젝트를 구성하는 데 사용됩니다.
Buildscript Dependencies: 이 섹션은 Gradle 빌드 스크립트에서 사용할 플러그인 및 의존성을 정의합니다. 여기에서는 com.ewerk.gradle.plugins.querydsl 플러그인을 추가하고 있습니다. 이 플러그인은 Querydsl을 프로젝트에 통합하는 데 도움을 줍니다.
Plugins: Spring Boot와 관련된 플러그인 및 버전을 설정합니다. 이 프로젝트에서는 Spring Boot 2.7.14 버전을 사용하고 있으며, io.spring.dependency-management 플러그인을 사용하여 의존성 관리를 설정하고 있습니다.
Project Information: 프로젝트 그룹, 버전 및 Java 소스 호환성을 설정합니다.
Configurations: 다양한 Gradle 구성을 정의합니다. 여기에서는 compileOnly 구성을 annotationProcessor에서 확장하고 있습니다.
Repositories: Maven 중앙 저장소에서 의존성을 다운로드 받을 수 있도록 설정합니다.
Dependencies: 프로젝트에서 사용하는 모든 의존성을 정의합니다. Spring Boot Starter, Thymeleaf, Lombok, MySQL, MariaDB 등과 같은 의존성을 추가하고 있습니다.
QueryDSL Configuration: Querydsl 관련 설정을 정의합니다. Querydsl을 사용하여 JPA 엔터티를 생성하기 위해 필요한 구성을 제공합니다. querydslDir 변수는 생성된 Querydsl 소스 코드가 위치하는 디렉토리를 지정합니다.
SourceSets: 메인 소스 세트를 정의하고, Querydsl 소스 코드 디렉토리를 메인 소스에 추가합니다.
CompileQuerydsl: Querydsl을 컴파일하는 데 필요한 옵션을 설정합니다.
Configurations: querydsl 구성을 compileClasspath에서 확장하도록 설정합니다.
Test Task Configuration: 테스트 실행을 위한 설정을 지정합니다.
이 스크립트는 Spring Boot 기반의 프로젝트를 구성하고, Querydsl을 사용하여 JPA 엔터티를 생성하고 쿼리를 작성할 수 있도록 설정하는 데 필요한 기본적인 구성을 포함하고 있습니다.
application.yml
server:
address: localhost
port: 8080
spring:
jpa:
show-sql: true
database: mysql
properties:
hibernate:
ddl-auto: create
format_sql: true
# create 기존 테이블 삭제 후 다시 생성
# create-drop create와 같음, 종료 시점에 테이블 drop
# update 변경분만 반영(운영 db 사용 x) -> 추가만됨, 지우는건 x
# validate 엔티티와 테이블이 매핑 되었는지 확인
# none 사용 x
# 개발 초기 create or update
# 테스트 서버 update or validate
# 운용 validate or none
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/dbname?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Seoul
username: username
password: password
thymeleaf:
cache: false
prefix: file:src/main/resources/templates/
suffix: .html
devtools:
restart:
enabled: true
위의 코드는 Spring Boot 애플리케이션의 설정 파일인 application.yml (또는 application.properties)의 내용을 나타냅니다. 이 설정 파일은 Spring Boot 애플리케이션의 동작 방식 및 환경 구성을 정의하는 데 사용됩니다.
Server Configuration:
server.address: 애플리케이션이 바인딩할 IP 주소를 지정합니다. 여기서는 localhost로 설정되어 로컬 호스트에서만 액세스할 수 있습니다.
server.port: 애플리케이션의 HTTP 포트를 지정합니다. 여기서는 8080으로 설정되어 8080번 포트에서 실행됩니다.
Spring Data JPA Configuration:
spring.jpa.database: 사용할 데이터베이스 종류를 설정합니다. 여기서는 MySQL을 사용하고 있습니다.
spring.jpa.hibernate.ddl-auto: Hibernate의 DDL 자동 생성 기능을 설정합니다. 여기서는 create로 설정되어 애플리케이션을 시작할 때마다 데이터베이스 스키마를 삭제하고 다시 생성합니다. 이 옵션은 주로 개발 및 테스트 단계에서 사용됩니다.
spring.jpa.hibernate.format_sql: SQL 쿼리를 예쁘게 출력할지 여부를 설정합니다. true로 설정되어 SQL 쿼리가 예쁘게 출력됩니다.
spring.jpa.show-sql: 쿼리를 로그로 출력할지 여부를 설정합니다. true로 설정되어 JPA가 실행하는 SQL 쿼리가 로그로 출력됩니다.
Thymeleaf Configuration:
thymeleaf.cache: Thymeleaf 템플릿 캐싱을 활성화 또는 비활성화합니다. false로 설정되어 템플릿 캐싱이 비활성화됩니다.
thymeleaf.prefix: Thymeleaf 템플릿 파일이 위치한 디렉토리를 지정합니다. 여기서는 상대 경로 file:src/main/resources/templates/로 설정되어 템플릿 파일이 src/main/resources/templates/ 디렉토리에 있다고 가정합니다.
thymeleaf.suffix: Thymeleaf 템플릿 파일의 확장자를 지정합니다. .html로 설정되어 HTML 템플릿 파일을 사용합니다.
Spring Boot DevTools Configuration:
devtools.restart.enabled: Spring Boot DevTools의 자동 재시작 기능을 활성화 또는 비활성화합니다. true로 설정되어 코드 변경 시 애플리케이션이 자동으로 재시작됩니다.
이러한 설정을 통해 Spring Boot 애플리케이션은 웹 서버의 주소와 포트를 구성하고, JPA와 Hibernate 설정을 지정하여 데이터베이스와의 상호작용을 관리하며, Thymeleaf를 사용하여 뷰 템플릿을 처리하며, 개발 도구를 통해 애플리케이션을 쉽게 개발하고 테스트할 수 있게 됩니다.
1. 엔티티 클래스 생성
먼저 두 개의 테이블과 매핑되는 엔티티 클래스를 생성합니다.
- Members.java
- Board.java
Members와 Board 테이블을 조인하려고 한다면 다음과 같은 엔티티 클래스를 생성할 수 있습니다.
Board.java
package com.jpatest.jpatest.entity;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import javax.persistence.*;
import java.time.LocalDateTime;
@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
public class Board {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "board_id")
private Long id; // 번호
private String title; // 제목
private String content; // 내용
@CreatedDate
private LocalDateTime regDate; // 등록일
@LastModifiedDate
private LocalDateTime uptDate; // 수정일
private Long viewCount; // 조회수
private String delYn; // 삭제 여부
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
private Members members;
@Builder
public Board(String title, String content, Members members) {
this.title = title;
this.content = content;
this.viewCount = 0L;
this.delYn = "N";
this.members = members;
this.regDate = LocalDateTime.now();
this.uptDate = LocalDateTime.now();
}
}
위의 코드는 JPA(Java Persistence API)를 사용하여 데이터베이스와 상호작용하는 데 사용되는 엔티티 클래스를 나타냅니다.
이 클래스는 게시판 게시물과 관련된 정보를 저장하는 데 사용됩니다.
@Entity: 이 어노테이션은 클래스가 JPA 엔티티임을 나타냅니다. JPA는 이 클래스와 데이터베이스 테이블을 매핑합니다.
@NoArgsConstructor(access = AccessLevel.PROTECTED): 이 어노테이션은 인자 없는 생성자를 생성합니다. AccessLevel.PROTECTED로 설정되어 외부에서 직접 생성되는 것을 방지하며, JPA는 프록시 객체를 생성할 때 이 생성자를 사용합니다.
@Getter: Lombok 프로젝트의 어노테이션으로, 게시물 엔티티 클래스의 필드에 대한 Getter 메서드를 자동으로 생성합니다.
@Id: 이 어노테이션은 엔티티 클래스의 기본 키(primary key)를 나타냅니다. @GeneratedValue 어노테이션과 함께 사용하여 자동으로 생성되는 값을 가지는 필드임을 지정합니다.
@GeneratedValue(strategy = GenerationType.IDENTITY): 이 어노테이션은 기본 키 값이 자동으로 생성되는 전략을 설정합니다. 여기서는 데이터베이스의 자동 증가(AUTO_INCREMENT) 기능을 사용하여 기본 키 값을 생성합니다.
@Column(name = "board_id"): 이 어노테이션은 엔티티 클래스의 필드와 데이터베이스 테이블의 컬럼 간 매핑을 지정합니다. name 속성은 데이터베이스 테이블의 컬럼 이름을 지정합니다.
나머지 필드들은 게시물 엔티티의 속성을 나타냅니다. 각각의 의미는 다음과 같습니다:
title: 게시물의 제목을 나타내는 문자열 필드.
content: 게시물의 내용을 나타내는 문자열 필드.
regDate: 게시물의 등록일을 나타내는 LocalDateTime 필드.
uptDate: 게시물의 수정일을 나타내는 LocalDateTime 필드.
viewCount: 게시물의 조회수를 나타내는 Long 필드.
delYn: 게시물의 삭제 여부를 나타내는 문자열 필드.
members: 회원과 게시물 간의 다대일(N:1) 관계를 나타내는 필드. @ManyToOne 어노테이션을 사용하여 매핑되며, @JoinColumn 어노테이션을 통해 외래 키를 지정합니다.
@Builder: Lombok 프로젝트의 어노테이션으로, 빌더 패턴을 자동으로 생성합니다.
이를 통해 객체를 생성할 때 가독성 있고 유연한 방식으로 객체를 초기화할 수 있습니다.
Members 객체와 관련된 필드만 설정하고 나머지 필드는 기본값으로 초기화됩니다.
이 클래스는 게시판 게시물과 관련된 정보를 저장하고, 데이터베이스와의 상호작용을 위한 JPA 엔티티로 사용됩니다.
Members.java
package com.jpatest.jpatest.entity;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
public class Members {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "member_id")
private Long id;
private String username;
private String password;
private String phoneNo;
private int age;
@OneToMany(mappedBy = "members")
private List<Board> boardList = new ArrayList<>();
@Builder
public Members(String username, int age) {
this.username = username;
this.age = age;
}
}
위의 코드는 JPA(Java Persistence API)를 사용하여 데이터베이스와 상호작용하는 데 사용되는 Members 엔티티 클래스를 나타냅니다. 이 클래스는 회원 정보를 저장하는 데 사용됩니다.
@Entity: 이 어노테이션은 클래스가 JPA 엔티티임을 나타냅니다. JPA는 이 클래스와 데이터베이스 테이블을 매핑합니다.
@NoArgsConstructor(access = AccessLevel.PROTECTED): 이 어노테이션은 인자 없는 생성자를 생성합니다. AccessLevel.PROTECTED로 설정되어 외부에서 직접 생성되는 것을 방지하며, JPA는 프록시 객체를 생성할 때 이 생성자를 사용합니다.
@Getter: Lombok 프로젝트의 어노테이션으로, Members 엔티티 클래스의 필드에 대한 Getter 메서드를 자동으로 생성합니다.
@Id: 이 어노테이션은 엔티티 클래스의 기본 키(primary key)를 나타냅니다. @GeneratedValue 어노테이션과 함께 사용하여 자동으로 생성되는 값을 가지는 필드임을 지정합니다.
@GeneratedValue(strategy = GenerationType.IDENTITY): 이 어노테이션은 기본 키 값이 자동으로 생성되는 전략을 설정합니다. 여기서는 데이터베이스의 자동 증가(AUTO_INCREMENT) 기능을 사용하여 기본 키 값을 생성합니다.
@Column(name = "member_id"): 이 어노테이션은 엔티티 클래스의 필드와 데이터베이스 테이블의 컬럼 간 매핑을 지정합니다. name 속성은 데이터베이스 테이블의 컬럼 이름을 지정합니다.
나머지 필드들은 회원 엔티티 클래스의 속성을 나타냅니다. 각각의 의미는 다음과 같습니다:
username: 회원의 이름을 나타내는 문자열 필드.
password: 회원의 비밀번호를 나타내는 문자열 필드.
phoneNo: 회원의 전화번호를 나타내는 문자열 필드.
age: 회원의 나이를 나타내는 정수 필드.
boardList: 회원과 게시물 간의 일대다(1:N) 관계를 나타내는 필드. @OneToMany 어노테이션을 사용하여 매핑되며, mappedBy 속성을 통해 관계의 주인을 설정합니다.
@Builder: Lombok 프로젝트의 어노테이션으로, 빌더 패턴을 자동으로 생성합니다. 이를 통해 객체를 생성할 때 가독성 있고 유연한 방식으로 객체를 초기화할 수 있습니다. Members 객체와 관련된 필드만 설정하고 나머지 필드는 기본값으로 초기화됩니다.
이 클래스는 회원 정보를 저장하고, 데이터베이스와의 상호작용을 위한 JPA 엔티티로 사용됩니다.
2. Repository 인터페이스 생성
각 엔티티에 대한 Repository 인터페이스를 생성합니다.
BoardRepository.java
package com.jpatest.jpatest.repository;
import com.jpatest.jpatest.entity.Board;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface BoardRepository extends JpaRepository<Board, Long> {
}
MemberRepository.java
package com.jpatest.jpatest.repository;
import com.jpatest.jpatest.entity.Members;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface MemberRepository extends JpaRepository<Members, Long> {
}
위 코드는 Spring Data JPA를 사용하여 데이터베이스와 상호작용하기 위한 두 개의 리포지토리 인터페이스인 BoardRepository와 MemberRepository를 정의하고 있습니다.
BoardRepository:
JpaRepository<Board, Long>를 확장하고 있습니다. 이는 Spring Data JPA에서 제공하는 JpaRepository를 활용하여 Board 엔티티에 대한 데이터 액세스를 위한 메서드들을 제공합니다.
@Repository 어노테이션은 Spring에게 이 인터페이스가 리포지토리 역할을 하는 빈(bean)임을 알려줍니다. Spring은 이 빈을 자동으로 생성하고 관리합니다.
Board 엔티티와 관련된 CRUD(Create, Read, Update, Delete) 및 데이터베이스 조작 작업을 위한 메서드를 JpaRepository에서 상속받아 사용할 수 있습니다.
MemberRepository:
JpaRepository<Members, Long>를 확장하고 있습니다. 이는 Spring Data JPA에서 제공하는 JpaRepository를 활용하여 Members 엔티티에 대한 데이터 액세스를 위한 메서드들을 제공합니다.
@Repository 어노테이션은 Spring에게 이 인터페이스가 리포지토리 역할을 하는 빈(bean)임을 알려줍니다. Spring은 이 빈을 자동으로 생성하고 관리합니다.
Members 엔티티와 관련된 CRUD(Create, Read, Update, Delete) 및 데이터베이스 조작 작업을 위한 메서드를 JpaRepository에서 상속받아 사용할 수 있습니다.
이렇게 정의된 리포지토리 인터페이스들을 사용하면 데이터베이스와의 상호작용을 위한 코드를 직접 작성하지 않고, JpaRepository에서 제공하는 메서드들을 활용하여 데이터를 쉽게 읽고 쓸 수 있습니다. Spring Data JPA는 개발자들이 데이터 액세스 작업을 훨씬 편리하게 처리할 수 있도록 도와줍니다.
3. controller 생성
- BoardController.java
package com.jpatest.jpatest.controller;
import com.jpatest.jpatest.dto.BoardDto;
import com.jpatest.jpatest.dto.MemberDto;
import com.jpatest.jpatest.entity.Board;
import com.jpatest.jpatest.entity.Members;
import com.jpatest.jpatest.repository.BoardRepository;
import com.jpatest.jpatest.repository.MemberRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.List;
@Controller
public class BoardController {
@Autowired
BoardRepository boardRepository;
@Autowired
MemberRepository memberRepository;
@GetMapping("/add_member")
public String addMember(){
String username = "지화자";
int age = 20;
Members members = Members.builder()
.username(username)
.age(age)
.build();
memberRepository.save(members);
return "board/list";
}
@GetMapping("/add_member_dto")
public String addMemberDto(){
String username = "문지방";
int age = 25;
MemberDto memberDto = new MemberDto(username, age);
Members members = memberDto.toEntity();
memberRepository.save(members);
return "board/list";
}
@GetMapping("/add_board")
public String addBoard(){
String title = "타이틀이지1";
String content = "내용1";
List<Members> membersList = memberRepository.findAll();
Members members = membersList.get(0);
Board board = Board.builder()
.title(title)
.content(content)
.members(members)
.build();
boardRepository.save(board);
return "board/list";
}
@GetMapping("/add_board_dto")
public String addBoardDto(){
String title = "타이틀이지1";
String content = "내용1";
List<Members> membersList = memberRepository.findAll();
Members members = membersList.get(0);
BoardDto boardDto = new BoardDto(title, content);
Board board = boardDto.toEntity(members);
boardRepository.save(board);
return "board/list";
}
}
위 코드는 Spring Boot 애플리케이션에서 웹 요청을 처리하는 BoardController 클래스를 정의하고 있습니다. 이 컨트롤러는 회원과 게시판 데이터를 생성하고 관리하기 위한 다양한 엔드포인트를 제공합니다.
@Controller 어노테이션:
이 클래스가 컨트롤러 역할을 하는 것을 나타내며 Spring에 의해 관리되는 빈(bean)으로 등록됩니다.
@Autowired 어노테이션:
의존성 주입을 통해 BoardRepository와 MemberRepository 빈을 주입받습니다.
/add_member 엔드포인트:
회원 데이터를 추가하는 엔드포인트입니다.
회원의 이름과 나이를 받아 Members 엔티티를 생성하고 저장합니다.
/add_member_dto 엔드포인트:
회원 데이터를 추가하는 엔드포인트입니다.
회원의 이름과 나이를 MemberDto 객체를 통해 받아와서 Members 엔티티로 변환하여 저장합니다.
DTO(Data Transfer Object) 패턴을 사용하여 데이터 전송과 관련된 작업을 처리합니다.
/add_board 엔드포인트:
게시판 데이터를 추가하는 엔드포인트입니다.
게시글의 제목과 내용을 받아와서, 회원 데이터를 조회한 후 Board 엔티티를 생성하고 저장합니다.
/add_board_dto 엔드포인트:
게시판 데이터를 추가하는 엔드포인트입니다.
게시글의 제목과 내용을 BoardDto 객체를 통해 받아와서, 회원 데이터를 조회한 후 Board 엔티티로 변환하여 저장합니다.
DTO(Data Transfer Object) 패턴을 사용하여 데이터 전송과 관련된 작업을 처리합니다.
각 엔드포인트는 클라이언트의 요청을 받아 해당 동작을 수행하고, 그 결과로 "board/list" 뷰 페이지를 반환합니다. 이렇게 구현된 컨트롤러를 통해 웹 애플리케이션에서 회원과 게시글을 추가할 수 있게 됩니다.
4. DTO 생성
- BoardDto
- MemberDto
BoardDto.java
package com.jpatest.jpatest.dto;
import com.jpatest.jpatest.entity.Board;
import com.jpatest.jpatest.entity.Members;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class BoardDto {
private Long id;
private String title;
private String content;
private Long viewCount;
private LocalDateTime redDate;
private LocalDateTime uptDate;
public BoardDto(String title, String content) {
this.title = title;
this.content = content;
}
public Board toEntity(Members members) {
return Board.builder()
.title(title)
.content(content)
.members(members)
.build();
}
}
위 코드는 데이터 전송 객체(Data Transfer Object, DTO)를 정의한 클래스인 BoardDto를 나타냅니다. DTO는 주로 데이터의 전달과 관련된 역할을 하는 객체로, 엔티티 클래스와 웹 뷰 간 데이터 전달을 쉽게 하기 위해 사용됩니다.
@Data 어노테이션:
Lombok 라이브러리를 사용하여 Getter, Setter, equals, hashCode, toString 등의 메서드를 자동으로 생성합니다.
멤버 변수:
id: 게시글의 고유 식별자
title: 게시글의 제목
content: 게시글의 내용
viewCount: 조회수
redDate: 등록 날짜
uptDate: 수정 날짜
생성자:
BoardDto(String title, String content): 제목과 내용을 매개변수로 받는 생성자입니다.
toEntity 메서드:
Members 엔티티를 매개변수로 받아서, Board 엔티티로 변환하여 반환하는 메서드입니다.
Board 엔티티를 빌더 패턴을 사용하여 생성하고, title, content, 그리고 받아온 members를 설정한 후 엔티티를 반환합니다.
이렇게 정의된 BoardDto 클래스는 주로 웹 요청에서 받은 데이터를 가공하거나 엔티티로 변환하는 데 사용됩니다. 예를 들어, 웹 폼에서 입력한 데이터를 BoardDto 객체로 수신하고, 이를 toEntity 메서드를 통해 Board 엔티티로 변환하여 JPA를 사용하여 데이터베이스에 저장할 수 있습니다.
MemberDto.java
package com.jpatest.jpatest.dto;
import com.jpatest.jpatest.entity.Members;
import lombok.Data;
@Data
public class MemberDto {
private Long id;
private String username;
private String password;
private String phoneNo;
private int age;
public MemberDto(String username, int age) {
this.username = username;
this.age = age;
}
public Members toEntity() {
return Members.builder()
.username(username)
.age(age)
.build();
}
}
위 코드는 데이터 전송 객체(Data Transfer Object, DTO)를 정의한 클래스인 MemberDto를 나타냅니다. DTO는 주로 데이터의 전달과 관련된 역할을 하는 객체로, 엔티티 클래스와 웹 뷰 간 데이터 전달을 쉽게 하기 위해 사용됩니다.
@Data 어노테이션:
Lombok 라이브러리를 사용하여 Getter, Setter, equals, hashCode, toString 등의 메서드를 자동으로 생성합니다.
멤버 변수:
id: 회원의 고유 식별자
username: 회원의 이름 또는 사용자명
password: 회원의 비밀번호
phoneNo: 회원의 전화번호
age: 회원의 나이
생성자:
MemberDto(String username, int age): 사용자명(username)과 나이(age)를 매개변수로 받는 생성자입니다.
toEntity 메서드:
Members 엔티티로 변환하는 메서드입니다.
Members 엔티티를 빌더 패턴을 사용하여 생성하고, 받아온 username과 age를 설정한 후 엔티티를 반환합니다.
이렇게 정의된 MemberDto 클래스는 주로 웹 요청에서 받은 데이터를 가공하거나 엔티티로 변환하는 데 사용됩니다. 예를 들어, 웹 폼에서 입력한 회원 정보 데이터를 MemberDto 객체로 수신하고, 이를 toEntity 메서드를 통해 Members 엔티티로 변환하여 JPA를 사용하여 데이터베이스에 저장할 수 있습니다.
5. 웹서버 시작시 테이블 과 데이터 자동 생성
아래 경로에 insert 쿼리문 만들어 저장합니다.
resources/import.sql
INSERT INTO members (username, age, phone_no) VALUES('사용자1','31','016-2222-2222');
INSERT INTO members (username, age, phone_no) VALUES('사용자2','32','016-2222-2222');
INSERT INTO members (username, age, phone_no) VALUES('사용자3','33','016-2222-2222');
INSERT INTO members (username, age, phone_no) VALUES('사용자4','34','016-2222-2222');
INSERT INTO members (username, age, phone_no) VALUES('사용자5','35','017-2222-2222');
INSERT INTO members (username, age, phone_no) VALUES('사용자6','36','018-2222-2222');
INSERT INTO members (username, age, phone_no) VALUES('사용자7','46','019-2222-2222');
6. Talend API tester 로 확인
참고 https://aamoos.tistory.com/671?category=856312
Controller 의 비지니스 로직을 Service 로 이동해본다.
프로젝트 구조
BoardController.java
package com.jpatest.jpatest.controller;
import com.jpatest.jpatest.service.BoardService;
import com.jpatest.jpatest.service.MemberService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class BoardController {
private final BoardService boardService;
private final MemberService memberService;
public BoardController(BoardService boardService, MemberService memberService) {
this.boardService = boardService;
this.memberService = memberService;
}
@GetMapping("/add_member")
public String addMember(){
memberService.write();
return "board/list";
}
@GetMapping("/add_member_dto")
public String addMemberDto(){
memberService.writeDto();
return "board/list";
}
@GetMapping("/add_board")
public String addBoard(){
boardService.write();
return "board/list";
}
@GetMapping("/add_board_dto")
public String addBoardDto(){
boardService.writeDto();
return "board/list";
}
}
package com.jpatest.jpatest.service;
public interface BoardService {
void write();
void writeDto();
}
package com.jpatest.jpatest.service;
import com.jpatest.jpatest.dto.BoardDto;
import com.jpatest.jpatest.dto.MemberDto;
import com.jpatest.jpatest.entity.Board;
import com.jpatest.jpatest.entity.Members;
import com.jpatest.jpatest.repository.BoardRepository;
import com.jpatest.jpatest.repository.MemberRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class BoardServiceImpl implements BoardService {
@Autowired
BoardRepository boardRepository;
@Autowired
MemberRepository memberRepository;
@Override
public void write() {
String title = "타이틀이지1";
String content = "내용1";
List<Members> membersList = memberRepository.findAll();
Members members = membersList.get(0);
Board board = Board.builder()
.title(title)
.content(content)
.members(members)
.build();
boardRepository.save(board);
}
@Override
public void writeDto() {
String title = "타이틀이지77";
String content = "내용77";
List<Members> membersList = memberRepository.findAll();
Members members = membersList.get(0);
BoardDto boardDto = new BoardDto(title, content);
Board board = boardDto.toEntity(members);
boardRepository.save(board);
}
}
package com.jpatest.jpatest.service;
public interface MemberService {
void write();
void writeDto();
}
package com.jpatest.jpatest.service;
import com.jpatest.jpatest.dto.MemberDto;
import com.jpatest.jpatest.entity.Members;
import com.jpatest.jpatest.repository.BoardRepository;
import com.jpatest.jpatest.repository.MemberRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class MemberServiceImpl implements MemberService {
@Autowired
BoardRepository boardRepository;
@Autowired
MemberRepository memberRepository;
@Override
public void write() {
String username = "지화자";
int age = 20;
Members members = Members.builder()
.username(username)
.age(age)
.build();
memberRepository.save(members);
}
@Override
public void writeDto() {
String username = "문지방";
int age = 25;
MemberDto memberDto = new MemberDto(username, age);
Members members = memberDto.toEntity();
memberRepository.save(members);
}
}
'프로그래밍 > Java' 카테고리의 다른 글
인텔리제이 2020.3 에서 java 17 -> java 11 spring boot 3 -> 2 (0) | 2024.08.12 |
---|---|
[spring boot JPA] object references an unsaved transient instance - save the transient instance before flushing 오류 원인 (0) | 2023.08.25 |
spring boot 와 JPA 사용한 프로젝트 전체 구조 (0) | 2023.08.23 |
IntelliJ 이용하여 스프링 부트 + JPA + Mysql + thymleaf 게시판 CRUD (0) | 2023.08.23 |
IntelliJ 이용하여 스프링 부트 + JPA + Mysql 간단한 예제 (0) | 2023.08.22 |