본문 바로가기
Web Develop/Book Study

[Book Study] 스프링 부트 핵심 가이드 - 6. 데이터베이스 연동

by tripleup 2023. 9. 9.
728x90
반응형

[Book Study] 스프링 부트 핵심 가이드
6. 데이터베이스 연동


6 - 1 MariaDB 설치

6 - 2 ORM

ORM (Object Relational Mapping)

- 객체와 RDB의 테이블을 자동으로 매핑하는 방법

- 클래스는 데이터베이스의 테이블과 매핑하기 위해 만들어진 것이 아니기 때문에 RDB테이블과 어쩔수 없는 불일치 존재

- ORM은 이 둘의 불일치와 제약사항을 해결하는 역할

 

ORM의 장점

1. ORM을 사용하면서 데이터베이스 쿼리를 객체지향적으로 조작할 수 있다.

2. 재사용 및 유지보수가 편리하다.

3. 데이터베이스에 대한 종속성이 줄어든다.

 

ORM의 단점

1. ORM만으로 온전한 서비스를 구현하기에는 한계가 있다.

2. 애플리케이션의 객체 관점과 데이터베이스의 관계 관점의 불일치가 발생한다.


6 - 3 JPA

JPA (Java Persistence API)

- 자바 진영의 ORM 기술 표준으로 채택된 인터페이스의 모음

- ORM이 큰 개념이라면 JPA는 더 구체화된 스펙을 포함

- 개발자가 직접 JDBC를 구현하게 되면 SQL에 의존하게 되는 문제 등이 있어 개발의 효율성이 떨어지는데, JPA가 이 같은 문제점을 보완해서 개발자 대신 적절한 SQL을 생성하고 데이터베이스를 조작해서 객체를 자동 매핑하는 역할 수행

 

JPA 기반의 구현체

1. 하이버네이트 (Hibernate) : 가장 많이 사용

2. 이클립스 링크 (Eclipse Link)

3. 데이터 뉴클리어스 (DataNucleus)


6 - 4 하이버네이트

하이버네이트

- 자바의 ORM 프레임워크, JPA가 정의하는 인터페이스를 구현하고 있는 JPA 구현체 중 하나

 

Spring Data JPA

- JPA를 편리하게 사용할 수 있도록 지원하는 스프링 하위 프로젝트 중 하나

- CRUD 처리에 필요한 인터페이스를 제공하며, 하이버네이트의 엔티티 매니저를 직접 다루지 않고 리포토리를 정의해 사용함으로써 스프링이 적합한 쿼리르르 동적으로 생성하는 방식으로 데이터베이스 조작


6 - 5 영속성 컨텍스트

영속성 컨텍스트 (Persistence Context)

- 애플리케이션과 데이터베이스 사이에서 엔티티와 레코드의 괴리를 해소하는 기능과 객체를 보관하는 기능을 수행

 

엔티티 매니저

- 엔티티를 관리하는 객체, 데이터베이스에 접근해서 CRUD 작업을 수행

 

엔티티의 생명주기

1. 비영속 : 영속성 컨텍스트에 추가되지 않은 엔티티 객체의 상태 

2. 영속 : 영속성 컨텍스트에 의해 엔티티 객체가 관리되는 상태

3. 준영속 : 영속성 컨텍스트에 의해 관리되던 엔티티 객체가 컨텍스트와 분리된 상태

4. 삭제 : 데이터베이스에서 레코드를 삭제하기 위해 영속성 컨텍스트에 삭제를 요청한 상태


6 - 6 데이터베이스 연동

6 - 7 엔티티 설계

엔티티 설계

- 데이터베이스 테이블을 자바 클래스로 표현하는 것

- 데이터베이스와 객체 지향 프로그래밍 간의 간극 감소 

 

@Entity
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "name", nullable = false)
    private String name;

    @Column(name = "age")
    private int age;

    // 기본 생성자
    public Person() {
    }

    // Getter와 Setter
    // ...
}

엔티티 관련 기본 어노테이션

@Entity

- 해당 클래스가 엔티티임을 명시하기 위한 어노테이션

 

@Table

- 클래스의 이름과 테이블의 이름을 다르게 지정해야 하는 경우

- 명시하지 않으면 테이블의 이름과 클래스의 이름이 동일하단는 읨

 

@Id

- 테이블의 기본값 역할로 사용

 

@GeneratedValue

- 해당 필드의 값을 어떤 방식으로 자동으로 생성할지 결정할 때 사용

 

값 생성 방식

1. GeneratedValue를 사용하지 않는 방식 (직접 할당)

- 애플리케이션에서 자체적으로 고유한 기본값을 생성할 경우 사용하는 방식

- 내부에 정해진 규칙에 의해 기본값을 생성하고 식별자로 사용

 

2. AUTO

- GenetratedValue의 기본 설정값

- 기본값을 사용하는 데이터베이스에 맞게 자동 생성

 

3. IDENTITY

- 기본값 생성을 데이터베이스에 위임하는 방식

- 데이터베이스의 AUTO_INCREMENT를 사용해 기본값을 생성

 

4. SEQUENCE

- @SequenceGenerator 어노테이션으로 식별자 셍성기를 설정하고 이를 통해 값을 자동 주입 받음


