DB연결까지 마무리되었으니 JPA를 사용하여 데이터를 INSERT
, SELECT
할 수 있도록 구현하겠습니다.
/* MEMBER 테이블 생성하기 */
drop table if exists member CASCADE;
create table member
(
id bigint generated by default as identity,
name varchar(255),
primary key (id)
);
쿼리를 실행란에서 실행하면 MEMBER
테이블이 생성됩니다.
쿼리 전체를 드레그한 후 ctrl+Enter
단축키로 쿼리 실행이 가능합니다.
JPA는 기존의 반복적인 코드는 물론이고, 기본적인 SQL도 직접 만들어서 실행시켜 준다.
JPA를 사용하면 SQL과 데이터 중심의 설계에서 객체 중심의 설계로 패러다임을 전환할 수 있다.
/* JDBC Template 코드 */
@Override
public List<Member> findAll() {
return jdbcTemplate.query("SELECT * FROM MEMBER", memberRowMapper());
}
/* -------------------- */
/* JPA 코드 */
// from절을 보면 테이블이 아닌 Entity 객체를 대상으로 사용
@Override
public List<Member> findAll() {
return em.createQuery("SELECT m FROM Member m", Member.class).getResultList();
}
개발 생산성을 크게 높일 수 있다.
build.gradle
파일에 JPA 라이브러리 추가dependencies {
...
// implementation 'org.springframework.boot:spring-boot-starter-jdbc' 주석 처리
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
}
spring-boot-starter-data-jpa
는 내부에 jdbc 관련 라이브러리를 포함하기 때문에 사용했던 jdbc 라이브러리는 제거해도 됩니다.
application.properties
파일에 JPA 설정 추가...
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=none
show-sql
: JPA가 생생하는 SQL을 출력합니다.ddl-auto
: JPA는 테이블을 자동으로 생성하는 기능을 제공하는데 none
을 사용하여 해당 기능을 사용하지 않습니다.create
를 사용하면 엔티티 정보를 바탕으로 테이블도 직접 생성해줍니다. @Entity
public class Member {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) // IDENTITY 전략: 디비에 값을 넣을 때 자동으로 채번을 해주는 (ex/auto Increament) 것을 말한다.
private Long id;
// @Column(name = "userName") // 컬럼명이 userName이라면 이렇게 맵핑할 수 있음
private String name;
public Long getId() {
return id;
}
public String getName() {
return name;
}
public void setId(Long id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
}
EntityManager
로 모두 동작을 함EntityManager
를 생성해줌EntityManager
를 injection 받기만 하면 됨 public class JpaMemberRepository implements MemberRepository {
private final EntityManager em;
/*
* JPA는 EntityManager로 모두 동작을 함
* gradle 파일에 jpa dependency 를 추가하게 되면 Spring이 현재 DB와 연결해서 EntityManager를 생성해줌
* 우리는 생성된 EntityManager를 injection 받기만 하면 된다~!
* */
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 m where m.name = :name", Member.class)
.setParameter("name", name)
.getResultList();
return result.stream().findAny();
}
@Override
public List<Member> findAll() {
List<Member> result = em.createQuery("select m from Member m", Member.class).getResultList(); // 테이블이 아닌 Entity 객체를 대상으로 사용
return result;
}
}
@Transactional
public class MemberService {
...
}
org.springframework.transaction.annotation.Transactional
를 사용하자SpringConfig
)@Configuration
public class SpringConfig {
// private DataSource dataSource;
//
// @Autowired
// public SpringConfig(DataSource dataSource) { this.dataSource = dataSource; }
private EntityManager em;
@Autowired
public SpringConfig(EntityManager em) {
this.em = em;
}
...
@Bean
public MemberRepository memberRepository() {
// return new MemoryMemberRepository();
// return new JdbcTemplateMemberRepository(dataSource);
return new JpaMemberRepository(em);
}
/* Spring이 실행되면 MemberService, MemberRepository를 bean으로 등록하고, 위에 작성된 것처럼 MemberService에 memberRepository를 주입해준다. */
}
위까지 마무리하게 되면 드디어 DB를 사용하여 데이터를 다룰 수 있게 됩니다.
위에서 JPA 엔티티 Member
클래스를 만들면서
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) // IDENTITY 전략: 디비에 값을 넣을 때 자동으로 채번을 해주는 (ex/auto Increament) 것을 말한다.
private Long id;
id
필드에 auto Increament
설정을 하였기 때문에 자동으로 채번이 되는 것을 확인할 수 있습니다.
DB에도 데이터가 쌓이는 것을 확인할 수 있습니다.