Spring Boot (4) ORM MariaDB

넙데데맨·2022년 7월 19일
0

Spring Data JPA 사용

spring.datasource.driverClassName=org.mariadb.jdbc.Driver
spring.datasource.url = jdbc:mariadb://localhost:3306/springboot
spring.datasource.username="ID"
spring.datasource.password="패스워드"

spring.jpa.hibernate.ddl-auto=create
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true	

아래 3줄은 하이버네이트 옵션 선택사항이다.

spring.jpa.hibernate.ddl-auto

데이터베이스 자동 조작 옵션
create : 애플리케이션이 가동되고 SessionFactory가 실행될 때 기존 테이블을 지우고 새로 생성
create-drop : create와 동일한 기능이지만 애플리케이션 종료시 기존 테이블을 지움
update : SessionFactory가 실행될 때 객체를 검사해서 변경된 스키마 갱신 / 기존 데이터는 유지
validate : 스키마는 건드리지 않으며 객체와 테이블 정보가 다르면 오류
none : ddl-auto 사용 X

spring.jpa.show-sql

로그에 하이버네이트 쿼리문 출력

spring.jpa.properties.hibernate.format_sql

사람이 보기 좋은 형태로 포매팅

엔티티 설계

Spring Data JPA 사용 시 테이블 생성을 위해 쿼리를 작성할 필요가 없다. 테이블과 구조를 생성하는 사용한다.

엔티티 어노테이션

@Entity

해당 클래스가 엔티티임을 명시

@Table(name=사용할 테이블 이름)

클래스 이름과 테이블 이름 다르게 지정 시 사용

@Id

기본 키 역할로 사용 됨

@GeneratedValue(strategy = GenerationType.방식)

@Id와 함께 사용되며 해당 필드 값을 어떤 방식으로 자동생성 할 지 정한다.

GeneratedValue 사용하지 않는 방식

애플리케이션에서 자체적으로 값을 생성해서 할당해준다.
AUTO JPA가 자동으로 생성 전략 결정
IDENTITY 기본 키 생성 데이터베이스에 위임
SEQUENCE 시퀀스 오브젝트를 만들고 값을 주입 받음
TABLE DB에 키 생성용 테이블을 만듬

@Column

@Entity 설정한 필드에 설정을 더하기 위해 사용
name DB 칼럼명 설정
nullable null 처리 가능 명시
length 데이터의 최대길이 설정
unique 유니크 설정

@Transient

엔티티 클래스에 선언된 필드를 DB에서 사용하지 않으려고 할 때 사용한다.

리포지토리 인터페이스 설계

Spring Data JPA가 제공하는 인터페이스로 엔티티가 생성한 DB에 접근하는 데 사용된다.

메서드 생성 규칙

CRUD에서 Read에 해당하는 Select 쿼리를 제외하면 따로 생성해 사용하는 메서드는 없다.
리포지토리에서는 기본값으로 단일 조회, 전체 엔티티 조회만 지원하기 때문에 다른 메소드가 필요하다.

조회 메서드 기능

FindBy SQL의 where절 수행
AND,OR 조건 여러개 설정
Like,NotLLike SQL의 like처럼 특정 문자 포함 조건
StartsWith,StartingWith 특정 키워드 시작 문자열 조건
EndWith,EndingWith 특정 키워드 끝나는 문자열 조건
IsNull,IsNotNull 레코드 값 Null이거나 아닌 값 조건
True,False Boolean 타입 레코드
Before,After 시간 기준 검색
LessThan,GreaterThan 특정값 기준 대소 비교
Between 두 값 사이 데이터 조회
OrderBy orderby와 동일한 기능 정렬하는 데 사용
countBy SQL의 count와 동일 기능(결과의 개수 출력)

DAO 설계

데이터베이스 접근 로직 관리 객체로 비즈니스 로직 동작 과정 중 데이터 조작 기능은 DAO 객체가 수행한다.
Spring Data JPA 에서는 DAO의 개념을 리포지토리가 대체하고 있다.
서비스 로직과 비즈니스 로직을 분리한 후 중간 계층이 있는 것이 유지 보수에서 용이한 경우가 많다.

Select 메소드

public Product selectProduct(Long number) {
        Product selectedProduct = productRepository.getReferenceById(number);

        return selectedProduct;
    }

Insert 메소드

public Product insertProduct(Product product) {
        Product savedProduct = productRepository.save(product);

        return savedProduct;
    }

Update 메소드

