1. Spring Data JPA 사용
- CRUD 처리를 위한 공통 인터페이스
특징
- Spring 및 JPA 기반의 리포지토리 구축을 위한 정교한 지원
- Querydsl 술어 지원 및 이에 따른 유형 안전 JPA 쿼리
- 도메인 클래스의 투명한 감사
- 페이지 매김 지원, 동적 쿼리 실행, 맞춤형 데이터 액세스 코드 통합 기능
- @Query부트스트랩 시간 에 주석 이 달린 쿼리의 유효성 검사
- XML 기반 엔티티 매핑 지원
- 을 도입하여 JavaConfig 기반 저장소 구성 @EnableJpaRepositories.
출처 : https://spring.io/projects/spring-data-jpa
Spring Data JPA
Spring Data JPA, part of the larger Spring Data family, makes it easy to easily implement JPA based repositories. This module deals with enhanced support for JPA based data access layers. It makes it easier to build Spring-powered applications that use dat
spring.io
JPA Repository 객체 의존성 주입하는 방법
1. @Configuration어노테이션을 사용하는 Config 클래스에서@EnableJpaRepositories(basePackages = “”)
2. @Repository 어노테이션으로 의존성 주입
3. 필드로 @Autowired 사용
4. xml파일 사용하여 주입
User 클래스
/*
* Lombok 의 기능
* : @Getter, @Setter
* - 어노테이션을 클래스에 사용시 모든 필드에 대해서 setter(), getter() 선언됨
* - 어노테이션을 필드에 사용시 필드에 대해서 setter(), getter() 선언됨
* - 컴파일시 우측>리팩토링>Delombok에서 자동 setter(), getter() 자동 생성
* : @ToString
* - 어노테이션 사용으로 클래스에 필드 toString() 선언
* : @NoArgsConstructor
* - 인자가 없는 생성자(반드시 필요하여 항시 선언)
* : @AllArgsConstructor
* - 객체가 가지고 있는 모든 필드를 인자로 받는 생성자
* : @RequiredArgsConstructor
* - 필요한 인자만 가지고 만든 생성자
* : @NonNull
* - Lombok에서 제공, 해당 필드를 필수값으로 지정하여 @RequiredArgsConstructor 생성자를 사용
* : @EqualsAndHashCode
* - Equals(), HashCode()를 오버라이딩하여 사용한다는 어노테이션
* : @Data
* - Equivalent to @Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode.
* - 위의 어노테이션들을 합쳐놓은것과 동일하다.(만능 어노테이션으로 보이나, OOP원칙을 깨는 단점이 보임)
* : @Builder
* - @AllArgsConstructor와 비슷하게 객체를 생성하고 필드값을 주입해주는 빌더의 형식으로 제공
* : @Entity
* - ORM에서 DB테이블에서 객체와 연결해주기 위해 객체를 엔티티로 선언
* : @Id
* - 엔티티의 PK 선언
* : @GeneratedValue
* - 순차적으로 숫자 증가
*/
@NoArgsConstructor
@AllArgsConstructor
@RequiredArgsConstructor
@Data
@Builder
@Entity
@Table(name = "TB_USER")
public class User{
@Id
@NonNull
private String id;
@GeneratedValue
private Long num;
@NonNull
private String pwd;
private LocalDateTime createDt;
private LocalDateTime updateDt;
}
UserRepository 인터페이스
/* @Repository
* UserRepositoryTest 부분에서 @Autowired를 통해 의존성 주입해주었으므로 @Repository를 선언해주지않음
*/
public interface UserRepository extends JpaRepository<User,String> {
}
UserRepository 인터페이스 Test
@SpringBootTest
class UserRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
void crud(){
// save User 테이블 생성 후 인자에 있는 값으로 저장
userRepository.save(new User("tom","123"));
// User 테이블에 모든 데이터를 List 형태로 가져옴(전체 조회)
System.out.println("Repository User : "+userRepository.findAll());
}
}
결과
2022-09-23 22:50:30.631 WARN 46658 --- [ Test worker] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2022-09-23 22:50:30.890 INFO 46658 --- [ Test worker] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:a23fadfa-6d6f-42ee-ad20-d0fd914a7423'
2022-09-23 22:50:31.480 INFO 46658 --- [ Test worker] c.t.j.j.repository.UserRepositoryTest : Started UserRepositoryTest in 3.69 seconds (JVM running for 4.79)
Repository User : [User(id=tom, num=null, pwd=123, createDt=null, updateDt=null)]
2022-09-23 22:50:31.987 INFO 46658 --- [ionShutdownHook] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2022-09-23 22:50:31.989 INFO 46658 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2022-09-23 22:50:31.992 INFO 46658 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
BUILD SUCCESSFUL in 6s
4 actionable tasks: 2 executed, 2 up-to-date
10:50:32 PM: 실행이 완료되었습니다 ':test --tests "com.test.jpa.jpaProj.repository.UserRepositoryTest.crud"'.
2. JPARepository 인터페이스
create(INSERT) - save(), saveAll()
1. save() 소스
@SpringBootTest
class UserRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
void crud() {
// 1.
// save User 테이블 생성 후 인자에 있는 값으로 저장
userRepository.save(new User("tom", "123"));
}
1. save() 결과
Hibernate:
select
user0_.id as id1_0_0_,
user0_.create_dt as create_d2_0_0_,
user0_.num as num3_0_0_,
user0_.pwd as pwd4_0_0_,
user0_.update_dt as update_d5_0_0_
from
tb_user user0_
where
user0_.id=?
Hibernate:
insert
into
tb_user
(create_dt, num, pwd, update_dt, id)
values
(?, ?, ?, ?, ?)
2. saveAll() 소스
@SpringBootTest
class UserRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
void crud() {
// 5. saveAll 사용하여 여러개 insert
User user1 = new User("jack", "s");
User user2 = new User("bro", "d");
//insert
userRepository.saveAll(Lists.newArrayList(user1, user2));
//select
List<User> list = userRepository.findAll();
list.forEach(System.out::println);
}
2. saveAll() 결과
Hibernate:
select
user0_.id as id1_0_0_,
user0_.create_dt as create_d2_0_0_,
user0_.num as num3_0_0_,
user0_.pwd as pwd4_0_0_,
user0_.update_dt as update_d5_0_0_
from
tb_user user0_
where
user0_.id=?
Hibernate:
select
user0_.id as id1_0_0_,
user0_.create_dt as create_d2_0_0_,
user0_.num as num3_0_0_,
user0_.pwd as pwd4_0_0_,
user0_.update_dt as update_d5_0_0_
from
tb_user user0_
where
user0_.id=?
Hibernate:
insert
into
tb_user
(create_dt, num, pwd, update_dt, id)
values
(?, ?, ?, ?, ?)
Hibernate:
insert
into
tb_user
(create_dt, num, pwd, update_dt, id)
values
(?, ?, ?, ?, ?)
Hibernate:
select
user0_.id as id1_0_,
user0_.create_dt as create_d2_0_,
user0_.num as num3_0_,
user0_.pwd as pwd4_0_,
user0_.update_dt as update_d5_0_
from
tb_user user0_
User(id=sera, num=1, pwd=sera, createDt=2022-10-12T14:01:54.100921, updateDt=2022-10-12T14:01:54.100921)
User(id=tomy, num=2, pwd=tomy, createDt=2022-10-12T14:01:54.108098, updateDt=2022-10-12T14:01:54.108098)
User(id=dora, num=3, pwd=dora, createDt=2022-10-12T14:01:54.111595, updateDt=2022-10-12T14:01:54.111595)
User(id=okay, num=4, pwd=okay, createDt=2022-10-12T14:01:54.112741, updateDt=2022-10-12T14:01:54.112741)
User(id=tommy, num=5, pwd=tommy, createDt=2022-10-12T14:01:54.113934, updateDt=2022-10-12T14:01:54.113934)
User(id=jack, num=null, pwd=s, createDt=null, updateDt=null)
User(id=bro, num=null, pwd=d, createDt=null, updateDt=null)
read(SELECT) - findAll(), findAllById(), getOne(), getRefereneceById(), findById(), count(), existsById()
1. findAll() 소스
@SpringBootTest
class UserRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
void crud() {
// 2.
// User 테이블에 모든 데이터를 List 형태로 가져옴(전체 조회)
System.out.println("Repository User : " + userRepository.findAll());
userRepository.findAll().forEach(System.out::println); // toString
}
1. findAll() 결과
Hibernate:
select
user0_.id as id1_0_,
user0_.create_dt as create_d2_0_,
user0_.num as num3_0_,
user0_.pwd as pwd4_0_,
user0_.update_dt as update_d5_0_
from
tb_user user0_
Repository User : [User(id=sera, num=1, pwd=sera, createDt=2022-10-12T13:56:57.010900, updateDt=2022-10-12T13:56:57.010900), User(id=tomy, num=2, pwd=tomy, createDt=2022-10-12T13:56:57.015226, updateDt=2022-10-12T13:56:57.015226), User(id=dora, num=3, pwd=dora, createDt=2022-10-12T13:56:57.016021, updateDt=2022-10-12T13:56:57.016021), User(id=okay, num=4, pwd=okay, createDt=2022-10-12T13:56:57.016772, updateDt=2022-10-12T13:56:57.016772), User(id=tommy, num=5, pwd=tommy, createDt=2022-10-12T13:56:57.017385, updateDt=2022-10-12T13:56:57.017385)]
Hibernate:
select
user0_.id as id1_0_,
user0_.create_dt as create_d2_0_,
user0_.num as num3_0_,
user0_.pwd as pwd4_0_,
user0_.update_dt as update_d5_0_
from
tb_user user0_
User(id=sera, num=1, pwd=sera, createDt=2022-10-12T13:56:57.010900, updateDt=2022-10-12T13:56:57.010900)
User(id=tomy, num=2, pwd=tomy, createDt=2022-10-12T13:56:57.015226, updateDt=2022-10-12T13:56:57.015226)
User(id=dora, num=3, pwd=dora, createDt=2022-10-12T13:56:57.016021, updateDt=2022-10-12T13:56:57.016021)
User(id=okay, num=4, pwd=okay, createDt=2022-10-12T13:56:57.016772, updateDt=2022-10-12T13:56:57.016772)
User(id=tommy, num=5, pwd=tommy, createDt=2022-10-12T13:56:57.017385, updateDt=2022-10-12T13:56:57.017385)
1. findAll(sort) 소스
@SpringBootTest
class UserRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
void crud() {
// 3. findAll을 사용하여 Sorting
// num으로 역순
List<User> users = userRepository.findAll(Sort.by(Sort.Direction.DESC, "num"));
users.forEach(System.out::println);
}
1. findAll(sort) 결과
Hibernate:
select
user0_.id as id1_0_,
user0_.create_dt as create_d2_0_,
user0_.num as num3_0_,
user0_.pwd as pwd4_0_,
user0_.update_dt as update_d5_0_
from
tb_user user0_
order by
user0_.num desc
User(id=tommy, num=5, pwd=tommy, createDt=2022-10-12T13:58:18.396988, updateDt=2022-10-12T13:58:18.396988)
User(id=okay, num=4, pwd=okay, createDt=2022-10-12T13:58:18.396650, updateDt=2022-10-12T13:58:18.396650)
User(id=dora, num=3, pwd=dora, createDt=2022-10-12T13:58:18.396242, updateDt=2022-10-12T13:58:18.396242)
User(id=tomy, num=2, pwd=tomy, createDt=2022-10-12T13:58:18.395778, updateDt=2022-10-12T13:58:18.395778)
User(id=sera, num=1, pwd=sera, createDt=2022-10-12T13:58:18.393920, updateDt=2022-10-12T13:58:18.393920)
2. findAllById() 소스
@SpringBootTest
class UserRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
void crud() {
// 4. findAllById를 사용하여 ID를 IN으로 조회
// Lists.newArrayList 는 List 객체를 생성후 list.add("sera")랑 같다. assertj 패키지의 함수 사용
List<User> users = userRepository.findAllById(Lists.newArrayList("sera", "tommy", "tom"));
users.forEach(System.out::println);
}
2. findAllById() 결과
Hibernate:
select
user0_.id as id1_0_,
user0_.create_dt as create_d2_0_,
user0_.num as num3_0_,
user0_.pwd as pwd4_0_,
user0_.update_dt as update_d5_0_
from
tb_user user0_
where
user0_.id in (
? , ? , ?
)
User(id=sera, num=1, pwd=sera, createDt=2022-10-12T13:59:21.614585, updateDt=2022-10-12T13:59:21.614585)
User(id=tommy, num=5, pwd=tommy, createDt=2022-10-12T13:59:21.621134, updateDt=2022-10-12T13:59:21.621134)
3. getOne() 소스
@Transactional
@SpringBootTest
class UserRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
void crud() {
// 7. getOne / getReferenceById 하여 특정 값 select
User user = userRepository.getOne("tommy"); // session 에러 발생하여 @Transactional 어노테이션 사용하여 getOne과 출력하는것까지 연결해준다.
System.out.println(user);
}
}
3. getOne() 결과
2022-10-12 14:07:28.867 INFO 40109 --- [ Test worker] o.s.t.c.transaction.TransactionContext : Began transaction (1) for test context [DefaultTestContext@652a7737 testClass = UserRepositoryTest, testInstance = com.test.jpa.jpaProj.repository.UserRepositoryTest@2d36add1, testMethod = crud@UserRepositoryTest, testException = [null], mergedContextConfiguration = [WebMergedContextConfiguration@5b7ea70d testClass = UserRepositoryTest, locations = '{}', classes = '{class com.test.jpa.jpaProj.JpaProjApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}', contextCustomizers = set[org.springframework.boot.test.autoconfigure.actuate.metrics.MetricsExportContextCustomizerFactory$DisableMetricExportContextCustomizer@1984b1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@b4711e2, org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@401f7633, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@2c78d320, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@4716be8b, org.springframework.boot.test.context.SpringBootTestArgs@1, org.springframework.boot.test.context.SpringBootTestWebEnvironment@37271612], resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map['org.springframework.test.context.web.ServletTestExecutionListener.activateListener' -> true, 'org.springframework.test.context.web.ServletTestExecutionListener.populatedRequestContextHolder' -> true, 'org.springframework.test.context.web.ServletTestExecutionListener.resetRequestContextHolder' -> true, 'org.springframework.test.context.event.ApplicationEventsTestExecutionListener.recordApplicationEvents' -> false]]; transaction manager [org.springframework.orm.jpa.JpaTransactionManager@2651e783]; rollback [true]
Hibernate:
select
user0_.id as id1_0_0_,
user0_.create_dt as create_d2_0_0_,
user0_.num as num3_0_0_,
user0_.pwd as pwd4_0_0_,
user0_.update_dt as update_d5_0_0_
from
tb_user user0_
where
user0_.id=?
User(id=tommy, num=5, pwd=tommy, createDt=2022-10-12T14:07:28.772, updateDt=2022-10-12T14:07:28.772)
2022-10-12 14:07:29.134 INFO 40109 --- [ Test worker] o.s.t.c.transaction.TransactionContext : Rolled back transaction for test: [DefaultTestContext@652a7737 testClass = UserRepositoryTest, testInstance = com.test.jpa.jpaProj.repository.UserRepositoryTest@2d36add1, testMethod = crud@UserRepositoryTest, testException = [null], mergedContextConfiguration = [WebMergedContextConfiguration@5b7ea70d testClass = UserRepositoryTest, locations = '{}', classes = '{class com.test.jpa.jpaProj.JpaProjApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}', contextCustomizers = set[org.springframework.boot.test.autoconfigure.actuate.metrics.MetricsExportContextCustomizerFactory$DisableMetricExportContextCustomizer@1984b1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@b4711e2, org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@401f7633, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@2c78d320, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@4716be8b, org.springframework.boot.test.context.SpringBootTestArgs@1, org.springframework.boot.test.context.SpringBootTestWebEnvironment@37271612], resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map['org.springframework.test.context.web.ServletTestExecutionListener.activateListener' -> true, 'org.springframework.test.context.web.ServletTestExecutionListener.populatedRequestContextHolder' -> true, 'org.springframework.test.context.web.ServletTestExecutionListener.resetRequestContextHolder' -> true, 'org.springframework.test.context.event.ApplicationEventsTestExecutionListener.recordApplicationEvents' -> false]]
4. getRefereneceById() 소스
@Transactional
@SpringBootTest
class UserRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
void crud() {
// 7. getOne / getReferenceById 하여 특정 값 select
User user = userRepository.getReferenceById("tommy"); // session 에러 발생하여 @Transactional 어노테이션 사용하여 getReferenceById 출력하는것까지 연결해준다.
System.out.println(user);
}
}
4. getRefereneceById() 결과
2022-10-12 14:06:26.175 INFO 40067 --- [ Test worker] o.s.t.c.transaction.TransactionContext : Began transaction (1) for test context [DefaultTestContext@652a7737 testClass = UserRepositoryTest, testInstance = com.test.jpa.jpaProj.repository.UserRepositoryTest@2d36add1, testMethod = crud@UserRepositoryTest, testException = [null], mergedContextConfiguration = [WebMergedContextConfiguration@5b7ea70d testClass = UserRepositoryTest, locations = '{}', classes = '{class com.test.jpa.jpaProj.JpaProjApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}', contextCustomizers = set[org.springframework.boot.test.autoconfigure.actuate.metrics.MetricsExportContextCustomizerFactory$DisableMetricExportContextCustomizer@1984b1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@b4711e2, org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@401f7633, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@2c78d320, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@4716be8b, org.springframework.boot.test.context.SpringBootTestArgs@1, org.springframework.boot.test.context.SpringBootTestWebEnvironment@37271612], resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map['org.springframework.test.context.web.ServletTestExecutionListener.activateListener' -> true, 'org.springframework.test.context.web.ServletTestExecutionListener.populatedRequestContextHolder' -> true, 'org.springframework.test.context.web.ServletTestExecutionListener.resetRequestContextHolder' -> true, 'org.springframework.test.context.event.ApplicationEventsTestExecutionListener.recordApplicationEvents' -> false]]; transaction manager [org.springframework.orm.jpa.JpaTransactionManager@2651e783]; rollback [true]
Hibernate:
select
user0_.id as id1_0_0_,
user0_.create_dt as create_d2_0_0_,
user0_.num as num3_0_0_,
user0_.pwd as pwd4_0_0_,
user0_.update_dt as update_d5_0_0_
from
tb_user user0_
where
user0_.id=?
User(id=tommy, num=5, pwd=tommy, createDt=2022-10-12T14:06:26.089231, updateDt=2022-10-12T14:06:26.089231)
2022-10-12 14:06:26.469 INFO 40067 --- [ Test worker] o.s.t.c.transaction.TransactionContext : Rolled back transaction for test: [DefaultTestContext@652a7737 testClass = UserRepositoryTest, testInstance = com.test.jpa.jpaProj.repository.UserRepositoryTest@2d36add1, testMethod = crud@UserRepositoryTest, testException = [null], mergedContextConfiguration = [WebMergedContextConfiguration@5b7ea70d testClass = UserRepositoryTest, locations = '{}', classes = '{class com.test.jpa.jpaProj.JpaProjApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}', contextCustomizers = set[org.springframework.boot.test.autoconfigure.actuate.metrics.MetricsExportContextCustomizerFactory$DisableMetricExportContextCustomizer@1984b1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@b4711e2, org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@401f7633, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@2c78d320, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@4716be8b, org.springframework.boot.test.context.SpringBootTestArgs@1, org.springframework.boot.test.context.SpringBootTestWebEnvironment@37271612], resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map['org.springframework.test.context.web.ServletTestExecutionListener.activateListener' -> true, 'org.springframework.test.context.web.ServletTestExecutionListener.populatedRequestContextHolder' -> true, 'org.springframework.test.context.web.ServletTestExecutionListener.resetRequestContextHolder' -> true, 'org.springframework.test.context.event.ApplicationEventsTestExecutionListener.recordApplicationEvents' -> false]]
5. findById() 소스 - Optional사용
@SpringBootTest
class UserRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
void crud() {
// 8. findById
Optional<User> user = userRepository.findById("sera");
System.out.println(user);
}
}
5. findById() 결과 - Optional사용
Hibernate:
select
user0_.id as id1_0_0_,
user0_.create_dt as create_d2_0_0_,
user0_.num as num3_0_0_,
user0_.pwd as pwd4_0_0_,
user0_.update_dt as update_d5_0_0_
from
tb_user user0_
where
user0_.id=?
Optional[User(id=sera, num=1, pwd=sera, createDt=2022-10-12T14:09:16.592033, updateDt=2022-10-12T14:09:16.592033)]
5. findById() 소스 - orElse()사용하여 null
@SpringBootTest
class UserRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
void crud() {
// 8. findById
User user = userRepository.findById("sera").orElse(null); // sera라는 값이 존재하지 않을 경우 null반환
System.out.println(user);
}
}
5. findById() 결과 - orElse()사용하여 null
Hibernate:
select
user0_.id as id1_0_0_,
user0_.create_dt as create_d2_0_0_,
user0_.num as num3_0_0_,
user0_.pwd as pwd4_0_0_,
user0_.update_dt as update_d5_0_0_
from
tb_user user0_
where
user0_.id=?
User(id=sera, num=1, pwd=sera, createDt=2022-10-12T14:11:16.967148, updateDt=2022-10-12T14:11:16.967148)
6. count() 소스
@SpringBootTest
class UserRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
void crud() {
// 9. count()
long count = userRepository.count();
System.out.println(count);
}
}
6. count() 결과
Hibernate:
select
count(*) as col_0_0_
from
tb_user user0_
5
7. existsById() 소스
@SpringBootTest
class UserRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
void crud() {
// 10. existsById()
// count() 함수 쿼리가 동작
boolean ext = userRepository.existsById("1");
System.out.println(ext);
}
}
7. existsById() 결과
Hibernate:
select
count(*) as col_0_0_
from
tb_user user0_
where
user0_.id=?
false
update(UPDATE) - save()
1. save() 소스
// update
userRepository.save(new User("arma","arma"));
User user = userRepository.findById("tomy").orElseThrow(RuntimeException::new);
user.setPwd("arma");
userRepository.save(user);
userRepository.findAll().forEach(System.out::println);
1. save() 결과
Hibernate:
select
user0_.id as id1_0_0_,
user0_.create_dt as create_d2_0_0_,
user0_.num as num3_0_0_,
user0_.pwd as pwd4_0_0_,
user0_.update_dt as update_d5_0_0_
from
tb_user user0_
where
user0_.id=?
Hibernate:
insert
into
tb_user
(create_dt, num, pwd, update_dt, id)
values
(?, ?, ?, ?, ?)
Hibernate:
select
user0_.id as id1_0_0_,
user0_.create_dt as create_d2_0_0_,
user0_.num as num3_0_0_,
user0_.pwd as pwd4_0_0_,
user0_.update_dt as update_d5_0_0_
from
tb_user user0_
where
user0_.id=?
Hibernate:
select
user0_.id as id1_0_0_,
user0_.create_dt as create_d2_0_0_,
user0_.num as num3_0_0_,
user0_.pwd as pwd4_0_0_,
user0_.update_dt as update_d5_0_0_
from
tb_user user0_
where
user0_.id=?
Hibernate:
update
tb_user
set
create_dt=?,
num=?,
pwd=?,
update_dt=?
where
id=?
Hibernate:
select
user0_.id as id1_0_,
user0_.create_dt as create_d2_0_,
user0_.num as num3_0_,
user0_.pwd as pwd4_0_,
user0_.update_dt as update_d5_0_
from
tb_user user0_
User(id=sera, num=1, pwd=sera, createDt=2022-10-12T14:23:01.086413, updateDt=2022-10-12T14:23:01.086413)
User(id=tomy, num=2, pwd=arma, createDt=2022-10-12T14:23:01.088870, updateDt=2022-10-12T14:23:01.088870)
User(id=dora, num=3, pwd=dora, createDt=2022-10-12T14:23:01.089399, updateDt=2022-10-12T14:23:01.089399)
User(id=okay, num=4, pwd=okay, createDt=2022-10-12T14:23:01.090130, updateDt=2022-10-12T14:23:01.090130)
User(id=tommy, num=5, pwd=tommy, createDt=2022-10-12T14:23:01.090627, updateDt=2022-10-12T14:23:01.090627)
User(id=arma, num=null, pwd=arma, createDt=null, updateDt=null)
delete(DELETE) - delete(), deleteById(), deleteAll(), deleteInBatch()
1. delete() 소스 - orElse()
// 11. delete()
userRepository.delete(userRepository.findById("sera").orElse(null));
1. delete() 결과 - orElse()
Hibernate:
select
user0_.id as id1_0_0_,
user0_.create_dt as create_d2_0_0_,
user0_.num as num3_0_0_,
user0_.pwd as pwd4_0_0_,
user0_.update_dt as update_d5_0_0_
from
tb_user user0_
where
user0_.id=?
Hibernate:
select
user0_.id as id1_0_0_,
user0_.create_dt as create_d2_0_0_,
user0_.num as num3_0_0_,
user0_.pwd as pwd4_0_0_,
user0_.update_dt as update_d5_0_0_
from
tb_user user0_
where
user0_.id=?
Hibernate:
delete
from
tb_user
where
id=?
1. delete() 소스 - orElseThrow()
// 11. delete()
userRepository.delete(userRepository.findById("sera").orElseThrow(RuntimeException::new));
1. delete() 결과 - orElseThrow()
Hibernate:
select
user0_.id as id1_0_0_,
user0_.create_dt as create_d2_0_0_,
user0_.num as num3_0_0_,
user0_.pwd as pwd4_0_0_,
user0_.update_dt as update_d5_0_0_
from
tb_user user0_
where
user0_.id=?
Hibernate:
select
user0_.id as id1_0_0_,
user0_.create_dt as create_d2_0_0_,
user0_.num as num3_0_0_,
user0_.pwd as pwd4_0_0_,
user0_.update_dt as update_d5_0_0_
from
tb_user user0_
where
user0_.id=?
Hibernate:
delete
from
tb_user
where
id=?
2. deleteById() 소스
// 12. deleteById()
userRepository.deleteById("tommy");
userRepository.findAll().forEach(System.out::println);
2. deleteById() 결과
Hibernate:
select
user0_.id as id1_0_0_,
user0_.create_dt as create_d2_0_0_,
user0_.num as num3_0_0_,
user0_.pwd as pwd4_0_0_,
user0_.update_dt as update_d5_0_0_
from
tb_user user0_
where
user0_.id=?
Hibernate:
select
user0_.id as id1_0_0_,
user0_.create_dt as create_d2_0_0_,
user0_.num as num3_0_0_,
user0_.pwd as pwd4_0_0_,
user0_.update_dt as update_d5_0_0_
from
tb_user user0_
where
user0_.id=?
Hibernate:
delete
from
tb_user
where
id=?
Hibernate:
select
user0_.id as id1_0_0_,
user0_.create_dt as create_d2_0_0_,
user0_.num as num3_0_0_,
user0_.pwd as pwd4_0_0_,
user0_.update_dt as update_d5_0_0_
from
tb_user user0_
where
user0_.id=?
Hibernate:
delete
from
tb_user
where
id=?
Hibernate:
select
user0_.id as id1_0_,
user0_.create_dt as create_d2_0_,
user0_.num as num3_0_,
user0_.pwd as pwd4_0_,
user0_.update_dt as update_d5_0_
from
tb_user user0_
User(id=tomy, num=2, pwd=tomy, createDt=2022-10-12T14:16:59.720026, updateDt=2022-10-12T14:16:59.720026)
User(id=dora, num=3, pwd=dora, createDt=2022-10-12T14:16:59.720492, updateDt=2022-10-12T14:16:59.720492)
User(id=okay, num=4, pwd=okay, createDt=2022-10-12T14:16:59.720888, updateDt=2022-10-12T14:16:59.720888)
3. deleteAll() 소스 - deleteAll()
// 13. deleteAll()
userRepository.deleteAll();
userRepository.findAll().forEach(System.out::println);
3. deleteAll() 결과 - deleteAll()
Hibernate:
select
user0_.id as id1_0_,
user0_.create_dt as create_d2_0_,
user0_.num as num3_0_,
user0_.pwd as pwd4_0_,
user0_.update_dt as update_d5_0_
from
tb_user user0_
Hibernate:
delete
from
tb_user
where
id=?
Hibernate:
delete
from
tb_user
where
id=?
Hibernate:
delete
from
tb_user
where
id=?
Hibernate:
delete
from
tb_user
where
id=?
Hibernate:
delete
from
tb_user
where
id=?
Hibernate:
select
user0_.id as id1_0_,
user0_.create_dt as create_d2_0_,
user0_.num as num3_0_,
user0_.pwd as pwd4_0_,
user0_.update_dt as update_d5_0_
from
tb_user user0_
3. deleteAll() 소스 - deleteAll(findAllById())
// 13. deleteAll()
userRepository.deleteAll(userRepository.findAllById(Lists.newArrayList("sera","orl")));
userRepository.findAll().forEach(System.out::println);
3. deleteAll() 결과 - deleteAll(findAllById())
Hibernate:
select
user0_.id as id1_0_,
user0_.create_dt as create_d2_0_,
user0_.num as num3_0_,
user0_.pwd as pwd4_0_,
user0_.update_dt as update_d5_0_
from
tb_user user0_
where
user0_.id in (
? , ?
)
Hibernate:
select
user0_.id as id1_0_0_,
user0_.create_dt as create_d2_0_0_,
user0_.num as num3_0_0_,
user0_.pwd as pwd4_0_0_,
user0_.update_dt as update_d5_0_0_
from
tb_user user0_
where
user0_.id=?
Hibernate:
delete
from
tb_user
where
id=?
Hibernate:
select
user0_.id as id1_0_,
user0_.create_dt as create_d2_0_,
user0_.num as num3_0_,
user0_.pwd as pwd4_0_,
user0_.update_dt as update_d5_0_
from
tb_user user0_
User(id=tomy, num=2, pwd=tomy, createDt=2022-10-12T14:18:36.140060, updateDt=2022-10-12T14:18:36.140060)
User(id=dora, num=3, pwd=dora, createDt=2022-10-12T14:18:36.140654, updateDt=2022-10-12T14:18:36.140654)
User(id=okay, num=4, pwd=okay, createDt=2022-10-12T14:18:36.141245, updateDt=2022-10-12T14:18:36.141245)
User(id=tommy, num=5, pwd=tommy, createDt=2022-10-12T14:18:36.141835, updateDt=2022-10-12T14:18:36.141835)
4. deleteInBatch() 소스
// 14. deleteInBatch()
userRepository.deleteInBatch(userRepository.findAllById(Lists.newArrayList("sera","orl")));
userRepository.findAll().forEach(System.out::println);
4. deleteInBatch() 결과
Hibernate:
select
user0_.id as id1_0_,
user0_.create_dt as create_d2_0_,
user0_.num as num3_0_,
user0_.pwd as pwd4_0_,
user0_.update_dt as update_d5_0_
from
tb_user user0_
where
user0_.id in (
? , ?
)
Hibernate:
delete
from
tb_user
where
id=?
Hibernate:
select
user0_.id as id1_0_,
user0_.create_dt as create_d2_0_,
user0_.num as num3_0_,
user0_.pwd as pwd4_0_,
user0_.update_dt as update_d5_0_
from
tb_user user0_
User(id=tomy, num=2, pwd=tomy, createDt=2022-10-12T14:19:16.539259, updateDt=2022-10-12T14:19:16.539259)
User(id=dora, num=3, pwd=dora, createDt=2022-10-12T14:19:16.539689, updateDt=2022-10-12T14:19:16.539689)
User(id=okay, num=4, pwd=okay, createDt=2022-10-12T14:19:16.540029, updateDt=2022-10-12T14:19:16.540029)
User(id=tommy, num=5, pwd=tommy, createDt=2022-10-12T14:19:16.540331, updateDt=2022-10-12T14:19:16.540331)
5. deleteAllInBatch() 소스
// 15. deleteAllInBatch()
userRepository.deleteAllInBatch();
userRepository.findAll().forEach(System.out::println);
5. deleteAllInBatch() 결과
Hibernate:
delete
from
tb_user
Hibernate:
select
user0_.id as id1_0_,
user0_.create_dt as create_d2_0_,
user0_.num as num3_0_,
user0_.pwd as pwd4_0_,
user0_.update_dt as update_d5_0_
from
tb_user user0_
Paging
1. Paging 소스
// 16. paging()
Page<User> users = userRepository.findAll(PageRequest.of(0,3));
System.out.println("page : "+users);
System.out.println("getTotalElements : "+users.getTotalElements());
System.out.println("getTotalPages : "+users.getTotalPages());
System.out.println("getNumberOfElements : "+users.getNumberOfElements());
System.out.println("getSort : "+users.getSort());
System.out.println("getSize : "+users.getSize());
1. Paging 결과
Hibernate:
select
user0_.id as id1_0_,
user0_.create_dt as create_d2_0_,
user0_.num as num3_0_,
user0_.pwd as pwd4_0_,
user0_.update_dt as update_d5_0_
from
tb_user user0_ limit ?
Hibernate:
select
count(user0_.id) as col_0_0_
from
tb_user user0_
page : Page 1 of 2 containing com.test.jpa.jpaProj.vo.User instances
getTotalElements : 5
getTotalPages : 2
getNumberOfElements : 3
getSort : UNSORTED
getSize : 3
QBE(QueryByExample)
: 단순히 인터페이스를 통해 동적으로 쿼리를 만드는 기능을 제공하는 기술
Example? probe? ExampleMatcher?
1. QueryByExample 소스
// 17. Query By Example
userRepository.findAll().forEach(System.out::println);
ExampleMatcher matcher = ExampleMatcher.matching()
.withIgnorePaths("id")
.withMatcher("pwd",endsWith());
Example<User> exam = Example.of(new User("sera","my"), matcher);
//Example<User> exam = Example.of(new User("tom","my"));
userRepository.findAll(exam).forEach(System.out::println);
1. QueryByExample 결과
Hibernate:
select
user0_.id as id1_0_,
user0_.create_dt as create_d2_0_,
user0_.num as num3_0_,
user0_.pwd as pwd4_0_,
user0_.update_dt as update_d5_0_
from
tb_user user0_
User(id=sera, num=1, pwd=sera, createDt=2022-10-12T14:22:03.097407, updateDt=2022-10-12T14:22:03.097407)
User(id=tomy, num=2, pwd=tomy, createDt=2022-10-12T14:22:03.099397, updateDt=2022-10-12T14:22:03.099397)
User(id=dora, num=3, pwd=dora, createDt=2022-10-12T14:22:03.099883, updateDt=2022-10-12T14:22:03.099883)
User(id=okay, num=4, pwd=okay, createDt=2022-10-12T14:22:03.100298, updateDt=2022-10-12T14:22:03.100298)
User(id=tommy, num=5, pwd=tommy, createDt=2022-10-12T14:22:03.100657, updateDt=2022-10-12T14:22:03.100657)
Hibernate:
select
user0_.id as id1_0_,
user0_.create_dt as create_d2_0_,
user0_.num as num3_0_,
user0_.pwd as pwd4_0_,
user0_.update_dt as update_d5_0_
from
tb_user user0_
where
user0_.pwd like ? escape ?
User(id=tomy, num=2, pwd=tomy, createDt=2022-10-12T14:22:03.099397, updateDt=2022-10-12T14:22:03.099397)
User(id=tommy, num=5, pwd=tommy, createDt=2022-10-12T14:22:03.100657, updateDt=2022-10-12T14:22:03.100657)
JpaRepository인터페이스의 구현체인 SImpleJpaRepository 클래스

Optional 클래스?
'Spring > 1-3. JPA' 카테고리의 다른 글
| (5. Spring Data JPA) Entity Listener 활용 (1) | 2022.10.18 |
|---|---|
| (4. Spring Data JPA) Entity의 기본속성(@Entity) (0) | 2022.10.17 |
| (3. Spring Data JPA)QueryMethod 쿼리메소드 정의 및 실습 (0) | 2022.10.15 |
| (2. Spring Data JPA)JpaRepository의 findById와 getOne 차이 (0) | 2022.10.12 |
| JPA(Java Persistence API) (0) | 2022.09.22 |