티스토리 뷰

Spring으로 개발을 하면서 Mybatis 프레임워크를 많이들 써봤을 것이다.
Mybatis는 JAVA 객체를 SQL과 매핑시켜주는 SQL Mapper이며 현재까지도 많이 쓰이고 있다.

 

Mybatis를 사용하면서 가장 많이보는 에러중 Paramter를 N개이상 넘겼을때 Parameter not found. available parameters are 라는 예외메세지가 출력되는 경우가 발생할 수 있는데 이 메시지는 왜 발생이되며 어떻게 해결해야하는지 알아보자. 환경구성은 Spring Boot와 Mybatis를 연동해서 살펴보았다.

Mybatis Sql SELECT

페이징 객체를 파라미터로 넘겨 리스트 10개를 가져오는 SQL이다.
이때 XML에 정의된 #{start}와 #{end}는 파라미터로 넘어온 PageDTO 클래스의 멤버변수 start와 end를 말한다.
제일 흔한 SQL이다. 이제 여기에 Paramter를 1개 더 추가해보자.

Search Paramter 추가

'title'이란 Paramter가 존재하지 않는다는 Exception이 발생했다.
왜 이러한 에러가 발생했는지 지금부터 내부코드를 살펴보자.

동작코드

Spring Boot에서 Mybatis를 사용할때 pom.xml에 mybatis의존성을 등록하게된다.  등록하게되면 @MapperScan 어노테이션으로 스캔할 패키지명을 명시해준다.  그러면 Spring에선 @MapperScan 어노테이션에 명시된 패키지 하위에 @Mapper 어노테이션이 선언된 인터페이스를 Bean으로 관리를 한다. 이런작업을 org.mybatis.spring.boot.MybatisAutoConfiguration 클래스에서 처리하게 된다.

인터페이스를 Bean으로 관리하겠다는건 인터페이스를 구현한 프록시 객체가 Spring Container에 의해 관리된다.

 

스프링이 마이바티스 관련 빈 설정을 잡아줄때는 몇가지 규칙이 있다.

1. @Mapper 어노테이션이 선언된 인터페이스의 package명과 동일한 경로의 XML파일이 classpath에 위치해야한다.

    ex) src/main/resources/com/kjh/study/mapper/BoardMapper.xml

 

2. 해당 인터페이스의 메소드명과 동일한 이름을 가진 xml tag구문이 있어야하며 이 이름은 유니크해야한다.

   ex) selectBoardList()  ->  select id="selectBoardList" 

   참고로 메서드 오버로딩을 하게되면 서버 구동시 mapper id값이 충돌나는 예외가 발생된다.

 

3. XML 파일의 namespace 경로가 package 명과 같아야한다.

 

위 3가지 조건을 모두 충족시 Proxy객체가 생성이된다.



BoardMapper 인터페이스의 프록시 객체를 생성하게 되는걸 알 수 있다.
이 프록시 객체는 SqlSession 인터페이스의 구현체인
DefaultSqlSession.class 의 메소드를 호출한다.



BoardMapper 인터페이스의 프록시 객체가 호출한 메서드의 리턴타입을 확인하여 List면 selectList
그외엔 selectOne 메서드를 DefaultSqlSession가 호출하게 된다.

 

그러면 여기서 주목해야할것이 있다. selectList(String statement, Object parameter, RowBounds rowBounds) 메서드이다.

 

위에서 Parameter로 넘겼던 PageDTO와 Search 총 2개를 넘겼지만 받는쪽은 Object 타입 1개로 되어있다.
그럼이제 저 Paramter엔 어떤값이 담겨있는지 확인을 해보자.



Paramter는 HashMap에 담긴걸 확인할 수 있다. 빨간색 테두리를 보면
Search라는 Paramter는 "search", PageDTO는 "pageDTO" 라는 key에 담긴걸보면

Paramter가 2개이상일때부턴 내부적으로 Map에 저장되는걸 확인할 수 있다.

근데 파라미터는 2개를 넘겼는데 왜 Map에는 4개가 들어있을까?

 

Mybatis에서 메서드에 Parameter가 존재할땐 'param1' 이라는 default key값을 제공해준다.
만일 Paramter가 3개일땐 'param1', 'param2', 'param3' 이런식으로 메세드 매개변수 순서에 맞게 제공을해준다.



그래서 'title' 이라는 key를 찾지못했기 때문에 해당예외가 발생했던것이다.

 

Parameter가 2개이상일땐 Map에 담기는걸 알 수있었다. 그런데 어떤 key의 이름으로 담길까?
바로
매개변수 이름으로 key에 저장된다. 한번 테스트를 해보자

Paramter name 변경

PageDTO 변수를 'kjhPage', Search 변수를 'kjhSearch' 라는 이름으로 변경했다.

 

 

'kjhPage', 'kjhSearch' 라는 key이름으로 Map에 저장된걸 볼 수 있다.

 

 

정상적으로 실행되었다.

728x90

'Mybatis' 카테고리의 다른 글

[Mybatis] - Mybatis Interceptor  (2) 2020.12.26
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함