H2 x, MySQL로 연결 (application.properties 설정 , build.gradle 설정)
NEW Spring initializr 만들기

application.properties 설정 변경
server.port=9988
spring.datasource.url=jdbc:mysql://192.168.0.151/springbootboard_db
spring.datasource.username=root
spring.datasource.password=1234
#File Transfer Settings 파일 전송 사용 여부
spring.servlet.multipart.enabled=true
spring.servlet.multipart.max-file-size=100MB
spring.servlet.multipart.max-request-size=110MB
file.image.board=/home/soribada/img
# #최종적으로 src/main/resources/templates/ 경로를 의미
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
# 보기좋게 출력 system out 으로 보기 좋게 포맷팅하기 때문에 로그가 용량을 좀 더 차지함
spring.jpa.properties.hibernate.format_sql=true
# # hibernate logging info , logger로 출력
logging.level.org.hibernate.SQL=debug
build.gradle 설정 변경
plugins {
id 'java'
id 'war'
id 'org.springframework.boot' version '3.0.2'
id 'io.spring.dependency-management' version '1.1.0'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
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-jdbc'
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'
annotationProcessor 'org.projectlombok:lombok'
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.0'
implementation 'org.springframework.boot:spring-boot-starter-validation'
}
tasks.named('test') {
useJUnitPlatform()
}
Answer Entity 변경
package com.mysite.entity;
import java.time.LocalDateTime;
import jakarta.persistence.*;
import org.springframework.data.annotation.CreatedDate;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "answer")
public class Answer {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;
@Column(name = "content")
private String content;
@Column(name = "createDate")
private LocalDateTime createDate;
@JoinColumn(name = "questionId")
@ManyToOne(fetch = FetchType.LAZY)
private Question question;
}
Question Entity 변경
package com.mysite.entity;
import java.time.LocalDateTime;
import java.util.List;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "question")
public class Question {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;
@Column(name = "subject")
private String subject;
@Column(name = "content")
private String content;
@Column(name = "createDate")
private LocalDateTime createDate;
@OneToMany(mappedBy = "Question")
private List<Answer> answerList;
}
테이블 생성 Question & Answer
create table Question (
id Integer not null auto_increment primary key,
subject varchar(255) not null,
content text null,
createDate datetime not null
);
create table Answer (
id Integer not null auto_increment primary key,
content text null,
createDate datetime not null,
questionId Integer null
);
Repository 생성 _ 리포지터리
엔티티만으로는 데이터베이스에 데이터를 저장하거나 조회 할 수 없다. 데이터 처리를 위해서는 실제 데이터베이스와 연동하는 JPA 리포지터리가 필요하다.
리포지터리란?
리포지터리는 엔티티에 의해 생성된 데이터베이스 테이블에 접근하는 메서드들(예: findAll, save 등)을 사용하기 위한 인터페이스이다. 데이터 처리를 위해서는 테이블에 어떤 값을 넣거나 값을 조회하는 등의 CRUD(Create, Read, Update, Delete)가 필요하다. 이 때 이러한 CRUD를 어떻게 처리할지 정의하는 계층이 바로 리포지터리이다
리포지터리 생성
public interface AnswerRepository extends JpaRepository<Answer, Integer>{
}
public interface QuestionRepository extends JpaRepository<Question, Integer>{
}
테스트 코드 작성 실패
package com.mysite.SpringBootBoard;
import java.time.LocalDateTime;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import com.mysite.entity.Question;
import com.mysite.repository.QuestionRepository;
@SpringBootTest // 스프링부트 테스트 클래스
class SpringBootBoardApplicationTests {
@Autowired QuestionRepository questionRepository; // 리포지터리와 연결 (스프링의 DI기능)
@Test // 일단 테스트 실패
void testJpa() {
Question q1 = new Question();
q1.setId(1);
q1.setSubject("springbootboard?");
q1.setContent("SpringBootBoard 에 내용을 입력합니다.");
q1.setCreateDate(LocalDateTime.now());
questionRepository.save(q1);
Question q2 = new Question();
q2.setSubject("스프링부트test제목입력");
q2.setContent("ID는 자동으로 생성되나요?");
q2.setCreateDate(LocalDateTime.now());
this.questionRepository.save(q2);
}
}
오류 코드
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.mysite.SpringBootBoard.SpringBootBoardApplicationTests': Unsatisfied dependency expressed through field 'questionRepository': No qualifying bean of type 'com.mysite.repository.QuestionRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
엔티티에 추가함
@NoArgsConstructor | 파라미터가 없는 기본 생성자를 생성 |
@AllArgsConstructor | 모든 필드 값을 파라미터로 받는 생성자를 만듦 |
@RequiredArgsConstructor | final이나 @NonNull인 필드 값만 파라미터로 받는 생성자 만듦 |
@Data | @Getter/ @Setter, @ToString, @EqualsAndHashCode와 @RequiredArgsConstructor 를 합친 어노테이션 |
@NoArgsConstructor
@RequiredArgsConstructor
@AllArgsConstructor
public class User {
private Long id;
@NonNull
private String name;
@NonNull
private String pw;
private int age;
}
User user1 = new User(); // @NoArgsConstructor
User user2 = new User("user2", "1234"); // @RequiredArgsConstructor
User user3 = new User(1L, "user3", "1234", null); // @AllArgsConstructor
참고 블로그
[Lombok] @NoArgsConstructor , @AllArgsConstructor , @RequiredArgsConstructor
@NoArgsConstructor 파라미터가 없는 기본 생성자를 생성 @AllArgsConstructor 모든 필드 값을 파라미터로 받는 생성자를 만듦 @RequiredArgsConstructor final이나 @NonNull인 필드 값만 파라미터로 받는 생성자 만듦
athena7.tistory.com
Lombok
lombok 프로젝트 : 자바 라이브러리로 코드 에디터나 빌드툴(InteliJ, Eclipse, Vscode 등)에 추가하여 코드를 효율적으로 작성할 수 있도록 도와준다. class명 위에 어노테이션을 명시해줌으로써 getter, setter, equals 와 같은 method를 따로 작성하는 번거로움을 줄여줌.
@Data
@Getter/ @Setter, @ToString, @EqualsAndHashCode와 @RequiredArgsConstructor를 합친 어노테이션
참고 사이트 https://projectlombok.org/features/
Stable
projectlombok.org
참고 블로그
https://zi-c.tistory.com/entry/JAVA-Lombok-%EC%96%B4%EB%85%B8%ED%85%8C%EC%9D%B4%EC%85%98-Data
[JAVA] Lombok 어노테이션 @Data
Lombok이란? Lombok 프로젝트는 자바 라이브러리로 코드 에디터나 빌드 툴(IntelliJ, Eclipse, XCode 등)에 추가하여 코드를 효율적으로 작성할 수 있도록 도와준다. class명 위에 어노테이션을 명시해줌으
zi-c.tistory.com
'JAVA SPRING > SpringBoot' 카테고리의 다른 글
개인프로젝트 _ SpringBootBoard (2) (0) | 2023.05.01 |
---|---|
개인프로젝트 _ SpringBootBoard (1) (1) | 2023.04.11 |
SpringBootBoard) 점프 투 스프링부트 게시판 만들기 -2 (H2 설치 및 접속 & InteliJ 설정) (0) | 2023.03.31 |
SpringBootBoard) 점프 투 스프링부트 게시판 만들기 -1 (0) | 2023.03.30 |