코드짜는 노인네

[Spring] JPA 개념과 JPA 사용예시 본문

spring/JPA

[Spring] JPA 개념과 JPA 사용예시

ikohong 2022. 8. 22. 03:43
728x90
반응형

[Spring] JPA 개념과 JPA 사용예시


▶ JPA (Java Persistence API)
  • 자바 진영의 ORM 기술 표준으로 SQL을 쓰지 않고 데이터를 생성, 조회, 수정, 삭제할 수 있도록 해주는 번역기
  • Java 플랫폼 SE와 자바 플랫폼 EE를 사용하는 응용 프로그램에서 관계형 데이터베이스의 관리를 표현하는 자바 API
  • 실제로 구현된 것이 아니라 구현된 클래스와 매핑을 해주기 위해 사용되는 프레임워크
  • JPA 인터페이스를 구현한 대표적인 오픈소스 : Hibernate
  • 어플리케이션과 JDBC 사이에서 동작
  • 개발자가 작성해야 할 SQL과 JDBC API 코드를 JPA가 대신 처리해줌으로 유지보수해야 하는 코드 수가 줄어듦
▶ ORM (Object Relational Mapping)
  • 객체와 테이블을 매핑해서 패러다임의 불일치를 개발자 대신 해결해주는 것
  • 객체는 객체대로 설계하고 RDB는 RDB에 맞게 설계하는 것을 추구함 ⇒ 객체와 RDB를 중간에서 서로 매핑
  • 데이터베이스와 객체 지향 프로그래밍 언어 간의 호환되지 않는 데이터를 변환하는 프로그래밍 기법
▶ JPA 사용방법 (JpaRepository)
인텔리제이(intelliJ) 툴을 활용하였습니다.
1. build.gradle

프로젝트를 생성할때 타입을 'Gradle'로 선택을 해서 생성을 해주세요.

다음 화면에서 종속성을 추가해주는데 JPA를 사용하기 위해서 'Spring Data JPA', SQL과 연동을 하기 위해 'MySQL Driver'를 추가하였으며, 코드를 자동 완성 해주는 라이브러리 'Lombok'을 추가해주었습니다.

혹여나 프로젝트를 생성하다가 추가를 못했다면, 왼쪽 탭에서 'build.gradle' 안에 'dependencies' 괄호안에 아래의 코드를 추가해주시면 됩니다.

implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

 

2. domain & Repository & DTO

"테이블"은 Domain, "SQL"은 Repository 입니다.

src - main - java - com - example - 프로젝트명 안에 controller, domain, service 파일을 구성해놓았습니다. 여기서 domain의 의미는 데이터베이스의 테이블을 의미합니다. 이 domain 파일안에 JPA을 활용해 테이블을 구성해야됩니다.

2-0. 데이터베이스 접근 : application.properties 수정
spring.datasource.url=jdbc:mysql://MySQL DB URL :3306/데이터베이스명
spring.datasource.username=username
spring.datasource.password=password
spring.jpa.hibernate.ddl-auto=update

일단은 먼제 MySQL을 해당 프로젝트와 연동을 시켜줘야합니다. 저 같은 경우 AWS의 RDS를 사용해서 접근을 해서 위의 코드를 활용했는데, 접근할 데이터베이스는 미리 생성을 해두셔야됩니다. JPA는 생성되어있는 데이터베이스에 테이블과 컬럼을 생성을 해주지만, 데이터베이스 자체는 생성을 해주지 않습니다.

2-1. 테이블 매핑을 위한 클래스 생성 : @Entity를 활용한 테이블 매핑 (Mapping)

@Getter
@NoArgsConstructor // 기본 생성자 생성
@Entity  // DB 테이블 역할
// 초기 데이터베이스 1개 생성필요 - 하지 않을시 에러 발생 : application.properties 에서 작성한 DB이름으로 생성필요
//@Table(name = "posts") -- 이걸 작성하면 posts와 post 테이블 2개가 생성됨
public class Post extends Timestamped{
    // 제목, 작성자명, 작성 날짜 (Timestamped), 비밀번호 - JWT?, 게시글 내용

    @GeneratedValue(strategy = GenerationType.AUTO)
    @Id
    private Long id;

    @Column(nullable = false)
    private String title;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private String password;

    @Column(nullable = false)
    private String post;

    // 게시물 생성시 이용
    public Post(PostRequestDto requestDto) {
        this.title = requestDto.getTitle();
        this.name = requestDto.getTitle();
        this.password = requestDto.getPassword();
        this.post = requestDto.getPost();
    }
    
    public void updateByPost(PostMypostRequestDto requestDto) {
        this.title = requestDto.getTitle();
        this.post = requestDto.getPost();
    }
}

일단 먼저 테이블과 매핑할 클래스를 생성해줍니다. 클래스를 생성해준 다음, @Entity 를 작성해서 해당 클래스와 테이블을 매핑할것을 알려줍니다. 그리고 클래스안을 보면 다음과 같이 작성을 해줍니다.

@Id - 기본 키 매핑
@GenerateValue(strategy = GenerationType.AUTO) - 값을 자동으로 증가시킨다.
private 타입형 id;

@Column(nullable = false) - 필드와 컴럼 매핑 (null값을 불허한다.)
private 타입형 컬럼명;
...
2-2. Repository 인터페이스 생성 : extends JpaRepository<테이블 매핑 클래스명, id 데이터 타입>

다음은 SQL의 역할을 대신할 Repository 인터페이스를 생성해줘야합니다.  이 인터페이스에는 JpaRepository가 포함이 되어서, JPA를 사용할 수 있게 만들어줍니다. 이 공간은 비워놓을수도 있지만, 위의 사진과 같이, 조건을 만들어 따로 사용할 수도 있습니다.

2-3. Dto 클래스 생성 : 

계층간의 데이터 교환을 하기 위해 사용되는 클래스를 생성해줍니다. getter와 setter만 존재하며, 로직을 가지지않기에, 어떤 데이터를 교환할지만 작성을 해주면 됩니다.

3. JPA 사용하기
@RequiredArgsConstructor // final로 선언된 멤버 변수를 자동으로 생성합니다.
@Service  // 서비스임을 선언합니다.
public class PostRepository {
	private final PostRepository postRepository;
    
    @Transactional // 메소드 동작이 SQL 쿼리문임을 선언합니다. - 게시물 수정시 사용
    public Long update(Long id, PostRequestDto postRequestDto) {
        // 오류가 발생했을때 어떻게 할지 확인 - 게시판이 삭제되어 없을경우 대비
        Post post = postRepository.findById(id).orElseThrow(
                () -> new NullPointerException("해당 게시물이 존재하지 않습니다.")
        );
        post.updateByPost(postRequestDto);
        return id;
    }
}

위의 코드는 Service 계층에서 기존의 게시판을 업데이트하는 코드입니다. 위에서 JpaRepository를 생성한것을 사용하는데, 'postRepository.findById(id)'는 데이터베이스에 해당 id값에 대한 데이터를 조회한다는 뜻입니다. 이렇게 사용하는거 보면 약간 MongoDB 데이터베이스 조회할때 쓰는 문법과 조금은 비슷하다는 느낌을 받았습니다. 포스팅을 하면서도 아직 부족한 부분이 느껴지고, 코드가 완벽하지는 않았지만, 그래도 spring이라는게 어떻게 돌아가는구나를 느낄수 있었습니다.

728x90
반응형

'spring > JPA' 카테고리의 다른 글

[Spring] ORM(Object Relational Mapping)와 JPA(Java Persistent API)  (0) 2022.08.22
Comments