[Spring] Spring Data JPA(2)

99winnmin·2022년 7월 21일
0

Spring

목록 보기
12/17

JPA 시작 전 준비사항

JPA의 필수도구 LomBok

  • lombok을 사용한 예제 코드
@Data // @Getter, Setter, RequiredArgsConstructor, ToString, EqualsAndHashCode, Value 포함되어있음 -> 하지만 OOP를 위반하는 개념이기도함
@NoArgsConstructor // 생성자에 인자가 없을 때
@AllArgsConstructor // 생성자에 모든 인자가 들어가야할 때
@Builder
public class User {
    @NonNull // null값 금지여서 필수 값이 됨
    private String name;
    @NonNull
    private String email;
    private LocalDateTime createdAt;
    private LocalDateTime updatedAt;
}

보통 getter,setter 등등 필요한 메서드를 일일이 귀찮게 코딩 안해줘도 해당 어노테이션들로 structure들이 자동 생성된다.

H2 DB란?

JAVA 기반의 경량화된 관계형 데이터베이스이다.

  • 파일로 저장 -> 실제 DB처럼 이용가능
  • MemoryDB로 사용하여 실제 인스턴스가 동작할 때만 유지할 수 도 있음
  • H2 DB 사용 세팅
    • application.yaml 파일에 다음과 같이 설정을 추가해준다.
         spring:
           h2:
             console:
               enabled: true
    • In-memory형식이기 때문에 테스트가 끝나는 시점에서 데이터가 유지되지 않고 사라짐을 유의하자
    • 다음 사진과 동일한 순서로 H2 DB 콘솔을 세팅해준다(서버를 실행하여 H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:~~~'의 값을 이용해서 생성하면 된다.)

JPA Repository Interface의 기본 메서드

ORM(객체와 DB 사이와 관계를 이어주는 객체)는 즉 Entity임, 다음과 같이 entity로 선언해줄수 있음

@Entity // 객체를 Entity로 선언(ORM 으로 만듬)
public class JpaUser {
    @Id // entity는 무조건 pk값이 있어야함
    @GeneratedValue // pk값의 자동 순차적인 증가
    private Long id;
   }
  • interface를 하나 선언해서 수많은 jpa repo 메서드들을 사용할 수 있음 : JpaRepository를 상속함으로써 수많은 interface 계층에 있는 메서드들을 사용할 수 있게됨
public interface JpaUserRepository extends JpaRepository<JpaUser, Long> {
}
  • 기본 메서드 실습 코드
@SpringBootTest
class JpaUserRepositoryTest {
    @Autowired
    private JpaUserRepository jpaUserRepository;

    @Test
    void find(){ // create,read,update,delete
        // findAll()은 일반적으로 성능이슈 때메 잘 사용안함
        /*for (JpaUser jpaUser : jpaUserRepository.findAll()){
            System.out.println(jpaUser);
        }*/
        // jpaUserRepository.findAll().forEach(System.out::println); // 위 방식과 같은 Lamda 식 표현

        //List<JpaUser> users = jpaUserRepository.findAll(Sort.by(Sort.Direction.DESC, "name")); // 이름 역순 정렬
        List<JpaUser> users = jpaUserRepository.findAllById(Lists.newArrayList(1L,3L,5L)); // ID(1,3,5)찾기
        users.forEach(System.out::println);
    }

    @Test
    void save(){ // create,read,update,delete
        JpaUser jpaUser1 = new JpaUser("ryu","rqwer@gmail.com");
        JpaUser jpaUser2 = new JpaUser("you","rqwe494r@gmail.com");

        jpaUserRepository.saveAll(Lists.newArrayList(jpaUser1,jpaUser2));

        List<JpaUser> users = jpaUserRepository.findAll();

        users.forEach(System.out::println);
    }

    @Test
    @Transactional
    void getOne(){
        JpaUser jpaUser = jpaUserRepository.getReferenceById(1L);
        System.out.println(jpaUser);
    }

    @Test
    void findById(){
//        Optional<JpaUser> jpaUser = jpaUserRepository.findById(1L);
        JpaUser jpaUser = jpaUserRepository.findById(7L).orElse(null); // 없으면 null 반환
        // lazy patch?? ego patch??
        System.out.println(jpaUser);
    }

    @Test
    void saveAndFlush(){
//        jpaUserRepository.save(new JpaUser("new user","Qewreqwr@gmailc.om"));
//        jpaUserRepository.flush();
        jpaUserRepository.saveAndFlush(new JpaUser("new user","Qewreqwr@gmail.com"));

        jpaUserRepository.findAll().forEach(System.out::println);
    }

    @Test
    void count(){
        long count = jpaUserRepository.count();
        System.out.println(count);
    }

    @Test
    void exist(){
        boolean exists = jpaUserRepository.existsById(1L);
        System.out.println(exists);
    }

    @Test
    void delete(){
//        jpaUserRepository.delete(jpaUserRepository.findById(1L).orElseThrow(RuntimeException::new));
        jpaUserRepository.deleteById(1L);
        jpaUserRepository.findAll().forEach(System.out::println);
        jpaUserRepository.deleteAll();
        jpaUserRepository.findAll().forEach(System.out::println);
    }

    @Test
    void selectAndDelete(){
        jpaUserRepository.deleteAll(jpaUserRepository.findAllById(Lists.newArrayList(1L,3L)));
        jpaUserRepository.findAll().forEach(System.out::println);
    }
    // 메소드가 상당히 많은데 hibernate 에서 어떤 sql이 실행되는지를 체크하면서 성능을 개선하는 쪽으로 작성하는 것이 좋을 듯하다.
    @Test
    void deleteInBatch(){
//        jpaUserRepository.deleteAllInBatch(jpaUserRepository.findAllById(Lists.newArrayList(1L, 3L)));
        jpaUserRepository.deleteAllInBatch();
        jpaUserRepository.findAll().forEach(System.out::println);
    }

    @Test
    void pageTest(){
        // 1페이지당 3개씩 띠어라
        Page<JpaUser> page = jpaUserRepository.findAll(PageRequest.of(1,3));

        System.out.println("page : "+page);
        System.out.println("totalElements : "+page.getTotalElements());
        System.out.println("totalPages: "+page.getTotalPages());
        System.out.println("numberOfElements : "+page.getNumberOfElements());
        System.out.println("sort : "+page.getSort());
        System.out.println("size : "+page.getSize());

        page.getContent().forEach(System.out::println);
    }

    @Test
    void queryByExample(){
        ExampleMatcher exampleMatcher = ExampleMatcher.matching()
                .withIgnorePaths("name")
                .withMatcher("email",endsWith());

        Example<JpaUser> example = Example.of(new JpaUser("ryu","gmail.com"), exampleMatcher);
        jpaUserRepository.findAll(example).forEach(System.out::println);

        JpaUser jpaUser = new JpaUser();
        jpaUser.setEmail("3@gm");

        ExampleMatcher matcher = ExampleMatcher.matching().withMatcher("email", contains());
        Example<JpaUser> example1 = Example.of(jpaUser, matcher);

        jpaUserRepository.findAll(example1).forEach(System.out::println);
    }

    @Test
    void updateTest(){
        // 여기서 @Transactional을 쓰지 않아도 save()자체적으로 @Transactional붙어있긴함!
        jpaUserRepository.save(new JpaUser("david", "david@gmail.com"));

        JpaUser jpaUser = jpaUserRepository.findById(1L).orElseThrow(RuntimeException::new);
        jpaUser.setEmail("update@gmail.com");

        jpaUserRepository.save(jpaUser);
    }
}

출처 : 한 번에 끝내는 Java/Spring 웹 개발 마스터 초격차 패키지 Online.

profile
功在不舍

0개의 댓글