이전 과제에서는 JDBC template를 사용하여 SQL에 접근하고 사용하였다.
하지만 객체 지향 언어인 JAVA와 관계형 데이터베이스 사이에서는 여러 문제와 불편함이 발생한다.
이것을 해결해줄 JPA에 대하여 알아보고, 직접 시작해보자!
JPA (Java Persistence API)
: 객체 지향 프로그래밍 언어인 java와 관계형 데이터베이스 간의 패러다임 불일치 문제를 해결하여 데이터베이스 작업을 객체 지향적으로 수행할 수 있도록 지원하는 기술이다.

: SQL문을 작성하거나 JDBC를 사용하는 것보다 훨씬 간편하게 객체 전달을 할 수 있다.
JPA를 사용하면 자바 컬렉션에 저장하듯이(ex. list.add()) 객체가 저장되어 조회가 간편하다.
jpa.presist(member); //저장
Member member = jpa.find(memberId); //조회
member.setName("수정할 이름"); //수정
jpa.remove(member); //삭제
JPA의 여러 기능들을 사용하여 데이터베이스 설계 중심의 패러다임을 객체 설계 중심으로 역전시킬 수 있다.
: SQL을 직접 다루면 엔티티에 필드 하나만 추가해도 관련 SQL문과 JDBC 코드를 모두 수정해야 했다.
하지만 JPA를 사용하면 객체 필드가 수정되어도 JPA가 알아서 처리해준다!
: JPA는 상속 / 연관관계 / 객체 그래프 탐색 등 패러다임의 불일치 문제를 해결해준다.
JPA는 애플리케이션과 데이터베이스 사이에서 동작하기 때문에 효율적인 통신이 가능하다.
아래와 같은 상황에서, 멤버를 조회하는 SELECT SQL을 한 번만 데이터베이스에 전달하고 두 번째에는 조회한 멤버 객체를 재사용한다.
String memberId = "helloId";
Member member1 = jpa.find(memberId); //데이터베이스와 통신
Member member2 = jpa.find(memberId); //조회했던 멤버 객체 재사용
또한, JPA의 쓰기 지연(한번에 모아서 요청 보내기), 지연 로딩(필요할 때만 조회), 즉시로딩(한 번만 조회)등을 통해 네트워크 통신 비용 방면에서 좋은 성능을 지닌다.
관계형 데이터베이스는 같은 기능도 벤더마다 사용법이 다른 경우가 많다.
하지만 JPA는 애플리케이션과 데이터베이스 사이에 추상화된 데이터 접근 계층을 제공하여, 특정 데이터베이스 기술에 종속되지 않도록 한다.
Spring Boot 선택
-> Build system : Gradle - Groovy
-> JDK : 버전17 선택
Dependencies는
만 추가해주었다! 지금 선택하지 않아도 추후에 추가 가능하다.
Data Source
-> MySQL
-> User, Password 정보 추가한 후 Test Connection
-> 성공 후, board 스키마 생성
application.properties 에 아래의 코드들을 추가해준다.
// DataSource 설정 spring.datasource.url=jdbc:mysql://localhost:3306/board spring.datasource.username=계정 //개인이 설정한 계정과 비밀번호로 수정하기 spring.datasource.password=비밀번호 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver// Hibernate 설정 spring.jpa.hibernate.ddl-auto=create spring.jpa.properties.hibernate.show_sql=true spring.jpa.properties.hibernate.format_sql=true spring.jpa.properties.hibernate.use_sql_comments=true spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
✔️ Hibernate : JPA의 대표적인 구현체 중 하나이다.
일단 auto=create 로 설정해두었기 때문에,
프로젝트를 빌드할 때마다 테이블이 drop 후 새로 생성될 것이다.
DDL 자동 생성 속성
| 값 | 설명 |
|---|---|
| create | 기존 테이블을 삭제(DROP) 후 다시 생성(CREATE)한다. |
| create-drop | DROP 후 CREATE 하고 종료시점에 테이블을 삭제(DROP)한다. 테스트 시 사용 |
| update | 변경된 사항만 DDL에 반영한다. |
| validate | Entity와 테이블이 정상적으로 매핑 되었는지 확인한다. 실패 시 예외 발생 |
| none | 속성을 사용하지 않는다. |
이제 Entity 를 만들어보자.
💠 BaseEntity.java
@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseEntity {
@CreatedDate
@Column(updatable = false)
private LocalDateTime createdAt;
@LastModifiedDate
private LocalDateTime modifiedAt;
}
@MappedSuperClass@EntityListeners(AuditingEntityListener.class)@CreatedDate, @LastModifiedDateupdatable = false로 생성 시간이 수정되지 못하도록 설정한다.💠 Member.java
@Entity
@Table(name="member")
public class Member extends BaseEntity{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable=false, unique = true)
private String username;
@Column(nullable = false)
private String password;
private Integer age;
}
@GeneratedValue(strategy = GenerationType.IDENTITY)
member테이블@GeneratedValue(strategy = GenerationType.IDENTITY) 덕분에 id는 auto_increment로 설정되 것
실제 데이터베이스 탭에 들어가서 확인해보면 member 테이블이 자동으로 생성된 것을 볼 수 있다!!!
💠 Board.java
@Entity
@Table(name="board")
public class Board extends BaseEntity{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String title;
@Column(columnDefinition = "longtext") //아주 긴 내용도 저장할 수 있음
private String contents;
}
board 테이블까지 만들어주고 빌드해보면,

두 개의 테이블이 요로코롬 잘 생성되었다!!! 👏
@ManyToOne, @JoinColumn 작성// Board.java 에 추가
@ManyToOne
@JoinColumn(name="member_id")
private Member member;
@JoinColumn 으로 매핑한다.
새로 프로젝트 빌드 후 확인해보면, 연관관계가 잘 설정되었다!
이제 앞으로 JPA를 활용하여 데이터베이스에 쉽게 접근하여 사용하고, 프로젝트를 확장시킬 수 있게 되었다~!
다음 게시물에는 JPA로 데이터베이스를 설정한 후의 CRUD과정을 기록해보겠다.