7.springBoot/1)개념_springBoot

springBoot_개념_Day_15

구이제이 2024. 4. 26. 16:28

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는 객체 생성과 초기화에 사용되는 어노테이션입니다. 이 둘의 주요 차이점은 다음과 같습니다:

  1. @Builder:
  2. @Setter:

따라서, @Builder는 객체를 생성하고 초기화하는 데 사용되며, @Setter는 객체의 상태를 변경하는 데 사용됩니다. 일반적으로 @Builder는 객체 생성 시에 사용되고, @Setter는 객체 생성 이후에 필요한 경우에 사용됩니다.





4.DiffChecker를 사용하는 이유?

DiffChecker를 사용하는 이유는 코드나 텍스트의 변경 사항을 시각적으로 비교하여 확인할 수 있기 때문입니다. DiffChecker는 주로 다음과 같은 상황에서 사용됩니다:

  1. 코드 리뷰: 개발자들은 DiffChecker를 사용하여 코드 변경 사항을 리뷰하고 검토합니다. 두 개의 코드 버전을 비교하여 추가된, 수정된 또는 삭제된 부분을 쉽게 식별할 수 있습니다.
  2. 패치 파일 확인: 코드 변경 사항을 담은 패치 파일이나 diff 파일을 생성할 때, DiffChecker를 사용하여 변경된 내용을 확인하고 적용하기 전에 검토할 수 있습니다.
  3. 문서 비교: 문서나 텍스트 파일의 변경 사항을 비교하고 확인할 때 사용됩니다. 두 버전의 문서를 비교하여 수정된 내용을 확인하거나, 문서 간의 차이점을 분석할 수 있습니다.
  4. 버전 관리 시스템과의 통합: 버전 관리 시스템(예: Git)에서 변경된 코드를 비교하거나 병합하기 전에 DiffChecker를 사용하여 변경 내용을 확인할 수 있습니다.
  5. 프로그래밍 대회 및 알고리즘 문제 해결: 프로그래밍 대회나 알고리즘 문제 해결 시에는 주로 출력 결과나 코드 변경 사항을 비교하여 확인해야 합니다. 이때 DiffChecker를 사용하여 예상한 결과와 실제 결과를 비교하거나, 코드 변경 사항을 분석할 수 있습니다.




5.스프링부트레거시

 

스프링 부트 레거시라는 용어는 일반적으로 "스프링 부트"와 "레거시 시스템"이 결합된 상황을 가리킵니다. 여기서 "레거시 시스템"은 과거에 개발된 시스템을 나타내며, 스프링 부트와 함께 사용되는 것을 의미합니다.



6.비즈니스로직

 

  1. 비즈니스 로직:



ㅡㅡㅡ

 

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 : 확인만 (실제서비스에서 사용) : 

  1. 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

https://www.diffchecker.com/

 

  1. 코드 리뷰: 개발자들은 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);

   }

 

 

 

   }

  

  

 

 

 




 

#테스트결과

 





 




 






●자습

●자습

●자습



ㅡㅡㅡ



자바

디자인패턴