newlecture: spring boot (3) : Mybatis 응용
NoticeService 구현할 목록 분석하기
NoticeService
- 페이지를 요청할 때
List<NoticeView> getViewList();
int getCount();
- 검색을 요청할 때
List<NoticeView> getViewList(String field, String query);
- 페이지를 요청할 때 (페이징 버튼) 이때 검색된 결과 내에서 페이징 해야 한다!
List<NoticeView> getViewList(int page, String field, String query);
int getCount(String field, String query);
- 일괄공개를 요청할 때
int updatePubAll(int[] pubIds, int[] closeIds);
- 일괄삭제를 요청할 때
int deletaAll(int[] ids);
- 자세한 페이지 요청할 때
NoticeView getView(id);
Notice getNext(id);
Notice getPrev(id);
-수정 페이지를 요청할 때
int update(Notice notice);
int delete(int id);
int insert(Notice notice);
오버로딩 메서드에서의 구현순서
먼저 인자가 가장 많은 상세한 메서드를 구현한 후에 간단한 메서드는 이미 구현된 메서드를 통해서 구현한다
아래는 NoticeServiceImpl의 예시다
@Override
public List<NoticeView> getViewList() {
// TODO Auto-generated method stub
return getViewList(1, "title", "");
}
@Override
public List<NoticeView> getViewList(String field, String query) {
// TODO Auto-generated method stub
return getViewList(1, field, query);
}
@Override
public List<NoticeView> getViewList(int page, String field, String query) {
int size = 5;
int offset = 0 + size * (page-1); // an = a1 + (n-1)d : page 1-> 0, 2-> 10, 3-> 20
List<NoticeView> list = noticeDao.getViewList(offset, size, field, query);
return list;
}
XML이나 HTML에서 >
, <
>
는>
로<
는<
로 대신 표현 가능하다
기본형은 parameterType, returnType 이 생략 가능하다 그렇지 않다..
동적쿼리
쿼리가 아래와 같을 때 동적쿼리를 생각해볼 수 있다
int deleteAll(int[] ids);
<delete id="deleteAll">
delete from notice
where id in (1, 2, 3, 4)
</delete>
- 위 쿼리는 아래의 문법으로 동적쿼리 구현 가능하다
mybatis 동적 SQL https://mybatis.org/mybatis-3/ko/dynamic-sql.html
<delete id="deleteAll">
delete from notice
where id in
<foreach item="id" index="index" collection="ids"
open="(" separator="," close=")">
#{id}
</foreach>
</delete>
- 또다른 쿼리 예시를 보자
int updatePubAll(int[] pubIds, int[] closeIds);
위 코드는 공개/비공개할 목록을 화면상에서 받아와 하나의 트랜잭션안에서 처리하겠다는 메서드 시그니쳐이다
int updatePubAll(int[] ids, boolean pub);
반면 위 코드는 id 리스트와 공개할지의 여부를 받아와서 처리한다. 구현은 좀 더 직관적인 반면에 공개/비공개를 따로 2번을 트랜잭션을 처리해야 한다
첫 번째 시그니쳐 기준으로 구현해보자
아래는 예시쿼리이다
<update id="updatePubAll">
update Notice
set
pub = case id
when 14 then 0
when 15 then 0
when 21 then 1
when 22 then 1
where id in (14, 15, 21, 22)
</update>
순차적으로 접근을 해보자
<update id="updatePubAll">
update Notice
set
pub = case id
<foreach item="id" collection="pubIds">
when #{id} then 0
</foreach>
<foreach item="id" collection="closeIds">
when #{id} then 1
</foreach>
where id in (
14, 15
,
21, 22
)
</update>
다음 단계는 아래와 같다
<update id="updatePubAll">
update Notice
set
pub = case id
<foreach item="id" collection="pubIds">
when #{id} then 0
</foreach>
<foreach item="id" collection="closeIds">
when #{id} then 1
</foreach>
where id in (
<foreach item="id" index="index" collection="pubIds"
separator=",">
#{id}
</foreach>
,
<foreach item="id" index="index" collection="closeIds"
separator=",">
#{id}
</foreach>
</update>
아래는 2번째 메서드 시그니쳐이다.
마이바티스는 메서드 오버로딩이 안되기 때문에 하나를 선택해야 한다
<update id="updatePubAll">
update Notice
set
pub = #{pub}
where id in
<foreach item="id" index="index" collection="ids"
open="(" separator="," close=")">
#{id}
</foreach>
</update>
동적쿼리 : where, trim
where
<select id="getViewList" resultType="com.newlecture.web.entity.NoticeView">
select * from NoticeView
<where>
<if test="query != null or query != '' ">
${field} like '%${query}%'
</if>
and pub = #{pub}
</where>
order by id desc
limit #{offset}, #{size}
</select>
trim
<select id="getViewList" resultType="com.newlecture.web.entity.NoticeView">
select * from NoticeView
<trim prefix="WHERE" prefixOverrides="AND |OR ">
<if test="query != null or query != '' ">
${field} like '%${query}%'
</if>
and pub = #{pub}
</trim>
order by id desc
limit #{offset}, #{size}
</select>