CRUD 의 Create 단계에서 보았듯이, 이번 Read 역시 비슷한 process 로 development 하면 된다. 과정은 다음과 같다.

  1. DAO Interface 에 새로운 method 추가
  2. DAO Implementation 에 해당 method implement
  3. main app 을 update
Step 1: Add new method to DAO Interface
import com.lucvs.cruddemo.entity.Student;
 
public interface StudentDAO {
	...
	Student findById(Integer id);
}

id 를 argument 로 사용하는 findById 를 declare 한다.

Step 2: Define DAO Implementation
public class StudentDAOImpl implements StudentDAO {
	private EntityManager entityManager;
	...
 
	@Override
	public Student findById(Integer id) {
		return entityManager.find(Student.class, id);
	}
}

entityManager.find 를 사용하여 parameter 로 받은 id 값을 기준으로, Student entity class 에 대한 table 에서 해당하는 row 를 찾는다. 만약 id 에 해당하는 row 가 없다면, null 을 return 한다.

위 코드에서 볼 수 있듯이 Create 단계의 Implementation 에서는 @Transactional annotation 을 통하여 Create 관련 method 에 대한 작업이 atomic 하게 수행되도록 하였다.

그러나, Read 단계에서는 Database 의 data 자체나 structure 를 변경하지 않고 단순히 reading 만 하기 때문에 굳이 @Transactional 을 사용하여 Read 에 대한 overhead 를 키울 이유가 없다. 즉, performance 에서의 이점을 위한 것이다.

Step 3: Update Main Application
@SpringBootApplication 
public class CruddemoApplication {
	public static void main(String[] args) {
		SpringApplication.run(CruddemoApplication.class, args);	
	}
 
	@Bean
	public CommandLineRunner commandLineRunner(StudentDAO studentDAO) {
		return runner -> {
			readStudent(studentDAO);
		}
	}
 
	private void readStudent(StudentDAO studentDAO) {
		...
		// retrieve student based on the id: primary key
		Student myStudent = studentDAO.findById(tempStudent.getId());
		System.out.println("Found the student: " + myStudent);
	}
}
Read - Test

Database 를 TRUNCATE 를 통하여 초기화하고 하나의 object 를 생성하여 저장한 뒤, 해당 object 를 retrieve 하는 식으로 test 를 진행해보자.

위와 같이 성공적으로 저장된 object 의 data 를 retrieve 한 것을 볼 수 있다.