반응형
JPA는 ORM 기술이다. Object와 Relational Database Table을 Mapping해주는 기술이다.
1. JPA 관련 라이브러리 추가 (build.gradle)
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web' //여기
implementation 'org.springframework.boot:spring-boot-starter-data-jpa' //여기
runtimeOnly 'com.h2database:h2'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
spring-boot-starter-data-jpa를 설정하면 스프링부트에서 자동으로 EntityManager를 생성해준다. 데이터베이스와 연결까지 다해준다. 그래서 jpa repository를 만들 때 만들어진 EntityManager를 injection(DI) 해주면 된다.
2. JPA 관련 설정 추가하기 (application.properties)
spring.datasource.url=jdbc:h2:tcp://localhost/~/test
spring.datasource.driver-class-name=org.h2.Driver
#jpa가 날리는 sql을 볼 수 있다.
spring.jpa.show-sql=true
#jpa는 객체를 보고 알아서 테이블을 만든다. (create)
#현재는 테이블을 만들어둔 상태이기 때문에 끄고 시작할 것이다.
spring.jpa.hibernate.ddl-auto=none
3. JPA Entity 명시하기
- @Entity가 붙으면 jpa가 관리하는 entity라고 명시하는 것이다.
- @Id는 primary key를 명시한 것이다.
- @GeneratedValue(strategy=GenerationType.IDENTITY)는 primary key가 개발자에 의해 부여되는 것이 아닌 자동으로 시스템이 부여해주는 방식을 의미한다.
package com.hello.hellospring.domain;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
@Entity
public class Member {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
public void setId(Long id) {
this.id = id;
}
public Long getId() {
return id;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
4. JpaMemberRepository에 EntityManager
jpa의 repository는 entityManager를 꼭 설정해줘야 한다.
package com.hello.hellospring.repository;
import com.hello.hellospring.domain.Member;
import jakarta.persistence.EntityManager;
import org.springframework.beans.factory.annotation.Autowired;
public class JpaMemberRepository implements MemberRepository{
private EntityManager em;
@Autowired
public JpaMemberRepository(EntityManager em){
this.em = em;
}
}
5. JPA로 Insert
entityManager의 persist를 이용한다. jpa가 알아서 insert 쿼리 만들어서 데이터를 집어넣는다.
또한 member 객체에 setId까지 해준다.
@Override
public Member save(Member member) {
em.persist(member);
return member;
}
6. JPA로 Select
entityManager의 find를 이용한다.
find는 조회할 타입과 식별값을 넣어준다.
@Override
public Optional<Member> findById(Long id) {
Member member = em.find(Member.class, id);//조회할 타입과 식별값 넣어준다.
return Optional.ofNullable(member);
}
7. pk 기반이 아닌 명령
pk 기반이 아닌 명령어들은 jpql(jpa+sql)을 작성해야한다. entityManager의 createQuery를 이용한다.
@Override
public Optional<Member> findByName(String name) {
List<Member> member = em.createQuery("select m from Member m where m.name = :name", Member.class)
.setParameter("name", name)
.getResultList();
return member.stream().findAny();
}
8. Repository 설정 파일에서 변경 (JDBC -> JPA)
- JDBC 방식 코드
기존 JDBC 방식은 dataSource를 사용했다. dataSource는 h2 데이터베이스와 소켓 통신을 위한 창구였다. connection과 쿼리를 날릴 수 있게 도와줬다.
package com.hello.hellospring;
import com.hello.hellospring.repository.JdbcMemberRepository;
import com.hello.hellospring.repository.MemberRepository;
import com.hello.hellospring.repository.MemoryMemberRepository;
import com.hello.hellospring.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration
public class SpringConfig {
DataSource dataSource;
@Autowired
public SpringConfig(DataSource dataSource){
this.dataSource=dataSource;
}
@Bean
public MemberService memberService(){
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository(){
// return new MemoryMemberRepository();
return new JdbcMemberRepository(dataSource); //데이터베이스 교체
}
}
- JPA 방식 코드
주입방식 1) @PersistenceContext 사용
- EntityManagerFactory에서 새로운 EntityManager를 생성하거나
- Transaction에 의해 기존에 생성된 EntityManager를 반환해준다.
package com.hello.hellospring;
import com.hello.hellospring.repository.JdbcMemberRepository;
import com.hello.hellospring.repository.JpaMemberRepository;
import com.hello.hellospring.repository.MemberRepository;
import com.hello.hellospring.repository.MemoryMemberRepository;
import com.hello.hellospring.service.MemberService;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration
public class SpringConfig {
@PersistenceContext
private EntityManager em;
@Bean
public MemberService memberService(){
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository(){
// return new MemoryMemberRepository();
// return new JdbcMemberRepository(dataSource); //데이터베이스 교체
return new JpaMemberRepository(em);
}
}
주입방식 2) DI 사용
@Autowired를 사용해 클래스 생성 시 주입해주면 된다.
package com.hello.hellospring;
import com.hello.hellospring.repository.JdbcMemberRepository;
import com.hello.hellospring.repository.JpaMemberRepository;
import com.hello.hellospring.repository.MemberRepository;
import com.hello.hellospring.repository.MemoryMemberRepository;
import com.hello.hellospring.service.MemberService;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@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 MemoryMemberRepository();
// return new JdbcMemberRepository(dataSource); //데이터베이스 교체
return new JpaMemberRepository(em);
}
}
반응형
'BE > Spring' 카테고리의 다른 글
AOP(Aspect Oriented Programming) (0) | 2024.01.09 |
---|---|
스프링 데이터 JPA 기초 지식 (0) | 2024.01.09 |
데이터베이스 스프링에 연결하기 (1. 순수 JDBC 방식), DI와 OCP (0) | 2024.01.05 |
h2 실습용 데이터베이스 실행 방법 (0) | 2024.01.05 |
스프링 빈을 등록하는 방법 with DI/싱글톤패턴 (0) | 2024.01.04 |