springBoot_개념_Day_15
1.propertis
spring.jpa.hibernate.ddl-auto=update 무슨의미인가요?
#이 설정은 Hibernate가 애플리케이션 시작 시에 데이터베이스 스키마를 자동으로 갱신합니다.
#이전에 생성된 테이블이나 인덱스를 유지하면서 새로운 필드나 제약 조건을 추가합니다.
#단, 변경 사항이 테이블을 삭제하거나 데이터를 삭제하는 것을 초래하지 않도록 주의해야 합니다.
#spring.jpa.hibernate.ddl-auto=create:
#이 설정은 Hibernate가 애플리케이션 시작 시에 데이터베이스 스키마를 자동으로 생성합니다.
#기존의 데이터베이스가 존재하면 해당 데이터베이스를 삭제하고 새로운 스키마를 생성합니다.
#따라서 애플리케이션을 다시 시작할 때마다 데이터베이스의 내용이 손실될 수 있으므로 주의해야 합니다.
#이 두 옵션은 개발 및 ★★★테스트 환경★에서 유용하지만,
# 프로덕션 환경에서는 권장되지 않습니다. 프로덕션 환경에서는 데이터베이스 스키마를 수동으로 관리하고 변경 사항을 신중하게 적용해야 합니다.
참고 :
# spring.jpa.hibernate.ddl-auto=update대신해서 실제서비스할떄 사용하는 법
#spring.jpa.hibernate.ddl-auto=validate:
#Hibernate가 애플리케이션 시작 시에 데이터베이스 스키마를 검증합니다. 데이터베이스에 대한 매핑이 유효한지 확인하지만, 스키마를 갱신하거나 수정하지는 않습니다. 이 옵션은 프로덕션 환경에서 사용하기에 적합합니다.
#spring.jpa.hibernate.ddl-auto=none:
#Hibernate가 애플리케이션 시작 시에 데이터베이스 스키마를 조작하지 않도록 합니다. 따라서 Hibernate는 데이터베이스 스키마에 대한 어떠한 변경도 시도하지 않습니다. 이 옵션은 프로덕션 환경에서 가장 안전한 옵션 중 하나입니다. 다만, 새로운 엔티티나 필드를 추가할 때는 반드시 수동으로 데이터베이스 스키마를 업데이트해야 합니다.
#일반적으로 프로덕션 환경에서는 validate 또는 none을 사용하는 것이 좋습니다. 또한, 데이터베이스 관리 도구를 사용하여 스키마를 수동으로 관리하는 것도 권장됩니다.
#
2.레파지토리에서 테스트를 만드는이유는?
답변: 레포지토리에서 테스트를 작성하는 이유는 주로 다음과 같습니다:
데이터베이스 상호작용 테스트: 레포지토리는 데이터베이스와의 상호작용을 담당하므로, 해당 동작을 테스트해야 합니다. 데이터베이스에 데이터를 생성, 읽기, 업데이트, 삭제하는 메서드들이 제대로 동작하는지 확인합니다.
JPA 및 Spring Data JPA 테스트: Spring Boot에서는 JPA와 Spring Data JPA를 사용하여 데이터베이스를 다룹니다. 이러한 기술들의 기능을 테스트하여 올바르게 구현되었는지 확인합니다.
비즈니스 로직 테스트 지원: 레포지토리는 종종 비즈니스 로직에서 데이터베이스와의 상호작용을 호출하는데 사용됩니다. 따라서 레포지토리의 동작이 비즈니스 로직에 올바르게 통합되는지를 확인하기 위해 테스트가 필요합니다.
애플리케이션의 전반적인 테스트 커버리지 향상: 레포지토리의 테스트를 추가함으로써 애플리케이션의 전반적인 테스트 커버리지를 향상시킬 수 있습니다. 이는 애플리케이션의 신뢰성을 높이고 버그를 미리 발견하는 데 도움이 됩니다.
따라서 Spring Boot 애플리케이션에서는 레포지토리에서의 테스트가 중요한 부분을 차지하며, 일반적으로 단위 테스트와 통합 테스트를 모두 포함하여 레포지토리의 동작을 검증합니다.
3.어노테이션(Builer Vs setter) 의 차이
Spring Boot에서 @Builder와 @Setter는 객체 생성과 초기화에 사용되는 어노테이션입니다. 이 둘의 주요 차이점은 다음과 같습니다:
- @Builder:
- @Setter:
따라서, @Builder는 객체를 생성하고 초기화하는 데 사용되며, @Setter는 객체의 상태를 변경하는 데 사용됩니다. 일반적으로 @Builder는 객체 생성 시에 사용되고, @Setter는 객체 생성 이후에 필요한 경우에 사용됩니다.
4.DiffChecker를 사용하는 이유?
DiffChecker를 사용하는 이유는 코드나 텍스트의 변경 사항을 시각적으로 비교하여 확인할 수 있기 때문입니다. DiffChecker는 주로 다음과 같은 상황에서 사용됩니다:
- 코드 리뷰: 개발자들은 DiffChecker를 사용하여 코드 변경 사항을 리뷰하고 검토합니다. 두 개의 코드 버전을 비교하여 추가된, 수정된 또는 삭제된 부분을 쉽게 식별할 수 있습니다.
- 패치 파일 확인: 코드 변경 사항을 담은 패치 파일이나 diff 파일을 생성할 때, DiffChecker를 사용하여 변경된 내용을 확인하고 적용하기 전에 검토할 수 있습니다.
- 문서 비교: 문서나 텍스트 파일의 변경 사항을 비교하고 확인할 때 사용됩니다. 두 버전의 문서를 비교하여 수정된 내용을 확인하거나, 문서 간의 차이점을 분석할 수 있습니다.
- 버전 관리 시스템과의 통합: 버전 관리 시스템(예: Git)에서 변경된 코드를 비교하거나 병합하기 전에 DiffChecker를 사용하여 변경 내용을 확인할 수 있습니다.
- 프로그래밍 대회 및 알고리즘 문제 해결: 프로그래밍 대회나 알고리즘 문제 해결 시에는 주로 출력 결과나 코드 변경 사항을 비교하여 확인해야 합니다. 이때 DiffChecker를 사용하여 예상한 결과와 실제 결과를 비교하거나, 코드 변경 사항을 분석할 수 있습니다.
5.스프링부트레거시
스프링 부트 레거시라는 용어는 일반적으로 "스프링 부트"와 "레거시 시스템"이 결합된 상황을 가리킵니다. 여기서 "레거시 시스템"은 과거에 개발된 시스템을 나타내며, 스프링 부트와 함께 사용되는 것을 의미합니다.
6.비즈니스로직
- 비즈니스 로직:
ㅡㅡㅡ
1
2
3
4
5
6
7
8
ㅡㅡㅡ
●1.
시큐리티 버전차이
#그래이들 - 셋팅
#깃 쓰는 것
#빌드설정(pom.xml과 같은 것)
ㅡconfirgurations : 런타임(프로그램실행하는 중)동안에는 이녀석이 포함되지 않고, 컴파일할시에만포함되고, 런타임이 포함되지 않습니다.
(컴파일에 필요한 의존관계만 설정)
ㅡ레포지토리
implementaion : 프로젝트 코드가 컴파일 시점과 런타임에 모두 해당 라이브러리를 필요로 할때 사용
runtimeOnly : 런타임에만 필요의존성을 지정
annotationProcessor : 컴파일 시에 어노테이션을 처리할때 사용하는 도구의 의존성지정
testImplementation : 테스트 코드에서만 사용
★build.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '3.1.11'
id 'io.spring.dependency-management' version '1.1.4'
}
group = 'com'
version = '0.0.1-SNAPSHOT'
java {
sourceCompatibility = '17'
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
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'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testCompileOnly 'org.projectlombok:lombok'
testAnnotationProcessor 'org.projectlombok:lombok'
}
tasks.named('bootBuildImage') {
builder = 'paketobuildpacks/builder-jammy-base:latest'
}
tasks.named('test') {
useJUnitPlatform()
}
#빌드할 프로젝트 정보를 가지고 있습니다.
#그래이들 리셋방법( 이것을 통해서 , 그래이들이 오류가 생겼을때, 잡을수 있습니다.)
#야물
계층 : 들여쓰기,
콜론 : 한칸을 띄우기
★application.properties
spring.application.name=shopapi
server.port=8080
#mysql
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/shopapidb?serverTimezone=Asia/Seoul
spring.datasource.username=user01
spring.datasource.password=my1234
spring.jpa.hibernate.ddl-auto=update
#이 설정은 Hibernate가 애플리케이션 시작 시에 데이터베이스 스키마를 자동으로 갱신합니다.
#이전에 생성된 테이블이나 인덱스를 유지하면서 새로운 필드나 제약 조건을 추가합니다.
#단, 변경 사항이 테이블을 삭제하거나 데이터를 삭제하는 것을 초래하지 않도록 주의해야 합니다.
#spring.jpa.hibernate.ddl-auto=create:
#이 설정은 Hibernate가 애플리케이션 시작 시에 데이터베이스 스키마를 자동으로 생성합니다.
#기존의 데이터베이스가 존재하면 해당 데이터베이스를 삭제하고 새로운 스키마를 생성합니다.
#따라서 애플리케이션을 다시 시작할 때마다 데이터베이스의 내용이 손실될 수 있으므로 주의해야 합니다.
#이 두 옵션은 개발 및 ★★★테스트 환경★에서 유용하지만,
# 프로덕션 환경에서는 권장되지 않습니다. 프로덕션 환경에서는 데이터베이스 스키마를 수동으로 관리하고 변경 사항을 신중하게 적용해야 합니다.
# spring.jpa.hibernate.ddl-auto=update대신해서 실제서비스할떄 사용하는 법
#spring.jpa.hibernate.ddl-auto=validate:
#Hibernate가 애플리케이션 시작 시에 데이터베이스 스키마를 검증합니다. 데이터베이스에 대한 매핑이 유효한지 확인하지만, 스키마를 갱신하거나 수정하지는 않습니다. 이 옵션은 프로덕션 환경에서 사용하기에 적합합니다.
#spring.jpa.hibernate.ddl-auto=none:
#Hibernate가 애플리케이션 시작 시에 데이터베이스 스키마를 조작하지 않도록 합니다. 따라서 Hibernate는 데이터베이스 스키마에 대한 어떠한 변경도 시도하지 않습니다. 이 옵션은 프로덕션 환경에서 가장 안전한 옵션 중 하나입니다. 다만, 새로운 엔티티나 필드를 추가할 때는 반드시 수동으로 데이터베이스 스키마를 업데이트해야 합니다.
#일반적으로 프로덕션 환경에서는 validate 또는 none을 사용하는 것이 좋습니다. 또한, 데이터베이스 관리 도구를 사용하여 스키마를 수동으로 관리하는 것도 권장됩니다.
#
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.show-sql=true
#spring.jpa.dataase-platform
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
#spring.jpa.defer-datasource-initialization=true
-update : (테스트상태에서사용) : update 옵션은 Hibernate가 애플리케이션 시작 시에 데이터베이스 스키마를 자동으로 갱신합니다.
- 이전에 생성된 테이블이나 인덱스를 유지하면서 새로운 필드나 제약 조건을 추가합니다.
- 즉, 데이터베이스의 스키마를 자동으로 변경된 엔티티 클래스의 구조에 맞게 업데이트합니다. 기존 데이터는 유지됩니다.
-create : (테스트상태에서사용) : create 옵션은 Hibernate가 애플리케이션 시작 시에 데이터베이스 스키마를 자동으로 생성합니다.
- 기존의 데이터베이스가 존재하면 해당 데이터베이스를 삭제하고 새로운 스키마를 생성합니다.
- 따라서 애플리케이션을 다시 시작할 때마다 데이터베이스의 내용이 손실될 수 있으므로 주의해야 합니다.
-create-drop : (테스트상태에서사용) : create-drop 옵션은 create와 유사하게 작동하지만, 애플리케이션이 종료될 때 생성된 데이터베이스를 삭제합니다.
- 즉, 애플리케이션을 시작할 때마다 데이터베이스를 생성하고, 애플리케이션이 종료될 때마다 데이터베이스를 삭제합니다.
- 이 옵션은 주로 개발 및 테스트 환경에서 사용되며, 애플리케이션을 다시 시작할 때마다 깨끗한 상태로 데이터베이스를 초기화하는 데 유용합니다.
-none : (실제서비스에서 사용) : 애플리케이션 시작 시에 데이터베이스 스키마를 조작하지 않도록 합니다. 따라서 Hibernate는 데이터베이스 스키마에 대한 어떠한 변경도 시도하지 않습니다.
-validate : 확인만 (실제서비스에서 사용) :
- validate:
●2.
1.JPA = ORM(ORM은 Object-Relational Mapping)
2.spring.datasource.hikari.connection-timeout
3.aws = 트래픽 - 덜 갈수있도록 생각해야합니다.
(connetion, maxsize)
각각의 DB 방언을 맞추어 준다면, 어떤것을 쓰는간에,
개발자가 사용하기로 결정한 RDBMS 마다 ANSI SQL를 표준으로 두고 있다 하지만 자신만의 독자적인 기능을 가지며 이를 방언(Dialect) 라고 합니다 🧑🏼💻
#diffchecker
- 코드 리뷰: 개발자들은 DiffChecker를 사용하여 코드 변경 사항을 리뷰하고 검토합니다. 두 개의 코드 버전을 비교하여 추가된, 수정된 또는 삭제된 부분을 쉽게 식별할 수 있습니다.
#DB생성 (user01)
★MainController 생성
#스트링부트구조
실제구현영역
(계층)
(개념적)
컨트롤러 :
(프레젠테이션 계층)
서비스 :
(비즈니스 계층)
레포지토리 : 퍼시스텐츠 계층
(영속계층)
DB
#먼저구현순서JPA)
1.엔티티(도메인)
2.DTO(도메인)
3.레포지토리
4.서비스
5.컨트롤러
도메인(비즈니스 로직처리) : 엔티티,DTO 같이 묶어서 처리하는 것을 의미합니다.
●
# 도메인은 엔티티+레포지토리 2개를 묶어서 처리하는 경우가 많습니다.
엔티티작성 ㅡ 테이블역할
a1DTO(name,age)
a2DTO
a3DTO
DTO는 수레(DB랑 똑같이 안만들어줘도 댑니다.)
engine=InnoDB = mysql입니다.
#TodoRepository.java
●
#추가 (테스트할려고)
기존의 방법은 테스트프로퍼티선언하고 테스트 했습니다.(아래사진참고)
이번방법은 그래이들안에다가 이것을 넣고 테스트를 실행해보겠습니다.
JPA에 대한 테스트 페이징생성
●5
#엔티티는 변경이 안되는 것이 중요합니다.
★TodoRepositoryTest
package com.shopapi.repository;
import com.shopapi.domain.Todo;
import lombok.extern.log4j.Log4j2;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.time.LocalDate;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
@Log4j2
public class TodoRepositoryTest {
@Autowired //생성자주입(스프링빈이 알아서 객체생성해줍니다.)
private TodoRepository todoRepository;
//TodoRepository todoRepository = new TodoRepository() //위에 Autowired는 이것을 대신해서 수행해줍니다. 심지어 todoRepository는 인터페이스입니다. 복잡하지만, 알아서 해줍니다.
//스프링빈한테 객체를 만들어주고
//객체를 여기다가 만들어 놓는것
@Test
@DisplayName("TodoRepository 테스트")
public void repositoryTest1(){
log.info("==============================");
log.info(todoRepository);
}
@Test
@DisplayName("데이터 추가 테스트")
public void testInsert(){
for(int i = 1 ; i <=10; i++){
Todo todo = Todo.builder()
.title("제목" + i)
.legDate(LocalDate.of(2024,04, 26))
.writer("hong" + i)
.build();
todoRepository.save(todo);
}
//builder빌더쓰는 이유 : 명확하게 쓸려고 합니다.
//.build();
//build로 안하고 생성자라고하면, 순서가 바뀔수가 있습니다.
//순서가 바뀌어도, 잘찾아내기가 힘들수있기 때문입니다.
}
@Test
@DisplayName("데이터 조회 테스트")
public void testRead(){
Long tno =20l; //pk 타입이 Long형이기때문에.
//Optional은 주로 값이 존재하지 않을 수 있는 상황에서 NullPointerException을 방지하고자 할 때 사용됩니다.
Optional<Todo> result = todoRepository.findById(tno);
//orElseThrow : 이 메서드는 값이 존재할 경우에는 해당 값을 반환하고,
// 값이 존재하지 않을 경우에는 지정된 예외를 던집니다
Todo todo = result.orElseThrow();
log.info(todo);
//단위테스트 > 통합테스트 > 시스템테스트로 넘어가기위해서,
//다양한 테스트를 시도해야합니다.
}
@Test
@DisplayName("데이터 수정 테스트")
public void testModify(){
Long tno = 25l;
Optional<Todo> result = todoRepository.findById(tno);
Todo todo = result.orElseThrow();
todo.setTitle("기분좋은날");
todo.setWriter("홍길동");
todoRepository.save(todo);
todo = todoRepository.findById(tno).get();
}
@Test
@DisplayName("데이터 삭제 테스트")
public void testDelete(){
Long tno = 1l;
todoRepository.deleteById(tno);
}
}
#테스트결과
●자습
●자습
●자습
ㅡㅡㅡ
★
자바
디자인패턴