JPA에 대하여 알아보았다.
JDBC로도 해보았고 JDBCTemplate으로 전 포스팅에서 경험해보았다.
JDBCTemplate만 써도 개발해야할 코드가 확 줄어드는것을 확인할 수 있었다.
하지만 SQL query부분은 직접 써줘야만 했다.
그런데 JPA라는 기술을 사용하면 SQL query도 자동으로 해주게되어
개발 생산성을 크게 높일 수 있게된다.
단순히 SQL query을 만들어주는 것을 넘어서서
SQL과 데이터중심의 설계에서 객체중심의 설계로 패러다임을 전환을 할 수 있다.
구글 트렌드에서 Mybatis와 JPA를 비교해서 보면
2015년 부터 꾸준한 성장을 볼 수 있다!!
국내에도 JPA가 많이 보급되었다고한다.
전세계적으로 보면 JPA가 Mybatis와 비교도 할 수 없을만큼
차이가 심하다.
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') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}
먼저 JPA를 쓰기위해서는 build.gradle에 라이브러리를 추가해준다.!
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
application.properties에 JPA관련 설정을 추가해준다.
spring.jpa.show-sql을 true를 사용하면 JPA가 날리는 SQL을 볼 수있다.
spring.jpa.hibernate.ddl-auto를 사용하면 JPA가 객체를 보고
테이블도 만들어주게 된다 하지만 현재 만들어져있고 만들어진 것을 쓸 것이기때문에
none으로 설정해준다.
package hello.hellospring.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@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를 쓰려면 엔티티를 매핑해주어야한다.
JPA라는 것은 표준 인터페이스이다. 구현체로 하이버네이트 등등이 있는데
하이버네이트를 쓸 것이다. JPA는 객체와 ORM이라는 기술이다.
@Entity 애너테이션을 주면 JPA가 관리하는 엔티티가 된다.
그리고 pk를 설정해준다.
쿼리에 id를 넣는 것이 아니라 db가 자동으로 id를 생성해주는것을
Identity 전략이라고 한다.
이러한 애너테이션을 가지고 매핑을 하게된다!
package hello.hellospring.repository;
import hello.hellospring.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;
}
@Override
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 where m.name= :name", Member.class)
.setParameter("name",name)
.getResultList();
return result.stream().findAny();
}
@Override
public List<Member> findAll() {
return em.createQuery("select m from Member m",Member.class)
.getResultList();
}
}
JpaMemberRepository를 만들고 MemberRepository를 implements 한다.
JPA는 EntityManger라는 것으로 동작을한다.
스프링부트가 자동으로 EntityManager을 생성해준다.
db랑 통신하는 것들을 처리한다.
findByName이나 findAll을 하려면 JPQL이라는 쿼리를 이용해야한다.
JPQL이란 객체를 대상으로 쿼리를 날리는 것이다.
단건을 찾는것은 가능하지만
pk기반이 아닌 다른 기능들은 JPQL이라는 것이 필요하다.
그리고 MemberService클래스에 @Transaction을 필요로하기때문에
걸어둔다!
package hello.hellospring;
import hello.hellospring.repository.*;
import hello.hellospring.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.persistence.EntityManager;
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 JdbcTemplateMemberRepository(dataSource);
return new JpaMemberRepository(em);
}
}
SpringConfig또한 수정해주어야한다.
EntityManager라는 것이 필요하다.
콘솔창에서 뜬 쿼리이다.
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, ?)
'웹프로그래밍 > Spring 입문' 카테고리의 다른 글
| 21. AOP (0) | 2021.07.01 |
|---|---|
| 20. 스프링 데이터 JPA (0) | 2021.06.30 |
| 18. 스프링 JDBC Template (0) | 2021.06.29 |
| 17. 스프링 통합 테스트 (0) | 2021.06.29 |
| 16. 순수 JDBC (0) | 2021.06.24 |