인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

berichmore님의 프로필 이미지

작성한 질문수

스프링 DB 2편 - 데이터 접근 활용 기술

MyBatis 적용1 - 기본

게시판 mybatis 적용문제

작성

·

86

·

수정됨

0

학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.

1. 강의 내용과 관련된 질문을 남겨주세요.
2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.
(자주 하는 질문 링크: https://bit.ly/3fX6ygx)
3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.
(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)

질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.
=========================================
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? 예
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예
3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예

[질문 내용]
안녕하세요

mybatis를 체득하고 싶어서 게시판 프로젝트를 한번 해보려고 했는데 잘 안되네요

https://drive.google.com/file/d/1ku2NtUWjeSi1OJ2Z7SLsuqqG7Y471BHv/view?usp=sharing

파일은 여기있습니다.

강의보고 따라하긴 했는데 제가 제대로 이해를 못한건가 싶습니다

제가 생각하는 (공부해서 알게 된) 순서는 이렇습니다

  1. client의 request요청 - JSON배열로

    {
      "id": 1,
      "title": "게시글 제목",
      "content": "게시글 내용"
    }
    이렇게 온다고 가정 
    
  2. Controller에서 request를 @RequestBody 받고 service로 전송

  3. Service에서 dto를 param으로 변환하고 param을 mapper 인터페이스의 메서드로 감싸기

  4. Mapper 인터페이스에서 전달받은 메서드 이름과 id가 같은 mapper.xml로 보내서 CRUD 실행

  5. service Mapper.saveBoard(param)으로 → client에 넘겨줄 responseDto로 param을 보냄

create table member(
	id bigint auto_increment  primary key,
    board_writer varchar(20) not null,
    board_passwd varchar(20) not null
);

create table board(
	id bigint auto_increment primary key,
    writer_id bigint not null,
    title varchar(50) not null,
    board_contents text not null,
    board_count int default 0,
    created_at timestamp default current_timestamp,
    constraint fk_board foreign key(writer_id) references member(id) on delete cascade
);

image.png

테이블은 이렇고

image.png

클라이언트 실행하면 오류가 납니다;

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): Jay.Board.repository.mybatis.BoardMapper.saveBoard
	at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:229) ~[mybatis-3.5.14.jar:3.5.14]
	at org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:53) ~[mybatis-3.5.14.jar:3.5.14]
	at org.apache.ibatis.binding.MapperProxy.lambda$cachedInvoker$0(MapperProxy.java:96) ~[mybatis-3.5.14.jar:3.5.14]
	at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708) ~[na:na]
	at org.apache.ibatis.util.MapUtil.computeIfAbsent(MapUtil.java:36) ~[mybatis-3.5.14.jar:3.5.14]
	at org.apache.ibatis.binding.MapperProxy.cachedInvoker(MapperProxy.java:94) ~[mybatis-3.5.14.jar:3.5.14]
	at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) ~[mybatis-3.5.14.jar:3.5.14]
	at jdk.proxy2/jdk.proxy2.$Proxy63.saveBoard(Unknown Source) ~[na:na]
	at Jay.Board.service.BoardService.saveBoard(BoardService.java:27) ~[main/:na]
	at Jay.Board.controller.HomeController.saveBoard(HomeController.java:37) ~[main/:na]
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:257) ~[spring-web-6.2.2.jar:6.2.2]
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:190) ~[spring-web-6.2.2.jar:6.2.2]
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) ~[spring-webmvc-6.2.2.jar:6.2.2]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:986) ~[spring-webmvc-6.2.2.jar:6.2.2]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:891) ~[spring-webmvc-6.2.2.jar:6.2.2]
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.2.2.jar:6.2.2]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1088) ~[spring-webmvc-6.2.2.jar:6.2.2]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:978) ~[spring-webmvc-6.2.2.jar:6.2.2]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-6.2.2.jar:6.2.2]
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914) ~[spring-webmvc-6.2.2.jar:6.2.2]
	.....

 

 

이 이상은 제가 모르겠습니다….

mapper.xml이 반환되지 않는게 문제 같은데 어느부분이 문제가 되서 이러는지 도통 알 수 없네요.. 오늘 이것만 6시간째 붙잡고 있습니다..

프로그램 흐름의 순서와 그 각각 하는 일들이 어떤 일들이 펼쳐지는지를 이해하고 코딩을 하고싶습니다…

답변 2

0

berichmore님의 프로필 이미지
berichmore
질문자

ㅎㅎㅎ 해결했습니다 너무 감사드립니다 ㅎㅎㅎ

아는게 없어서 질문을 제대로 못드렸는데

혼자라도 해결해서 다행이네요 감사합니다 ㅎㅎ

David님의 프로필 이미지

어떤 부분이 문제였는지 공유해 주실 수 있으실까요~?

0

David님의 프로필 이미지

안녕하세요. berichmore님, 공식 서포터즈 David입니다.

오류가 발생했을 땐 오류 메시지를 천천히 읽어보고 그것을 이해해 보는 게 중요합니다.

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): Jay.Board.repository.mybatis.BoardMapper.saveBoard

질문에 올려주신 오류 메시지 제일 상단의 것을 읽어보면 바인딩 예외가 발생하고 있는 것을 알 수 있습니다. 바인딩은 무언가를 묶는 행위를 말합니다.

Invalid bound statement (not found)를 보면 바인딩과 관련된 구문이 유효하지 않은 것을 알 수 있습니다. 어디서 오류가 발생했는지도 알려주고 있습니다. BoardMapper에 saveBoard에서 문제가 있다고 하네요. 공유해주신 프로젝트 내 saveBoard 쿼리를 보면 #{board_contents}가 잘못 작성된 것으로 보여집니다. 이 부분을 적절히 수정 후 다시 시도해 보시겠어요?

<insert id="saveBoard" useGeneratedKeys="true" keyProperty="id">
        insert into board (writer_id,title, board_contents)
        values (#{writerId}, #{title}, #{board_contents})
    </insert>

감사합니다.

berichmore님의 프로필 이미지
berichmore
질문자

저도 그부분은 알고 있는데 왠지 해결을 못하겠네요....

답답합니다 ㅠㅠ

David님의 프로필 이미지

알고 계신 부분은 무엇이고, 알고 계신 것을 어떻게 적용하였는지 알려 주실 수 있으실까요?

berichmore님의 프로필 이미지
berichmore
질문자

제가 너무 지식이 적어 어떻게 말을해야할지몰랐어요

고맙습니다 그래도 혼자 이것 저것 해보니 잘됐어요 ㅎㅎ 또 여쭤볼게요

새해 복 많이 받으세요!