<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.springjpa</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-data-jpa</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</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>
</project>
@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Table(
name = "tbl_student",
uniqueConstraints = @UniqueConstraint(
name = "emailid_unique",
columnNames = "email_address"
)
) - (1)
public class Student {
@Id
@SequenceGenerator(
name = "student_sequence",
sequenceName = "student_sequence",
allocationSize = 1
) - (2)
@GeneratedValue(
strategy = GenerationType.SEQUENCE,
generator = "student_sequence"
) - (3)
private Long studentId;
private String firstName;
private String lastName;
@Column(
name = "email_address",
nullable = false
) - (4)
private String emailId;
private String guardianName;
private String guardianEmail;
private String guardianMobile;
}
(1) @Table
(2) @SequenceGenerator
name : 식별자 생성기의 이름 (필수)
sequenceName : 데이터베이스에 등록된 시퀀스 명 (DEFAULT: hibernate_sequence)
initialiValue : 시퀀스의 시작값, 최초 생성시에 사용된다. (DEFAULT: 1)
allocationSize : 시퀀스 호출시마다 증가하는값, 성능최적화에 사용되며 데이터베이스 시퀀스값이 1 씩 증가한다면 반드시 1로 지정해야한다.
(3) @GeneratedValue
(4) @Column
테스팅
@Repository
// generic에 엔티티와 PK의 타입 지정
public interface StudentRepository extends JpaRepository<Student, Long> {
}
@SpringBootTest
//@DataJpaTest
class StudentRepositoryTest {
@Autowired
private StudentRepository studentRepository;
@Test
public void saveStudent() {
Student student = Student.builder() - (1)
.emailId("test@gmail.com")
.firstName("lim")
.lastName("jisub")
.guardianName("Heedo")
.guardianEmail("heedo@gmail.com")
.guardianMobile("01012345678")
.build();
studentRepository.save(student);
}
@Test
public void printAllStudent() {
List<Student> studentList =
studentRepository.findAll();
System.out.println("studentList = " + studentList);
}
}
(1) Builder pattern
참고 : https://mangkyu.tistory.com/163
Guardian CLASS
@Embeddable - (1)
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@AttributeOverrides({
@AttributeOverride(
name = "name",
column = @Column(name = "guardian_name")
),
@AttributeOverride(
name = "email",
column = @Column(name = "guardian_email")
),
@AttributeOverride(
name = "mobile",
column = @Column(name = "guardian_mobile")
)
}) - (2)
public class Guardian {
// student 테이블에서만 사용하기
// 컬럼명 변경
private String name;
private String email;
private String mobile;
}
STUDENT CLASS
public class Student {
...
// private String guardianName;
// private String guardianEmail;
// private String guardianMobile;
// Embeding
@Embedded - (3)
private Guardian guardian;
}
(1) @Embeddable - 기존 Entity의 특정 컬럼들을 하나의 객체로 묶는다.
(2) @AttributeOverrides - 기존 Entity와 컬럼 명이 같을 시, @AttributeOverride 속성을 통해 해당 컬럼의 컬럼명을 오버라이드 한다.
(3) @Embedded - Guardian 객체로 컬럼 설정
테스팅
@SpringBootTest
class StudentRepositoryTest {
@Autowired
private StudentRepository studentRepository;
@Test
public void saveStudentWithGuardian() {
Guardian guardian = Guardian.builder()
.name("Heedo1")
.email("heedo1@gmail.com")
.mobile("01012345678")
.build();
Student student = Student.builder()
.emailId("test1@gmail.com")
.firstName("lim1")
.lastName("jisub1")
.guardian(guardian)
.build();
studentRepository.save(student);
}
}
@Repository
public interface StudentRepository extends JpaRepository<Student, Long> {
// camelCase 적용
List<Student> findByFirstName(String firstName);
// Like 적용
List<Student> findByFirstNameContaining(String name);
List<Student> findByLastNameNotNull();
List<Student> findByGuardianName(String guardianName);
Student findByFirstNameAndLastName(String firstName,
String lastName);
}
테스팅
@SpringBootTest
class StudentRepositoryTest {
@Autowired
private StudentRepository studentRepository;
@Test
public void printStudentByFirstName() {
List<Student> students =
studentRepository.findByFirstName("lim1");
System.out.println("students = " + students);
}
@Test
public void printStudentByFirstNameContaining() {
List<Student> students =
studentRepository.findByFirstNameContaining("li");
System.out.println("students = " + students);
}
@Test
public void printStudentBasedOnGuardianName() {
List<Student> students =
studentRepository.findByGuardianName("Heedo1");
System.out.println("students = " + students);
}
@Test
public void printStudentFindByFirstNameAndLastName() {
Student students =
studentRepository.findByFirstNameAndLastName("lim1", "jisub1");
System.out.println("students = " + students);
}
}
@Repository
public interface StudentRepository extends JpaRepository<Student, Long> {
// JPQL
@Query("select s from Student s where s.emailId = ?1")
Student getStudentByEmailAddress(String EmailId);
@Query("select s.firstName from Student s where s.emailId = ?1")
String getStudentFirstNameByEmailAddress(String EmailId);
}
테스팅
@SpringBootTest
class StudentRepositoryTest {
@Autowired
private StudentRepository studentRepository;
@Test
public void printStudentByEmailAddress() {
Student student =
studentRepository.getStudentByEmailAddress("test1@gmail.com");
System.out.println("student = " + student);
}
@Test
public void printStudentFirstNameByEmailAddress() {
String firstName =
studentRepository.getStudentFirstNameByEmailAddress("test1@gmail.com");
System.out.println("firstName = " + firstName);
}
}
@Repository
public interface StudentRepository extends JpaRepository<Student, Long> {
// Native
@Query(
value = "select * from tbl_student s where s.email_address = ?1",
nativeQuery = true
)
Student getStudentByEmailAddressNative(String emailId);
}
테스팅
@SpringBootTest
class StudentRepositoryTest {
@Autowired
private StudentRepository studentRepository;
@Test
public void printGetStudentByEmailAddressNative() {
Student student =
studentRepository.getStudentByEmailAddressNative("test1@gmail.com");
System.out.println("student = " + student);
}
}
@Repository
public interface StudentRepository extends JpaRepository<Student, Long> {
// Native Named Param
@Query(
value = "select * from tbl_student s where s.email_address = :emailId",
nativeQuery = true
)
Student getStudentByEmailAddressNativeNamedParam(@Param("emailId") String emailId);
}
테스팅
@SpringBootTest
class StudentRepositoryTest {
@Autowired
private StudentRepository studentRepository;
@Test
public void printGetStudentByEmailAddressNativeNamedParam() {
Student student =
studentRepository.getStudentByEmailAddressNativeNamedParam("test1@gmail.com");
System.out.println("student = " + student);
}
}
@Repository
public interface StudentRepository extends JpaRepository<Student, Long> {
@Modifying // @Query Annotation으로 작성 된 변경, 삭제 쿼리 메서드를 사용할 때 필요
@Transactional // 트랜잭션 처리
@Query(
value = "update tbl_student set first_name = ?1 where email_address = ?2",
nativeQuery = true
)
int updateStudentNameByEmailId(String firstName, String emailId);
}
테스팅
@SpringBootTest
class StudentRepositoryTest {
@Autowired
private StudentRepository studentRepository;
@Test
public void updateStudentNameByEmailIdTest() {
studentRepository.updateStudentNameByEmailId("lim33", "test1@gmail.com");
}
}
참고
Spring Data JPA Tutorial | Full In-depth Course - Daily Code Buffer
https://ncucu.me/191
https://dololak.tistory.com/479