일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- springdatajpa
- AOP
- 그리디
- 자바
- spring
- db
- http
- Spring Boot
- pointcut
- Android
- Exception
- Thymeleaf
- java
- jpa
- 인프런
- Servlet
- kotlin
- QueryDSL
- 스프링
- SpringBoot
- 김영한
- transaction
- JPQL
- JDBC
- 백준
- Greedy
- 스프링 핵심 원리
- 알고리즘
- Proxy
- 스프링 핵심 기능
- Today
- Total
개발자되기 프로젝트
JPA 본문
- JPA를 사용하면 SQL까지 안적어도 된다!
- 객체를 JPA에 넣어주면 JPA가 중간에서 DB에 SQL날리고 data가져옴
- SQL과 Data중심의 설계에서 객체 중심의 설계로 패터다임 전환
1. build.gradle
JPA를 사용하기 위해서 dependency 추가가 필요하다.(jdbc는 지워주자)
//implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
2. application.properties
spring.datasource.url= jdbc:h2:tcp://localhost/~/test
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=none
ddl-auto는 아래 글 참고
3.Entity, PK(Primary Key)
- @Entity : JPA가 관리하는 객체로 @Entity를 통해 테이블과 클래스를 맵핑할 수 있다.
- @Id : Primary key 지정, entity를 유일하게 식별 할 수 있도록. PK 필요.
- @GeneratedValue : 특정 규칙에 의해 primary key 자동 생성
생성 전략은 identity, table, auto등이 있다. - @Columm : 필드에서 사용하는 이름과 다르게 DB에 반영될 column명을 지정할 수 있음.
- 자세한 설명은 아래 글 참고.
@Data
@Entity
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "username")
private String name;
}
4. EntitManager
build.gradle의 의존성에 spring-boot-starter-data-jpa를 추가해줬다.
해당 의존성이 추가가 되어있으면, 스프링 부트가 자동으로 Entitymanager를 생성함.
이제 EntityManager를 사용하기 위해서는 주입받으면 된다!
5. JpaMemberRepository
웬만한 query를 안적어 줘도 된다 ㅋㅋㅋ
단. 조회 쿼리 중, PK나 findAll이 아닌 경우는 JPQL을 사용해야 한다.
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;
}
@Override //pk조회
public Optional<Member> findById(Long id) {
Member member = em.find(Member.class, id);
return Optional.ofNullable(member);
}
@Override
public Optional<Member> findByName(String name) {
List<Member> result = em.createQuery("select m from Member m where m.name= :name", Member.class)
.setParameter("name", name).getResultList();
return result.stream().findAny();
}
@Override
public List<Member> findAll() {
//JPQL 언어, Entity를 대상으로 query 작성하면 SQL로 변환됨.
//객체 자체를 select함.
return em.createQuery("select m from Member m", Member.class).getResultList();
}
}
*참고, createQuery
<T> TypedQuery<T> createQuery(String qlString, Class<T> resultClass);
6. @Transactional
jpa를 사용하려면 항상 @Transactional이 있어야 한다.
data를 저장하거나 변경할 땐, transaction이 있어야 한다.
실질적으로 data를 변경하고 저장한는 method를 제공하는 Service에 적용하자.
@Transactional
public class MemberService {
Transaction관련하여 아래 글 참고.
2021.07.04 - [JPA/영속성] - Entity 생애 주기
2021.07.04 - [JPA/영속성] - Transaction Manager - 1
2021.07.04 - [JPA/영속성] - Transaction Manager - 2
2021.07.04 - [JPA/영속성] - Transaction Manager-3 : Isolation
2021.07.05 - [JPA/영속성] - Transaction Manager - 4 : Isolation
2021.07.06 - [JPA/영속성] - Transaction Manager - 5 : Propagation
7. StringConfig
Repository를 바꿔치기 해주자!
JPA를 사용하기 위해서는 EntityManager가 필요하니 생성자를 통해 주입받아서사용하자.
@Configuration
public class SpringConfig {
//private DataSource dataSource;
private final EntityManager em;
@Autowired
public SpringConfig(EntityManager em) {
this.em = em;
}
/* @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);
//return new JdbcTemplateMemberRepository(dataSource);
return new JpaMemberRepository(em);
}
}
8. 통합 테스트
회원가입 테스트에 대하여 실행된 query를 보자
중복 확인을 위해 select query진행 후 insert query가 진행되었다.
Hibernate: select member0_.id as id1_0_, member0_.name as name2_0_ from member member0_ where member0_.name=?
Hibernate: insert into member (id, name) values (null, ?)
@Transactional에 의해 Test 종료 후 rollback 되었다.
9. GitHub : 210723 JPA