JPA에 대한 개념은 ORM, JPA에 대한 이해에 정리하였으니 참고바란다.
이번 글에서는 JpaRepository를 사용하는 간단한 예제에 대해 정리하였다. JPA의 가장 중요한 키워드는 영속성이다.
JPA를 처음 사용하는데 JpaRepository에 대해 공부하고있다면 영속성에 대해 먼저 공부하는 것을 추천한다.
영속성에 대한 내용은 다음 포스팅을 참고하길 바란다.
JPA 영속성 컨텍스트 이해 (Persistence Context)
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
spring.jpa.properties.hibernate.show_sql=true
@Getter
@NoArgsConstructor
@Entity
public class Posts {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(length = 500, nullable = false)
private String title;
@Column(columnDefinition = "TEXT", nullable = false)
private String content;
private String author;
@Builder
public Posts(String title, String content, String author) {
this.title = title;
this.content = content;
this.author = author;
}
}
JPA는 lombok을 사용하는 것이 일반적이다. - lombok 어노테이션
public interface PostsRepository extends JpaRepository<Posts, Long>{
List<Posts> findByContent(String content);
List<Posts> findByIdLessThan(long id);
List<Posts> findByIdLessThanEqual(long id);
List<Posts> findByTitleStartingWith(String title);
}
JpaRepository를 상속받는 인터페이스를 구현한다. JpaRepository는 Spring Data JPA에서 제공하는 JPA 구현을 위한 인터페이스로 간단하게 상속하여 사전에 정의된 여러 메서드를 통해 간단히 CRUD를 수행할 수 있다. 또한 정해진 규칙과 단어를 조합한 이름으로 메서드명을 작성하는 것만으로 다양한 쿼리를 생성할 수 있다.
Spring Data JPA 에서 정해놓은 네이밍 컨벤션을 지키면 JPA가 해당 메서드 이름을 분석해서 적절한 SQL을 작성한다.
자세한 내용은 공식문서에 설명되어있다. - Spring Data JPA 공식 문서
@Slf4j
@SpringBootTest
class JpaApplicationTests {
@Autowired
PostsRepository postsRepository;
@After(value = "execution(* com.jpa.example.*(..))")
public void cleanup() {
postsRepository.deleteAll();
}
@Test
public void boardList() {
String title = "테스트 게시글";
String content = "";
/*init data*/
for(int cnt = 1 ; cnt <= 10 ; cnt++) {
content = (cnt % 2 == 0 ? "짝": "홀");
postsRepository.save(Posts.builder()
.title(title)
.content(content)
.author("devlog" + cnt)
.build());
}
List<Posts> postsList = postsRepository.findAll();
printList(postsList, "findAll");
postsList = postsRepository.findByContent("짝");
printList(postsList, "findByContent - 짝");
postsList = postsRepository.findByContent("홀");
printList(postsList, "findByContent - 홀");
postsList = postsRepository.findByIdLessThan(5);
printList(postsList, "findByIdLessThen");
postsList = postsRepository.findByIdLessThanEqual(5);
printList(postsList, "findByIdLessThanEqual");
postsList = postsRepository.findByTitleStartingWith("테스트");
printList(postsList, "findByTitleLike");
}
private void printList(List<Posts> postsList, String logName) {
log.info("=========================[{} START]=========================", logName);
for(Posts posts : postsList) {
log.info("id : {}, title : {}, contents : {}, author : {}", posts.getId(), posts.getTitle(), posts.getContent(), posts.getAuthor());
}
log.info("=========================[{} END]=========================\n", logName);
}
}
Hibernate: drop table if exists posts CASCADE
Hibernate: create table posts (id bigint generated by default as identity, author varchar(255), content TEXT not null, title varchar(500) not null, primary key (id))
2023-03-29 17:51:54.953 INFO 23236 --- [ main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2023-03-29 17:51:54.990 INFO 23236 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2023-03-29 17:51:56.800 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : Started JpaApplicationTests in 10.686 seconds (JVM running for 14.079)
Hibernate: insert into posts (id, author, content, title) values (default, ?, ?, ?)
Hibernate: insert into posts (id, author, content, title) values (default, ?, ?, ?)
Hibernate: insert into posts (id, author, content, title) values (default, ?, ?, ?)
Hibernate: insert into posts (id, author, content, title) values (default, ?, ?, ?)
Hibernate: insert into posts (id, author, content, title) values (default, ?, ?, ?)
Hibernate: insert into posts (id, author, content, title) values (default, ?, ?, ?)
Hibernate: insert into posts (id, author, content, title) values (default, ?, ?, ?)
Hibernate: insert into posts (id, author, content, title) values (default, ?, ?, ?)
Hibernate: insert into posts (id, author, content, title) values (default, ?, ?, ?)
Hibernate: insert into posts (id, author, content, title) values (default, ?, ?, ?)
Hibernate: select posts0_.id as id1_0_, posts0_.author as author2_0_, posts0_.content as content3_0_, posts0_.title as title4_0_ from posts posts0_
2023-03-29 17:51:57.643 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : =========================[findAll START]=========================
2023-03-29 17:51:57.643 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 1, title : 테스트 게시글, contents : 홀, author : devlog1
2023-03-29 17:51:57.644 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 2, title : 테스트 게시글, contents : 짝, author : devlog2
2023-03-29 17:51:57.645 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 3, title : 테스트 게시글, contents : 홀, author : devlog3
2023-03-29 17:51:57.645 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 4, title : 테스트 게시글, contents : 짝, author : devlog4
2023-03-29 17:51:57.645 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 5, title : 테스트 게시글, contents : 홀, author : devlog5
2023-03-29 17:51:57.648 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 6, title : 테스트 게시글, contents : 짝, author : devlog6
2023-03-29 17:51:57.648 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 7, title : 테스트 게시글, contents : 홀, author : devlog7
2023-03-29 17:51:57.648 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 8, title : 테스트 게시글, contents : 짝, author : devlog8
2023-03-29 17:51:57.649 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 9, title : 테스트 게시글, contents : 홀, author : devlog9
2023-03-29 17:51:57.650 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 10, title : 테스트 게시글, contents : 짝, author : devlog10
2023-03-29 17:51:57.651 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : =========================[findAll END]=========================
Hibernate: select posts0_.id as id1_0_, posts0_.author as author2_0_, posts0_.content as content3_0_, posts0_.title as title4_0_ from posts posts0_ where posts0_.content=?
2023-03-29 17:51:57.769 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : =========================[findByContent - 짝 START]=========================
2023-03-29 17:51:57.769 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 2, title : 테스트 게시글, contents : 짝, author : devlog2
2023-03-29 17:51:57.770 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 4, title : 테스트 게시글, contents : 짝, author : devlog4
2023-03-29 17:51:57.770 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 6, title : 테스트 게시글, contents : 짝, author : devlog6
2023-03-29 17:51:57.770 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 8, title : 테스트 게시글, contents : 짝, author : devlog8
2023-03-29 17:51:57.770 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 10, title : 테스트 게시글, contents : 짝, author : devlog10
2023-03-29 17:51:57.770 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : =========================[findByContent - 짝 END]=========================
Hibernate: select posts0_.id as id1_0_, posts0_.author as author2_0_, posts0_.content as content3_0_, posts0_.title as title4_0_ from posts posts0_ where posts0_.content=?
2023-03-29 17:51:57.772 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : =========================[findByContent - 홀 START]=========================
2023-03-29 17:51:57.772 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 1, title : 테스트 게시글, contents : 홀, author : devlog1
2023-03-29 17:51:57.772 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 3, title : 테스트 게시글, contents : 홀, author : devlog3
2023-03-29 17:51:57.773 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 5, title : 테스트 게시글, contents : 홀, author : devlog5
2023-03-29 17:51:57.773 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 7, title : 테스트 게시글, contents : 홀, author : devlog7
2023-03-29 17:51:57.773 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 9, title : 테스트 게시글, contents : 홀, author : devlog9
2023-03-29 17:51:57.773 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : =========================[findByContent - 홀 END]=========================
Hibernate: select posts0_.id as id1_0_, posts0_.author as author2_0_, posts0_.content as content3_0_, posts0_.title as title4_0_ from posts posts0_ where posts0_.id<?
2023-03-29 17:51:57.793 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : =========================[findByIdLessThen START]=========================
2023-03-29 17:51:57.794 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 1, title : 테스트 게시글, contents : 홀, author : devlog1
2023-03-29 17:51:57.794 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 2, title : 테스트 게시글, contents : 짝, author : devlog2
2023-03-29 17:51:57.795 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 3, title : 테스트 게시글, contents : 홀, author : devlog3
2023-03-29 17:51:57.795 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 4, title : 테스트 게시글, contents : 짝, author : devlog4
2023-03-29 17:51:57.795 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : =========================[findByIdLessThen END]=========================
Hibernate: select posts0_.id as id1_0_, posts0_.author as author2_0_, posts0_.content as content3_0_, posts0_.title as title4_0_ from posts posts0_ where posts0_.id<=?
2023-03-29 17:51:57.802 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : =========================[findByIdLessThanEqual START]=========================
2023-03-29 17:51:57.802 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 1, title : 테스트 게시글, contents : 홀, author : devlog1
2023-03-29 17:51:57.803 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 2, title : 테스트 게시글, contents : 짝, author : devlog2
2023-03-29 17:51:57.803 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 3, title : 테스트 게시글, contents : 홀, author : devlog3
2023-03-29 17:51:57.803 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 4, title : 테스트 게시글, contents : 짝, author : devlog4
2023-03-29 17:51:57.803 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 5, title : 테스트 게시글, contents : 홀, author : devlog5
2023-03-29 17:51:57.803 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : =========================[findByIdLessThanEqual END]=========================
Hibernate: select posts0_.id as id1_0_, posts0_.author as author2_0_, posts0_.content as content3_0_, posts0_.title as title4_0_ from posts posts0_ where posts0_.title like ? escape ?
2023-03-29 17:51:57.830 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : =========================[findByTitleLike START]=========================
2023-03-29 17:51:57.830 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 1, title : 테스트 게시글, contents : 홀, author : devlog1
2023-03-29 17:51:57.830 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 2, title : 테스트 게시글, contents : 짝, author : devlog2
2023-03-29 17:51:57.831 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 3, title : 테스트 게시글, contents : 홀, author : devlog3
2023-03-29 17:51:57.831 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 4, title : 테스트 게시글, contents : 짝, author : devlog4
2023-03-29 17:51:57.831 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 5, title : 테스트 게시글, contents : 홀, author : devlog5
2023-03-29 17:51:57.831 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 6, title : 테스트 게시글, contents : 짝, author : devlog6
2023-03-29 17:51:57.835 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 7, title : 테스트 게시글, contents : 홀, author : devlog7
2023-03-29 17:51:57.836 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 8, title : 테스트 게시글, contents : 짝, author : devlog8
2023-03-29 17:51:57.837 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 9, title : 테스트 게시글, contents : 홀, author : devlog9
2023-03-29 17:51:57.837 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : id : 10, title : 테스트 게시글, contents : 짝, author : devlog10
2023-03-29 17:51:57.837 INFO 23236 --- [ main] com.jpa.example.JpaApplicationTests : =========================[findByTitleLike END]=========================
JPA Auditing 구현 (Custom EntityListener 적용) (1) | 2024.08.28 |
---|---|
JPA 영속성 컨텍스트 이해 (Persistence Context) (14) | 2024.08.26 |
ORM, JPA에 대한 이해 (12) | 2023.03.29 |
댓글 영역