SpringInAction 3장

김대철·2025년 2월 21일
0

spring-in-action

목록 보기
3/8
post-thumbnail

Chap 3. 데이터로 작업하기

3.1. JDBC를 사용해서 데이터 읽고 쓰기

  • JDBC(Java Database Connectivity)
    • 정의: 자바에서 데이터베이스에 접속이 가능하도록 하는 API

    • JDBC 주요 구성
      그림

      • JDBC 드라이버
        • DBMS와 통신을 담당하는 자바 클래스

        • DBMS에 따라 맞는 드라이버가 다름

          ex: com.mysql.jdbc.Driver(mySQL), oracle.jdbc.driver.OracleDriver(오라클)

      • JDBC URL
        • DBMS 연결을 위한 식별값
        • JDBC 드라이버에 따라 형식이 다름
        • 구성: jdbc:[DBMS]:[DB식별자]
    • JdbcTemplate

      • 스프링에서 JDBC 지원을 위한 클래스

      • JDBC 사용 시 요구되는 형식적인 코드없이 SQL 연산을 수행하도록 제공

      • JdbcTemplate 사용 여부에 따른 비교

        • 미적용 시
        @Override
        public Ingredient findById(String id) {
          Connection connection = null;       // DB 연결을 위한 객체
          PreparedStatement statement = null; // 쿼리문 정의를 위한 객체
          Resultset resultSet = null;         // 결과값 저장을 위한 객체
        
          try {
              connection = dataSource.getConnection(); // DB 연결
              statement = connection.preparedStatement(
                  "select id, name, type from Ingredient where id = ?");
              statement.setString(1, id);
              resultSet = statement.executeQuery(); // 쿼리 수행 및 결과 저장
              
              Ingredient ingredient = null;  // 쿼리 결과를 객체에 매핑시키기 위함
              if (resultSet.next()) {
                  ingredient = new Ingredient(
                      resultSet.getString("id"),
                      resultSet.getString("name"),
                      Ingredient.Type.valueOf(resultSet.getString("type")));
              }
              return ingredient;
          } catch (SQLException e) {
              // SQL 수행에 관한 예외 처리
          } finally {
              // 쿼리 수행 후 관련 객체 해제
              if (resultSet != null) {
                  try {
                      resultSet.close();
                  } catch (SQLException e) {}
              }
              if (statement != null) {
                  try {
                      statement.close();
                  } catch (SQLException e) {}
              }
              if (connection != null) {
                  try {
                      connection.close();
                  } catch (SQLException e) {}
              }
          }
          return null;
        }
        • 적용 시
        private JdbcTemplate jdbc; // JdbcTemplate 활용 쿼리 수행을 위한 객체
        
        @Override
        public Ingredient findById(String id) {
          return jdbc.queryForObject(
              "select id, name, type from Ingredient where id = ?",
              this::mapRowToIngredient, id);
        }
        
        private Ingredient mapRowToIngredient(ResultSet rs, int rowNum) throws SQLException {
          return new Ingredient(
              rs.getString("id");
              rs.getString("name");
              Ingredient.Type.valueOf(rs.getString("type")));
        }
      • 비교 결과

        • 연결 객체를 생성 및 메소드 실행 후 클린업하는 코드 필요 X
        • catch 블록에서 실행되어야 하는 예외처리 구문 필요 X
        • 쿼리 수행 및 결과를 객체로 생성하는 작업에 대한 코드만 필요
    • 주요 메소드 및 어노테이션

      • 어노테이션
        • Repository: Component에서 데이터 접근을 위한 어노테이션
        • SessionAttributes: 설정한 이름에 해당하는 모델 정보를 자동으로 세션에 넣는 어노테이션. 여러 요청에서 사용하는 객체의 경우에 사용
        • ModelAttribute: 해당 객체가 모델로부터 생성되거나 전달되어야 함을 알려주는 어노테이션
      • 메소드
        • queryForObject: 하나의 객체를 반환하도록 하는 쿼리 메소드 (파라미터로 검색할 행의 id를 추가로 받음)
        • query: 객체의 List를 반환하도록 하는 쿼리 메소드
        • update: 데이터베이스에 데이터를 추가하거나 수정하는 쿼리 수행을 위한 메소드
    • 데이터 추가를 위한 방법
      1) 직접 update 메소드를 사용

      • 필요 인자: PreparedStatementCreator(쿼리문), KeyHolder(고유한 값 제공) 객체
        2) SimpleJdbcInsert 사용
      • SimpleJdbcInsert: 데이터를 더 쉽게 추가하기 위해 JdbcTemplate를 래핑한 클래스
        • execute / executeAndReturnKey: 데이터 추가를 위한 메소드 [인자: Map<String, Object> → key: 컬럼이름, value: 추가되는 값]

3.2. 스프링 데이터 JPA를 사용해서 데이터 저장하고 사용하기

  • 스프링 데이터 JPA
    • ORM(Object-Relational Mapping)
      • 관계형 테이블을 클래스 객체를 자동으로 매핑해주는 것
      • 객체 모델과 관계형 모델 사이의 불일치 해결을 위해 필요
      • 장점: 재사용 및 유지보수의 용이성 증가, DBMS 종속성 감소
      • 단점: 프로시저가 많은 시스템에서 구현하기 어려움, 자주 사용되는 대형 쿼리에 대한 별도 튜닝 필요
      • ex: JPA, Hibernate 등
    • JPA
      • Java 애플리케이션에서 관계형 데이터베이스를 사용방식을 정의한 인터페이스
      • 반복적인 CRUD SQL 처리에 활용
      • 관계매핑 또는 성능 이슈에 대해 직접 쿼리를 작성하는 네이티브 SQL 제공
  • 다양한 스프링 데이터 프로젝트
    • 스프링 데이터 JPA: 관계형 데이터베이스의 JPA 퍼시스턴스
    • 스프링 데이터 MongoDB: 몽고 문서형 데이터베이스의 퍼시스턴스
    • 스프링 데이터 Neo4: Neo4j 그래프 데이터베이스의 퍼시스턴스
    • 스프링 데이터 Redis: 레디스 키-값 스토어의 퍼시스턴스
    • 스프링 데이터 Cassandra: 카산드라 데이터베이스의 퍼시스턴스
  • 스프링 데이터 JPA 주요 어노테이션
    • Entity: 해당 클래스를 JPA entity로 선언
    • Table: 해당 entity가 특정 테이블에 저장되어야 함
  • CrudRepository 인터페이스
    • Create(생성), Read(읽기), Update(변경), Delete(삭제) 연산을 위한 인터페이스

    • 매개변수로 저장되는 엔티티 타입과 ID 속성타입을 받음

      ex) CrudRepository<Ingredient, Long>: 엔티티타입은 Ingredient, ID 속성타입은 Long

  • JPA 리포지토리 커스터마이징
    • CRUD 연산에 추가하여 특정 속성값에 해당하는 쿼리가 필요한 경우 메소드 추가
    • 리포지토리 구현체 생성 시: 스프링 데이터가 인터페이스에 정의된 메소드의 이름 분석 후 용도 파악
    • 메소드 시그니처의 예시
      • findByDeliveryZip(String deliveryZip): deliveryZip과 일치하는 결과
      • findByDeliveryCityOrderByDeliveryTo(String city): city와 일치하는 결과를 DeliveryTo 기준 정렬
    • 복잡한 쿼리의 경우 Query 어노테이션으로 쿼리 작성 가능
profile
개발하는 미어캣

0개의 댓글