Spring, Spring boot

JPA를 활용한 기본적인 CRUD 해보기

ron_nie 2023. 10. 26. 19:21
728x90

사전 지식

영속성 컨텍스트

각 엔티티 매니저 별로 영속성 컨텍스트 생성됨

스프링에서는 엔티티 매니저를 사용하지 않고, 컨테이너를 통해 제공되기 때문에 Factory Manager가 자동으로 관리됨(close필요 없음)

Create Persistence Context

Entity 매니저가 실행되면 영속성 컨텍스트가 생성됨. 이 컨텍스트는 매니저와 1대1 매칭. 각 매니저는 개별 영속성 컨텍스트를 가지고 있음

EntityManagerFactory factory = Persistence.createEntityManagerFactory("syntax");
EntityManager manager = factory.createEntityManager();

Transient state

객체는 생성 되었지만 영속성 컨텍스트에는 아직 올라가지 않은 상태

Managed state

영속성 컨텍스트에 들어간 상태

manager.persist(student1);

Entity transaction commit

EntityTransaction이 커밋을 수행할 경우 flush()가 호출되는데 이때 영속성 컨텍스트 캐시에 보관되어있는 참조 정보와 데이터베이스의 내 정보를 동기화 해준다

tx.commit();

CRUD

@Test
void testSave () {
    tx.begin();
    // 컴퓨터 공학과 생성 및 저장
    Major major = new Major("CS");
    manager.persist(major); // 영속성 컨텍스트에 저장(아직 데이터베이스에는 저장 x)

    // 학생 2명 생성 및 저장
    Student wan = new Student("김완");
    Student sun = new Student("김진선");

    // 전공을 추가
    wan.setMajor(major);
    sun.setMajor(major);

    manager.persist(wan); // 영속성 컨텍스트에 저장(아직 데이터베이스에는 저장 x)
    manager.persist(sun);

    tx.commit(); // 디비에 저장
}
@Test
void testRead() {

    // id가 1인 학생 엔티티 조회
    int id = 1;
    Student student1 = manager.find(Student.class, id);
    System.out.println("id가 1인 학생 엔티티 조회 " + student1);

    // 해당 학생의 전공 조회
    Major major1 = student1.getMajor();
    System.out.println(major1);
}

추가로 정말 주의할 점이 jpa를 사용할 때는 엔티티에 기본 생성자가 있어야한다. 조회는 트랜잭션을 킬 필요가 없다(조회를 하는 것이라 디비가 충돌날 일이 없다)

@Test
void updateRelation() {
    // 한 명의 학생 조회 후 해당 학생의 전공을 다른 학과로 변경
    tx.begin();
    int id = 1;
    Student student1 = manager.find(Student.class, id);

    Major major2 = new Major("역관광경영학과");
    manager.persist(major2);


    student1.setMajor(major2);
    manager.persist(student1);

    tx.commit();

    Student student2 = manager.find(Student.class, id);
    assertThat(student1.getMajor()).isEqualTo(student2.getMajor());
}
@Test
void deleteEntity() {
    tx.begin();
    // 한 명의 학생 조회 후 해당 학생의 전공을 제거
    int id = 1;
    Student student1 = manager.find(Student.class, id);
    student1.setMajor(null);

    Major major = manager.find(Major.class, 3);
    manager.remove(major);



    tx.commit();
}

 

 

 

 

 

 

 

반응형