[SpringBoot] JPA 연동하기
- Web/SpringBoot
- 2022. 6. 16.
SpringBoot, JPA 연동하기
JPA 시작하기
JPA는 MyBatis 다음으로 가장 많이 사용하는 언어 중 하나로 손꼽히고 있다.
그런만큼 SpringBoot를 공부하면서 JPA를 시작하게 되었고, 이틀간의 노력으로 JPA를 통해 처음으로 insert 작업이 성공되었다.
Gradle 설정하기
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'org.projectlombok:lombok'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: '2.6.8'
runtimeOnly 'org.mariadb.jdbc:mariadb-java-client'
implementation group: 'org.mariadb.jdbc', name: 'mariadb-java-client', version: '2.7.5'
}
SpringBoot의 Gradle방식을 활용하였다.
spring-boot-stater-data-jpa를 불러왔고, 사용한 DB명은 MariaDB이다.
JPA를 활용하기 위해서는 runtimeOnly 설정을 반드시 해야한다.
runtimeOnly는 JPA가 사용할 DB를 의미한다.
server.port=8080
spring.jpa-show-sql=true
spring.jpa.hibernate.ddl-auto=none
spring.datasource.url=jdbc:mariadb://localhost:3306/mollang?characterEncoding=UTF-8
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.datasource.username= Mariadb 아이디
spring.datasource.password= MariaDB 비밀번호
SpringBoot의 가장 기본적인 application.properties 설정이다.
MariaDB를 활용하고 있어서, mariadb기본설정으로 되어있다.
SpringBoot Package 구조
패키지 구조는 다음과 같다.
Setter와 Getter를 담는 Bean, DTO, VO 대신해서 domain이 언급되었다.
DAO를 담당하는 Mapper대신 Repository가 등장한다.
Service는 그대로 표현되어있다.
기본적인 Entity
package com.mollang.first.domain;
import javax.persistence.*;
@Entity
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
JPA에서 가장 눈여겨볼 부분 중 하나라고 생각된다.
Entity는 Java의 필드와 DB의 컬럼을 잇는 역할을 담당하고있다.
보통은 domian의 Class명과 일치하는 Table을 매칭하며, 컬럼은 Field값 그대로 매칭이 되고있다.
그러나 이는 기본적인 Default기능이고, @Table과 @Colum은 생략되어있으므로, 반드시 Table명과 컬럼명을 그대로 사용할 필요는 없다.
@Id
Table의 PK를 의미한다.
@GeneratedValue
자동으로 시퀀스 기능을 지원하도록 도와주는 기능이다.
Repository 기능
package com.mollang.first.repository;
import com.mollang.first.domain.Member;
import javax.persistence.EntityManager;
import java.util.List;
import java.util.Optional;
public class JpaMemberRepository implements MemberRepository{
private final EntityManager em;
public JpaMemberRepository(EntityManager em) {
this.em = em;
}
@Override
public Member save(Member member) {
em.persist(member);
return member;
}
}
해당 글은 Save에 대해서만 코드를 공유하였다.
Save에서 사용하는 메소드는 persist([객체]); 이다.
persist는 EntityManager가 제공하는 메소드로, Insert의 기능이 들어있다.
여기서 가장 중요한 것은 EntityManager Code를 MemberService와 SpringConfig를 통해서 Service의 객체 생성시 EntityManager가 객체주입되도록 설계되어있다는 부분이다.
Service
package com.mollang.first.service;
import com.mollang.first.domain.Member;
import com.mollang.first.repository.MemberRepository;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;
@Transactional
public class MemberService {
private MemberRepository memberRepository;
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
public Long join(Member member) {
//DB 저장
memberRepository.save(member);
return member.getId();
}
}
Service에서는 SpringConfig가 MemberRespository가 연결되도록 되어있다.
기본적인 Autowired대신 사용한 코드이다.
package com.mollang.first.service;
import com.mollang.first.repository.JpaMemberRepository;
import com.mollang.first.repository.MemberRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.persistence.EntityManager;
@Configuration
public class SpringConfig {
private EntityManager em;
@Autowired
public SpringConfig(EntityManager em) {
this.em = em;
}
@Bean
public MemberService memberService() { return new MemberService(memberRepository());}
@Bean
public MemberRepository memberRepository() {
return new JpaMemberRepository(em);
}
}
모든 것이 시작되도록... 만들어진 코드이다.
가운데의 MemberService가 실행될 때, Repository 또한 생성이 된다.
그리고 동시에, EntityManager 또한 공유되도록 설계가 되어있다.
package com.mollang.first.service;
import com.mollang.first.domain.Member;
import com.mollang.first.repository.MemberRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Commit;
import org.springframework.transaction.annotation.Transactional;
@SpringBootTest
@Transactional
class MemberServiceTest {
@Autowired
MemberService memberService;
@Autowired
MemberRepository memberRepository;
@Test
@Commit
void 회원가입() {
Member member = new Member();
member.setName("123t");
System.out.println("테스트시작");
Long saveId = memberService.join(member);
System.out.println("test");
Member findMember = memberService.findOne(saveId).get();
System.out.println(findMember.getId());
}
}
코드가 실행이 되었을 때, DB에는 '123t'라는 name이 자동으로 Insert가 된다.
DB 저장시, 123t가 DB에 저장된 것을 확인할 수 있다.
마무리
객체 주입이 어색한 단계에서 JPA의 접근을 하다보니 이해가 어려운 부분이 되어버렸다.
결과적으로 EntityManager와 .persist의 메소드를 통해서 Insert기능이 되었다는 부분이다.
'Web > SpringBoot' 카테고리의 다른 글
[SpringBoot] JSP 연결하기 (0) | 2022.09.25 |
---|---|
[SpringBoot] Logback 설정하기 (0) | 2022.06.27 |
[SpringBoot] Interceptor 사용하는 방법 (0) | 2022.03.26 |
[SpringBoot] API방식, File Upload 하기 (0) | 2022.03.11 |
[SpringBoot] API 활용하기 (0) | 2022.03.11 |