본문 바로가기
Blog/TIL

[240529] 직접 해봐야 안다

by 코젼 2024. 5. 29.
728x90
반응형

🔶JPA

🔶Transaction


목차

    / 오늘의 TIL /


    JPA

    Spring Data JPA
    JPA(ORM)
    Hibernate
    JDBC

    application.yml 설정

    더보기
    • ddl-auto: 객체와 테이블이 다를 경우 처리 방법
      • create: 기존 테이블 삭제 후 생성
      • create-drop: 스프링 종료 후 테이블 제거
      • update: 객체와 테이블이 다른 부분만 변경
      • validate: 객체와 테이블이 동일한지 확인
      • none: 아무것도 안한다.
    • show_sql: jpa를 사용해서 db에 sql를 보내는 로그 보여줄지 유무
    • dialect: jpa가 자동으로 db마다 다른 점을 보완해준다.
    jpa:
      hibernate:
        ddl-auto: none
      properties:
        hibernate:
          show_sql: true
          format_sql: true
          dialect: org.hibernate.dialect.MYSQL8Dialect

     

    모든 정보 조회

    select * from user 를 JPA에서 사용하는 방법이다.

    JpaRepository를 상속받는 userRepository에서 findAll 메서드를 사용해서 모든 데이터를 조회할 수 있다.

    List 형태의 객체를 반환하기 때문에 stream을 통해 UserResponse 객체로 매핑시켜주고, List로 변환해서 반환한다.

     

    장점: ResultSet을 통해 컬럼을 하나하나 매핑할 필요 없이 객체를 통해 매핑시킬 수 있다.

     

    * collect(Collectors.toList): 컬렉션 객체를 통해 리스트로 반환한다.

    public List<UserResponse> getUsers() {
        List<User> users = userRepository.findAll();
        return users.stream()
                .map(user -> new UserResponse(user.getId(), user.getName(), user.getAge()))
                .collect(Collectors.toList());
    }

     

    Refactoring

    생성자를 생성하는 객체를 통해 더욱 깔끔하게 매핑시킬 수도 있다.

    public UserResponse(User u) {
        this.id = u.getId();
        this.name = u.getName();
        this.age = u.getAge();
    }
    public List<UserResponse> getUsers() {
        return userRepository.findAll().stream()
                .map(UserResponse::new)
                .collect(Collectors.toList());
    }

     

    id를 통해 데이터가 있는지 조회

    find~~ 형태인 경우 반환 값을 1개만 가져온다.

     

    ex) select * from user where id = 1;

    JpaRepository의 findById 메서드를 통해 요청된 id가 있는지 조회한다.

    반환된 Optional의 orElseThrow 메서드를 통해 조회된 값이 있는 경우 User 객체로 반환하고, 없는 경우 Exception을 던진다.

    User user = userRepository.findById(request.getId())
            .orElseThrow(IllegalArgumentException::new);

    요청 값으로 들어온 이름을 User 객체의 이름에 변경하고 저장한다.

    만약 User 객체에 변경된 값이 있다면, JpaRepository가 자동으로 인식해서 save를 동작시킨다.

    user.updateName(request.getName());
    userRepository.save(user);

     

    exists: 존재하는지 확인. 반환 타입은 boolean

    count: sql 결과 개수 확인. 반환 타입은 long


    Transaction

    IOException같은 checked exception은 rollback되지 않는다.

    영속성 컨텍스트

    테이블과 매핑된 Entity 객체를 관리하고 보관하는 역할을 한다.

    Transaction이 시작과 종료 시 영속성 컨텍스트도 시작과 종료를 한다.

    1. 변경 감지
      영속성 컨텍스트 안에서 호출된 Entity는 명시적으로 save를 호출하지 않아도 변경을 감지해서 자동으로 저장된다.
    2. 쓰기 지연
      commit을 요청할 때만 sql을 묶어서 한 번에 전달하기 때문에 쿼리 부하를 줄일 수 있다.
    3. 1차 캐싱
      동일한 sql을 진행할 경우 이미 영속성 컨텍스트가 sql을 캐시로 저장하고 있기 때문에 db에서 최초로 한 번만 요청할 수 있다.
      캐싱된 객체는 완전히 동일하다! (주소 값까지 동일하다는 뜻)
    728x90
    반응형

    'Blog > TIL' 카테고리의 다른 글

    [240531] 처음으로 배포를 해보다  (0) 2024.05.31
    [240530] 도메인 연관 관계의 중요성  (0) 2024.05.30
    [240528] 백문이 불여일타!  (0) 2024.05.28
    [240527] 코딩테스트 다다익선  (0) 2024.05.27
    [240526] API 개발하기  (0) 2024.05.26

    댓글