개발/Spring, Spring Data JPA, Querydsl

Spring - 스프링 MVC 구현하기(Mapper, @Valid, 등...)

잇(IT) 2023. 5. 30. 18:59
728x90

- 등록 작업의 경우

1. TodoMapper -> TodoService -> TodoController -> JSP의 순서로 처리하도록 한다.

 

- ModelMapper는 DTO를 VO로 변환하거나 VO를 DTO로 변환해야 하는 작업에 사용된다.

 

- @Configuration은 해당 클래스가 스프링 빈(Bean)에 대한 설정을 하는 클래스임을 명시한다.

- @Bean은 해당 메소드의 실행 결과로 반환된 객체를 스프링의 빈(Bean)으로 등록시키는 역할을 한다.

package org.zerock.springex.config;


import org.modelmapper.ModelMapper;
import org.modelmapper.convention.MatchingStrategies;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@Configuration
public class ModelMapperConfig {

    @Bean
    public ModelMapper getMapper() {
        ModelMapper modelMapper = new ModelMapper();
        modelMapper.getConfiguration()
                .setFieldMatchingEnabled(true)
                .setFieldAccessLevel(org.modelmapper.config.Configuration.AccessLevel.PRIVATE)
                .setMatchingStrategy(MatchingStrategies.STRICT);

        return modelMapper;
    }
}

- MyBatis를 이용하는 개발 단계는 다음과 같다

1. VO 선언

2. Mapper 인터페이스의 개발

3. XML의 개발

4. 테스트 코드의 개발

 

- MyBatis를 통해 SQL 구문을 보다 간결하게 처리 할 수 있다.

package org.zerock.springex.mapper;

import org.zerock.springex.domain.TodoVO;
import org.zerock.springex.dto.PageRequestDTO;

import java.util.List;

public interface TodoMapper {

    String getTime();

    void insert(TodoVO todoVO);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybaits.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.zerock.springex.mapper.TodoMapper">

    <select id="getTime" resultType="string">
        select now()
    </select>

    <insert id="insert">
        insert into tbl_todo (title, dueDate, writer) values ( #{title}, #{dueDate}, #{writer})
    </insert>
</mapper>

1. <mapper namespace="org.zerock.springex.mapper.TodoMapper">는 MyBatis 매퍼 파일에서 사용되는 네임스페이스(namespace)입니다.

2. 네임스페이스(namespace)는 매퍼 파일 내에서 해당 매퍼 인터페이스의 위치를 지정하는 역할을 합니다. 매퍼 인터페이스는 일반적으로 데이터베이스와 연관된 SQL 쿼리를 정의하는 인터페이스입니다.

3. 위의 코드에서는 org.zerock.springex.mapper.TodoMapper 패키지와 인터페이스를 네임스페이스로 지정하고 있습니다. 이것은 매퍼 파일과 해당 인터페이스를 연결시켜주는 역할을 합니다.

4. MyBatis에서는 네임스페이스를 사용하여 매퍼 파일과 매퍼 인터페이스를 매핑합니다. 네임스페이스를 통해 매퍼 파일의 SQL 쿼리를 매퍼 인터페이스의 메서드와 연결할 수 있습니다. 예를 들어, 매퍼 파일의 <select> 태그의 id 속성 값이 매퍼 인터페이스의 메서드명과 일치하면, 해당 메서드를 호출하면 MyBatis는 매퍼 파일의 SQL 쿼리를 실행합니다.

5. 따라서, <mapper namespace="org.zerock.springex.mapper.TodoMapper">는 해당 매퍼 파일이 org.zerock.springex.mapper.TodoMapper 인터페이스와 연관되어 있음을 나타냅니다. 이를 통해 매퍼 파일과 매퍼 인터페이스를 연결하여 쿼리를 실행할 수 있습니다.

 

---------- VO --------------

@Getter
@ToString
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class TodoVO {

    private Long tno;
    private String title;
    private LocalDate dueDate;
    private String writer;
    private boolean finished;
}

----------- Mapper 인터페이스 -----------------

package org.zerock.springex.mapper;

import org.zerock.springex.domain.TodoVO;
import org.zerock.springex.dto.PageRequestDTO;

import java.util.List;

public interface TodoMapper {

    String getTime();

    void insert(TodoVO todoVO);

    List<TodoVO> selectAll();
}


----------- xml 파일 ----------------

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybaits.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.zerock.springex.mapper.TodoMapper">
    <select id="selectAll" resultType="org.zerock.springex.domain.TodoVO">
        select * from tbl_todo order by tno desc
    </select>
</mapper>

1. resultType="org.zerock.springex.domain.TodoVO"는 MyBatis 매퍼 파일에서 사용되는 select 문의 결과 타입을 지정하는 부분입니다.

2. 위의 코드에서는 select 문의 결과로 받아올 데이터의 타입을 TodoVO로 지정하고 있습니다. 즉, select 문의 실행 결과로 반환되는 각 레코드의 컬럼 값을 TodoVO 객체에 매핑하고자 합니다.

3. 여기서 org.zerock.springex.domain.TodoVO는 TodoVO 클래스의 전체 경로를 나타냅니다. 이 클래스는 org.zerock.springex.domain 패키지에 정의되어 있습니다.

4. resultType은 매퍼 파일의 select 문의 결과를 매핑하기 위해 MyBatis가 사용하는 방식을 나타냅니다. resultType에 지정된 클래스의 객체를 생성하고, 각 컬럼의 값을 해당 클래스의 필드에 매핑하여 결과를 반환합니다.

5. 따라서, 위의 코드에서는 select 문의 결과로 반환되는 레코드들을 TodoVO 객체로 매핑하고, 그 결과로 List<TodoVO> 타입을 반환하도록 설정되어 있습니다. selectAll 메서드를 호출할 때 MyBatis는 해당 매퍼 파일의 select 문을 실행하고, 반환된 결과를 TodoVO 객체로 매핑하여 List<TodoVO> 타입으로 반환합니다.

6. 결과적으로 selectAll 메서드는 데이터베이스의 tbl_todo 테이블에서 모든 레코드를 조회하고, 각 레코드의 컬럼 값을 TodoVO 객체로 매핑한 후, List<TodoVO> 형태로 반환합니다.


 

- @Valid

1. 스프링 MVC의 경우 @Valid와 BindingResult라는 존재를 이용해서 간단하게 처리할 수 있다.

 @PostMapping("/register")
    public String registerPOST(@Valid TodoDTO todoDTO, BindingResult bindingResult, RedirectAttributes redirectAttributes){

        log.info("POST todo register........");

        if(bindingResult.hasErrors()) {
            log.info("has errors........");
            redirectAttributes.addFlashAttribute("errors", bindingResult.getAllErrors());
            return "redirect:/todo/register";
        }
        log.info(todoDTO);

        todoService.register(todoDTO);

        return "redirect:/todo/list";
    }

1. @Valid가 적용되었기 때문에 BindingResult 타입을 파라미터로 새롭게 추가한다.

2. 해당 클래스에서 문제가 발생하게 되면 hasErrors()를 이용해서 검증에 문제가 있다면 다시 입력화면으로 리다리엑트되도록 처리한다.

3. 처리 과정에서 잘못된 결과는 RedirectAttributes의 addFlashAttribute()를 이용해서 전달한다.

 

- JavaScript를 통한 에러 확인

<script>

         const serverValidResult = {}

         <c:forEach items="${errors}" var="error">

         serverValidResult['${error.getField()}'] = '${error.defaultMessage}'

         </c:forEach>

         console.log(serverValidResult)
</script>

- 위와 같이 에러를 바로 확인 할 수 있다.

728x90