NoticeDao를 더 구현해보자. (page, field, query 넣은거를 해봄)
//
MyBatis 아주 좋다.
String field, String query를 dao한테 넘겨주는게 아주 b
cf) jdbc는 where 다음에 'field' (문자열)을 넣어가지구 + 이런거로 넣었었는데
MyBatis는 인자를 꽂아넣을 때
1) parameter 전달되는건 ${field} - key로 인식. 값을 그대로 넣으면 됨
2) #{query} - 따옴표가 있는게 차이. 값 형태에 따라 맞춰주는거?
Q. %는 어디에 넣어주지?
-> NoticeDao에서
Q. # 대신에 $를 넣은 이유
-> #은 ''가 있는 것.
그래서 't'를 검색하게 되는 것 (query 구문에 맞지 않음)
그래서 # 대신에 $로 바꾸어주었다.
왜 주석처리?
-> myBaits는 오버로드 안 됨. '하나만 구현해줘서'
- 주석 처리 안하면 오류 나와서 실행 안 됨
-> 페이지 들어가자마자 t로 검색된 결과들이 나옴 :)
코드량을 적게 만드는데 아주 좋은 녀석이지만, 너무 interface가 MyBatis에 종속되게 됨.
-> 일반적으로 이렇게(위의 방법) 구현해주지 않는다.
구현할 내용이 SQL 붙이는거 = 매핑
MyBatis에서는 'SQL만 붙이면 내가 해줄게'
-> 근데 이렇게 하는건 바람직하지 않을 것 같다~ 가 요지.
- 인터페이스는 어떤 특정 구현 기술에 종속되서는 안되니, MyBatis에 삽입되는건 옳지 않다는 것
-> 따로 빼자!
1) NoticeDao 구현체를 만들어야겠다.
2) 매핑을 다른 곳에 해야겠다.
- xml로 뺌 1. 인터페이스를 인터페이스답게 해줌 2. 내려쓰기, 쿼리 작성이 복잡할 때 인터페이스 목록이 혼잡해지는데 이걸 해소할 수 있음 (xml은 파일 종류라 그냥 마음대로 내려쓰면서 사용 가능 ~!)
NoticeDao에서
- @Mapper 빼기
- SQL식도 빼기
(정말 인터페이스답게 만들어주기)
https://mybatis.org/mybatis-3/configuration.html#typeHandlers
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.apache.ibatis.submitted.rounding.Mapper">
<resultMap type="org.apache.ibatis.submitted.rounding.User" id="usermap">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="funkyNumber" property="funkyNumber"/>
<result column="roundingMode" property="roundingMode"/>
</resultMap>
<select id="getUser" resultMap="usermap">
select * from users
</select>
<insert id="insert">
insert into users (id, name, funkyNumber, roundingMode) values (
#{id}, #{name}, #{funkyNumber}, #{roundingMode}
)
</insert>
<resultMap type="org.apache.ibatis.submitted.rounding.User" id="usermap2">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="funkyNumber" property="funkyNumber"/>
<result column="roundingMode" property="roundingMode"
typeHandler="org.apache.ibatis.type.EnumTypeHandler"/>
</resultMap>
<select id="getUser2" resultMap="usermap2">
select * from users2
</select>
<insert id="insert2">
insert into users2 (id, name, funkyNumber, roundingMode) values (
#{id}, #{name}, #{funkyNumber}, #{roundingMode, typeHandler=org.apache.ibatis.type.EnumTypeHandler}
)
</insert>
</mapper>
interface에서 함수를 구현할 때 필요한 정보들을 매핑하는걸 NoticeDao에서 했었는데, 다 삭제.
-> 그 정보를
"어떠한 인터페이스를 구하려고 하는데, 어떤 함수와 어떤 SQL이 필요하다."
그리고 NoticeDao한테는 xml에다가 매핑해놨어~라고 알려줘야함.
1. 내가 매핑해줄 파일. class명
2. id? 함수인듯? - 메소드명
3. 반환 타입.
- List가 아니라 entity.Notice인 이유는 힌트만 주면 되어서? 그냥 List를 알아서 읽어오나보다~ 생각.
- Type에서 참조하는건 '필드형'
4. 쿼리문
//
Q. @Mapper는 어디로 갈까.
1) 매핑 정보 여기있어요.
2) 구현체를 IoC 컨테이너에 담아주는 역할
지금 2 작업을 어느곳에서도 안하는 상황
//
MyBatis는 구현을 '도와주는' 녀석이지 구현해주는 녀석이 아니라는거.
저 초록이는 누구지?
-> MyBatis (이 아이의 주요 역할이 매핑!)
mapper 를 두 가지로 나눠 인식
1) @ -> IoC 컨테이너에도 담아줌
2) xml -> Mapper 컨테이너에만 담아줌
우리는 지금 Dao 인터페이스를 구현하는걸 만들겠다는거지
mapper 객체를 'SqlSession'이라는걸 통해서 꺼내올 것
- 그리고 .getMapper() 해서 우리가 원하는 mapper 객체를 가지고올 것
장점
- 구현체에 대한 내용이 외부에 드러나지 않음. 내부에서만.
- 만약 다른 jpa같은거 쓰면 다른 NoticeDao 만들어서 바꾸면 됨.
@Mapper를 쓰면 -> MyBatis에 너무 의존적이어서
xml로 해주는거로 바꾼거고
자기 Mapper 컨테이너에 넣은걸 우리는 꺼내서 쓸 수 있다/가 요지. (이때 SqlSession 사용)
근데 이러면 IoC 컨테이너에서는 참조를 못해서
-> 위에 @Repository
// 실행했는데 안나옴
MyBatis가 NoticeControllerMapper를 읽지 못해서
-> 알려줘야함.
appliction.properties 에 가서
// key 포인트는 이전에 @Mapper 달았던거 잊기.
Dao를 구현해내야하는거고
jdbc 구현 대신에 MyBatis 도움 받아서 할 수 있다는거~
xml에 하는 순간 우리가 직접 @mapper 구현하겠다 하는거
직접 구현의 장점
1) 언제든지 인터페이스를 갈아끼우면 됨
2) 오버로드가 가능함
return 해주는건 받는 '매개변수'와 상관이 없나...?
//
'글쓰기' 작업이 가능하도록 해보자.
순서
parameterType
Controller<-service<-dao<-mapper
insert가 되는지 확인해보자
에러가 남
- witerId를 넣어주어야 (이렇게 설정되어 있어서)
//
숙제 : detail.page에서 자세한 페이지 나오는 작업하기
77일 - 테이블명을 맞춰주는 <resultMap>, 페이징(Limit * Offset *), 동적 쿼리, <where> (0) | 2021.06.09 |
---|---|
76일 - MyBatis를 활용한 DB 연결(2), Dao 구현하기 실습 (0) | 2021.06.08 |
75일 - DI, @Autowired로 결합하는 과정 (0) | 2021.06.07 |
75일 - MySQL 다운, NoticeDao, NoticeService(비즈니스 로직) 인터페이스 생성, DI 개념 (0) | 2021.06.07 |
Dispatcher Servlet 흐름 정말 쉽게 이해하기 (feat. 텔레토비 동산, 청소기, 콩자루) (0) | 2021.06.06 |