개발새발 블로그
김영한T 스프링 입문강의 - [섹션6] 스프링 DB 접근 기술 (JPA, 스프링 데이터 JPA) 본문
<JPA>
JPA는 SQL도 직접 만들어서 실행해준다.
build.gradle에 JPA관련 라이브러리를 추가해준다.
// implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
jpa가 내부에 jdbc 라이브러리를 포함하고 있어서, jdbc는 제거해도 된다.
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=none
application.properties에 JPA설정을 추가해준다.
show-sql은 JPA가 날리는 SQL을 볼 수 있고,
ddl-auto는 테이블을 자동으로 생성하는 기능을 제공하는데, 위에서 h2 db에 테이블을 이미 생성해주었으므로, 우리는 해당 기능을 꺼도 된다.
-> none이 아닌 create를 사용하면 테이블을 자동으로 생성해준다.
@Entity
public class Member {
...
}
도메인 클래스에 @Entity 애노테이션을 추가해주면, 앞으로 JPA가 관리한다는 뜻이다.
@Entity
public class Member {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; //임의의 값. 데이터 구분위해 시스템이 정해주는
@Column(name="username")
private String name;
...
현재 id는 pk(primary key)이다.
회원이 입력하는 값으로 들어가는게 아니라, db에서 데이터구분을 위해 자동으로 생성된다.
그래서 id에는 @Id @GeneratedValue(strategy = GenerationType.IDENTITY) 이런 애노테이션을 적어주어야하고,
만약, 테이블에 저장되어있는 열의 이름이 username이라면 그에 맞춰주기 위해 @Column(name="username") 애노테이션을 추가한다.
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) {
//pk는 위에서 한것처럼 바로 조회가 가능하지만, 나머지는 불가능. 객체쿼리를 사용해서 처리해야함
//Member member = em.find(Member.class, name); 불가능 (pk가 아니라서)
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() {
//객체를 대상을 쿼리를 날리는
return em.createQuery("select m from Member m", Member.class)
.getResultList();
}
}
EntityManager를 사용해서 처리해준다.
그리고 pk를 사용해서 객체를 불러올 경우에만 Member member = em.find(Member.class, id); 를 사용할 수 있고,
아닐 경우에는 em.createQuery("select m from Member m where m.name = :name", Member.class) 이렇게 객체를 불러오는 쿼리문을 사용해줘야 한다.
<스프링 데이터 JPA>
JPA를 사용하면 리포지토리 구현을 하지 않고도 개발을 완료할 수 있다.
public interface SpringDataJpaMemberRepository extends JpaRepository<Member, Long>, MemberRepository {
@Override
Optional<Member> findByName(String name);
}
JpaRepository를 상속받기만해도 알아서 구현체를 자동으로 만들어준다. 기본적인 CRUD는 다 제공을 해준다.
그리고 스프링빈에도 알아서 등록을 해준다.
JpaRepository가 못만드는게 있다. 누구나 다 만드는 공통된 것이 아니라, findByName 같은 이름으로 찾거나, 이메일로 찾고 싶은 등 우리의 도메인으로 사용하는 것들은 직접 구현을 해줘야한다.
findByName을 실행하게되면 JPQL로 select m from Member m where m.name = ? 을 만들어줄건데,
Optional<Member> findByNameAndId(String name, Long id);
이렇게 쓰면 Name과 Id로 찾아주는 로직이다. 이렇게 이름만 규칙에 맞게 잘 써줘도 JpaRepository가 알아서 구현해준다!!
복잡한 쿼리같은 경우는 직접 구현까지 해줘야한다.
Querydsl 이라는 라이브러리를 사용하면 되는데,
@Configuration
public class SpringConfig {
private final MemberRepository memberRepository;
public SpringConfig(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
@Bean
public MemberService memberService(){
return new MemberService(memberRepository);
}
// @Bean
// public MemberRepository memberRepository(){
// return new MemoryMemberRepository();
// return new JpaMemberRepository(em);
// }
}
'백 > spring' 카테고리의 다른 글
[스프링부트3 자바 백엔드 개발 입문] 3장 - 게시판 CRUD 만들기 (1) | 2024.01.09 |
---|---|
[스프링부트3 자바 백엔드 개발 입문] 1-2장 (2) | 2024.01.06 |
김영한T 스프링 입문강의 - [섹션6] 스프링 DB 접근 기술 (JDBC, Jdbc Template) (0) | 2023.11.19 |
김영한T 스프링 입문강의 - [섹션5] 회원관리 예제(웹 MVC 개발) (0) | 2023.11.07 |
김영한T 스프링 입문강의 - [섹션4] 스프링 빈과 의존관계 (0) | 2023.11.07 |