6 - 8 리포지토리 인터페이스 설계

포지토리 인터페이스

- Spring Data JPA를 사용하여 엔터티와 관련된 CRUD 작업을 단순화하게 해줌.

- 인터페이스만 정의하면 Spring Data JPA가 런타임에 구현체를 자동으로 생성

 

리포지토리 메서드의 생성 규칙

1. FindBy : SQL문의 where 절 역할을 수행하는 구문, findBy 뒤에 엔티티의 필드값을입력해서 사용

2. AND, OR : 조건을 여러 개 설정하기 우히ㅐ 사용

3. Like/NotLike : SQL문의 like와 동일한 기능을 수행하며 특정 문자를 포함하는지 여부를 조건으로 추가

4. StartsWith/StartingWith : 특정 키워드로 시작하는 문자열 조건을 설정

5. EndsWith/ StartingWith : 특정 키워드로 끝나는 문자열 조건을 설정

6. IsNull/ InNotNull : 레코드 값이 Null이거나 Null이 아닌 값을 검색

7. True/False : Boolean 타입의 레코드를 검색할 때 사용

8. Before/After : 시간을 기준으로 값을 검색

9. LessThan/GreaterThan : 특정 값(숫자)을 기준으로 대소 비교를 할 때 사용

10. Between : 두 값(숫자) 사이의 데이터를 조회

11. OrderBy : SQL 문에서 order by 와 동일한 기능을 수행

12 countBy : SQL 문의 count와 동일한 기능을 수행하며, 결괏값의 개수(count)를 추출

 

 

6 - 9  DAO 설계

DAO

- 데이터베이스와의 CRUD 작업을 캡슐화하는 객체
- DAO를 통해 애플리케이션 코드와 데이터베이스 간의 결합도를 낮추고 유지보수를 용이

 

public interface PersonDAO {
    void insertPerson(Person person);
    Person getPerson(Long id);
    List<Person> getAllPersons();
    void updatePerson(Person person);
    void deletePerson(Long id);
}

 

@Repository
public class PersonDAOImpl implements PersonDAO {
    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public void insertPerson(Person person) {
        entityManager.persist(person);
    }

    @Override
    public Person getPerson(Long id) {
        return entityManager.find(Person.class, id);
    }

    @Override
    public List<Person> getAllPersons() {
        TypedQuery<Person> query = entityManager.createQuery("SELECT p FROM Person p", Person.class);
        return query.getResultList();
    }

    @Override
    public void updatePerson(Person person) {
        entityManager.merge(person);
    }

    @Override
    public void deletePerson(Long id) {
        Person person = getPerson(id);
        if (person != null) {
            entityManager.remove(person);
        }
    }
}

6 - 10 DAO 연동을 위한 컨트롤러와 서비스 설계

컨트롤러 설계

- HTTP 요청을 받아 처리하고 응답을 반환하는 역할

- 서비스 레이어와 레포지토리와의 연동을 통해 비즈니스 로직을 수행하고 결과를 반환

@RestController
@RequestMapping("/api/persons")
public class PersonController {
    @Autowired
    private PersonRepository personRepository;

    @GetMapping
    public List<Person> getAllPersons() {
        return personRepository.findAll();
    }

    @GetMapping("/{id}")
    public ResponseEntity<Person> getPersonById(@PathVariable Long id) {
        Optional<Person> person = personRepository.findById(id);
        return person.map(ResponseEntity::ok).orElseGet(() -> ResponseEntity.notFound().build());
    }

    @PostMapping
    public Person createPerson(@RequestBody Person person) {
        return personRepository.save(person);
    }

    @PutMapping("/{id}")
    public Person updatePerson(@PathVariable Long id, @RequestBody Person updatedPerson) {
        return personRepository.findById(id)
                .map(person -> {
                    person.setName(updatedPerson.getName());
                    person.setAge(updatedPerson.getAge());
                    return personRepository.save(person);
                })
                .orElseThrow(() -> new ResourceNotFoundException("Person not found with id " + id));
    }

    @DeleteMapping("/{id}")
    public void deletePerson(@PathVariable Long id) {
        personRepository.deleteById(id);
    }
}

6 - 11 [한걸음 더] 반복되는 코드의 작성을 생략하는 방법 - 롬복

롬복(Lombok)

- 데이터(모델) 클래스를 생성할 때 반복적으로 사용하는 getter/setter과 같은 메서드를 어노테이션으로 대체하는 기능을 제공하는 라이브러리

 

롬복의 주요 어노테이션

1. @Getter, @Setter

- 클래스에 선언돼 있는 필드에 대한 getter/setter 메서드를 생성

 

생성자 자동 생성 어노테이션

1. NoArgsConstructor : 매개변수가 없는 생성자를 자동 생성

2. AllArgsConstructor : 모든 필드를 매개변수로 갖는 생성자를 자동 생성

3. RequiredArgsConstructor : 필드 중 finall이나 @NotNull이 설정된 변수를 매개변수로 갖는 생성자를 자동 생성

 

2. @ToString

- toString() 메서드를 생성하는 어노테이션

- 필드의 값을 문자열로 조합해서 리턴

 

 

728x90
반응형

댓글