20 JPA(Java Persistence API)
p396 - build.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '3.3.4'
id 'io.spring.dependency-management' version '1.1.6'
}
group = 'spring.jdbc'
version = '0.0.1-SNAPSHOT'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
// implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
testCompileOnly 'org.projectlombok:lombok'
testAnnotationProcessor 'org.projectlombok:lombok'
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.3' // MyBatis 의존성 추가
implementation 'org.springframework.boot:spring-boot-starter-data-jpa' // JPA 추가
}
tasks.named('test') {
useJUnitPlatform()
}
p 397 - src/reousrces/application.properties
# Application Name
spring.application.name=template
# MySQL Database Configuration
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=1234
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
# HikariCP Configuration
spring.datasource.hikari.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.pool-name=HikariPool
# MyBatis
mybatis.type-aliases-package=spring.jdbc.template.domain
mybatis.configuration.map-underscore-to-camel-case=true
logging.level.spring.jdbc.template.mybatis=trace
# JPA
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.orm.jdbc.bind=TRACE
p398 - src/main/java/spring/jdbc/template/domain/User
@Getter @Setter
@Entity
public class User {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long userIdx;
@Column(name="user_id", length = 255)
private String userId;
@Column(name = "age")
private int age;
public User(){}
public User(String userId, int age) {
this.userId = userId;
this.age = age;
}
}
p399, 400 - src/main/java/spring/jdbc/template/repository/UserJpaRepositoryImpl
@Slf4j
@Repository
@Transactional
public class UserJpaRepositoryImpl implements UserRepository{
@PersistenceContext
private EntityManager entityManager;
@Override
public User save(User user) {
entityManager.persist(user);
return user;
}
@Override
public void update(Long userIdx, UserUpdateDto userUpdateDto) {
User user = entityManager.find(User.class, userIdx);
user.setUserId(userUpdateDto.getUserId());
user.setAge(userUpdateDto.getAge());
}
@Override
public Optional<User> findByIdx(Long userIdx) {
User user = entityManager.find(User.class, userIdx);
return Optional.ofNullable(user);
}
@Override
public List<User> findAll(UserListDto dto) {
// User는 domain 안에 User 클래스를 말함
String jpql = "SELECT u FROM User u WHERE 1=1";
StringBuilder queryBuilder = new StringBuilder(jpql);
if (dto.getUserId() != null && !dto.getUserId().isEmpty()) {
queryBuilder.append(" AND u.userId = :userId");
}
if (dto.getMinAge() != null) {
queryBuilder.append(" AND u.age >= :minAge");
}
if (dto.getMaxAge() != null) {
queryBuilder.append(" AND u.age <= :maxAge");
}
TypedQuery<User> query = entityManager.createQuery(queryBuilder.toString(), User.class);
if (dto.getUserId() != null && !dto.getUserId().isEmpty()) {
query.setParameter("userId", dto.getUserId());
}
if (dto.getMinAge() != null) {
query.setParameter("minAge", dto.getMinAge());
}
if (dto.getMaxAge() != null) {
query.setParameter("maxAge", dto.getMaxAge());
}
return query.getResultList();
}
}
p401 ~ 403 - src/test/java/spring/jdbc/template/repository/UserJpaRepositoryImplTest
@SpringBootTest
@Transactional
public class UserJpaRepositoryImplTest {
@PersistenceContext
private EntityManager entityManager;
@Autowired
private UserJpaRepositoryImpl userJpaRepository;
@BeforeEach
public void setUp() {
// 테스트 데이터를 추가합니다.
User user1 = new User("user1", 25);
User user2 = new User("user2", 30);
User user3 = new User("user3", 35);
entityManager.persist(user1);
entityManager.persist(user2);
entityManager.persist(user3);
}
@Test
public void testSave() {
// 새로운 사용자 저장
User newUser = new User("user4", 28);
userJpaRepository.save(newUser);
// 저장된 사용자 검증
UserListDto dto = new UserListDto("user4", null, null);
List<User> users = userJpaRepository.findAll(dto);
assertThat(users).hasSize(1);
assertThat(users.get(0).getUserId()).isEqualTo("user4");
assertThat(users.get(0).getAge()).isEqualTo(28);
}
@Test
public void testUpdate() {
// 사용자 업데이트
UserUpdateDto updateDto = new UserUpdateDto("updatedUser1", 40);
Optional<User> userOpt = userJpaRepository.findByIdx(1L);
userOpt.ifPresent(user -> {
userJpaRepository.update(user.getUserIdx(), updateDto);
// 업데이트 검증
Optional<User> updatedUser = userJpaRepository.findByIdx(user.getUserIdx());
assertThat(updatedUser).isPresent();
assertThat(updatedUser.get().getUserId()).isEqualTo("updatedUser1");
assertThat(updatedUser.get().getAge()).isEqualTo(40);
});
}
@Test
public void testFindAll_noFilters() {
// 필터가 없는 경우, 모든 사용자가 반환되는지 확인
UserListDto dto = new UserListDto(null, null, null);
List<User> users = userJpaRepository.findAll(dto);
assertThat(users).hasSize(3);
}
@Test
public void testFindAll_withUserId() {
// 특정 userId로 필터링
UserListDto dto = new UserListDto("user1", null, null);
List<User> users = userJpaRepository.findAll(dto);
assertThat(users).hasSize(1);
assertThat(users.get(0).getUserId()).isEqualTo("user1");
}
@Test
public void testFindAll_withMinAge() {
// 최소 나이 조건으로 필터링
UserListDto dto = new UserListDto(null, 30, null);
List<User> users = userJpaRepository.findAll(dto);
assertThat(users).hasSize(2);
assertThat(users).extracting("userId").containsExactly("user2", "user3");
}
@Test
public void testFindAll_withMaxAge() {
// 최대 나이 조건으로 필터링
UserListDto dto = new UserListDto(null, null, 30);
List<User> users = userJpaRepository.findAll(dto);
assertThat(users).hasSize(2);
assertThat(users).extracting("userId").containsExactly("user1", "user2");
}
@Test
public void testFindAll_withMinAndMaxAge() {
// 최소 및 최대 나이 조건으로 필터링
UserListDto dto = new UserListDto(null, 25, 35);
List<User> users = userJpaRepository.findAll(dto);
assertThat(users).hasSize(3);
assertThat(users).extracting("userId").containsExactly("user1", "user2", "user3");
}
}
Last updated