public Product updateProductName(Long number, String name) throws Exception {
        Optional<Product> selectedProduct = productRepository.findById(number);

        Product updatedProduct;
        if(selectedProduct.isPresent()){
            Product product = selectedProduct.get();

            product.setName(name);
            product.setUpdatedAt(LocalDateTime.now());

            updatedProduct = productRepository.save(product);
        }else{
            throw new Exception();
        }
        return updatedProduct;
    }

find()를 통해 값을 가져오면 영속성 컨텍스트에 추가된다.
그 상태에서 값을 변경하고 save()를 실행하면 JPA에서 Dirty Check라는 변경 감지를 수행합니다.

Delete 메소드

public void deleteProduct(Long number) throws Exception {
        Optional<Product> selectedProduct = productRepository.findById(number);

        if(selectedProduct.isPresent()){
            Product product = selectedProduct.get();

            productRepository.delete(product);
        }else{
            throw  new Exception();
        }
    }

삭제 역시 find()를 통해 영속성 컨텍스트에 가져와야한다.
그 후 delete() 메소드를 통해 객체 삭제를 요청한다.

DAO 메소드

JPARepository의 메소드들이다.

findAll()
테이블에서 레코드 전체 목록을 조회 List<Member> 객체 리턴

getById(id) getReferenceById(id)
테이블에서 기본키 필드 값이 id인 레코드를 조회
실제 사용전엔 DB에 접근하지 않음(성능상 유리)

findById(id)
테이블에서 기본키 필드 값이 id인 레코드를 조회
영속성 컨텍스트에 데이터가 없을 시 실제 DB 확인
Optional<Member> 타입의 객체가 리턴
이 객체의 get 메서드를 호출하면 Member 객체가 리턴
예) Member m = memberRepository.findById(id).get();

save(member)
Member 객체를 Member 테이블에 저장
객체의 id(기본키) 속성값이 0이면 INSERT / 0이 아니면 UPDATE

saveAll(memberList)
Member 객체 목록을 Member 테이블에 저장

delete(member)
Member 객체의 id(기본키) 속성값과 일치하는 레코드를 삭제

deleteAll(memberList)
Member 객체 목록을 테이블에서 삭제

count()
Member 테이블의 전체 레코드 수를 리턴

exists(id)
Member 테이블에서 id에 해당하는 레코드가 있는지 true/false를 리턴

flush()
지금까지 Member 테이블에 대한 데이터 변경 작업들이 디스크에 모두 기록

Optinal 클래스

Optinal<T> 해당 타입을 감싸주는 Wrapper 클래스로 null값이 들어올 수 있어서 member!=null 같은 코드를 줄이는 데 도움을 준다.
isPresent() 해당값이 null이 아닌 지 체크하는 메소드
get()

DAO 연동 위한 컨트롤러, 서비스 설계

서비스 클래스

  • 도메인 모델을 활용해 애플리케이션에서 제공하는 핵심 기능 제공
  • 비즈니스 레이어에서 세부적인 기능을 서비스 레이어에선 세부적인 기능을 종합해 핵심 기능을 전달하도록 구성한다.
  • 또한 서비스에서 클라이언트가 요청한 데이터를 적절하게 가공해 컨트롤러에게 넘기는 역할을 한다.

데이터 액세스 레이어까지는 엔티티 객체를 다른 레이어에서는 DTO 객체를 사용하는 것이 일반적이며 하나만 사용하는 경우도 있다.

ProductServiceImpl 클래스와 Controller 클래스를 구현한 후 Swagger를 실행해보면 다음과 같이 controller와 모델이 나오게 되며


다음과 같이 데이터를 조작하면 DB에 업데이트된다.

Lombok

자주 사용하는 getter/setter, 생성자 등을 어노테이션으로 치환해 생성해 사용할 수 있게 하는 플러그인

@Getter @Setter Getter, Setter 메소드

@NoArgsContructor 기본 생성자
@AllArgsConstructor 모든 매개변수 생성자
@RequiredArgsConstructor inal, @NotNull 설정된 변수를 매개변수로 갖는 생성자

@ToString ToString 메소드
EqualsAndHashCode 객체의 동등성 동일성 비교 메서드 수행
동등성 : 값이 같다
동일성 : 서로 같은 객체다

@Data 위의 어노테이션 포괄하는 어노테이션

Swagger

application.properties에 해당 코드를 추가해야한다.

spring.mvc.pathmatch.matching-strategy=ant_path_matcher
profile
차근차근

0개의 댓글