딸기말차

[Spring] 4. Spring Mybatis 본문

Bootcamp/Spring

[Spring] 4. Spring Mybatis

딸기말차 2023. 8. 16. 10:29

엔코아 플레이데이터(Encore Playdata) Backend 2기 백엔드 개발 부트캠프 (playdata.io)

 

백엔드 개발 부트캠프

백엔드 기초부터 배포까지! 매력있는 백엔드 개발자 포트폴리오를 완성하여 취업하세요.

playdata.io


1. Mybatis 실습_2) DAO - xml mapping 

1. selectAllMemberList

public List<MemberVO> selectAllMemberList() {
    sqlMapper = getInstance();
    SqlSession session = sqlMapper.openSession();

    /* namespace + id를 통해 xml 내 Query 실행 */
    List<MemberVO> memlist = session.selectList("mapper.member.selectAllMemberList");
    return memlist;
}

<select id="selectAllMemberList" resultType="memberVO"> 
    <![CDATA[
    	<!-- joinDate를 기준으로 내림차순 정렬하여 t_member 조회 -->
        select * from t_member order by joinDate desc
    ]]>
</select>

2. selectName

public String selectName() {
    sqlMapper = getInstance();
    SqlSession session = sqlMapper.openSession();
    /* namespace + id를 통해 xml 내 Query 실행 */
    String name = session.selectOne("mapper.member.selectName");
    return name;
}

<select id="selectName" resultType="String"> 
    <![CDATA[
        <!-- id가 admin인 member의 name 조회 -->
        select name from t_member where id='admin'
    ]]>
</select>

3. selelctPwd

public int selectPwd() {
    sqlMapper = getInstance();
    SqlSession session = sqlMapper.openSession();
    /* namespace + id를 통해 xml 내 Query 실행 */
    int pwd = session.selectOne("mapper.member.selectPwd");
    return pwd;
}

<select id="selectPwd" resultType="int">
    <![CDATA[
    	<!-- id가 admin인 member의 pwd 조회 -->
    	select pwd from t_member where id='admin'
    ]]>
</select>

4. selectMemberById

public MemberVO selectMemberById(String id) {
    sqlMapper = getInstance();
    SqlSession session = sqlMapper.openSession();
    /* selectOne() 은 결과값이 반드시 하나여야한다. */
    MemberVO memberVO = session.selectOne("mapper.member.selectMemberById", id);
    return memberVO;
}

<select id="selectMemberById" resultType="memberVO" parameterType="String">
    <![CDATA[
    	<!-- id를 통해 t_member 조회 -->
    	select * from t_member where id=#{id}			
    ]]>
</select>

5. selectMemberByPwd

public List<MemberVO> selectMemberByPwd(int pwd) {
    sqlMapper = getInstance();
    SqlSession session = sqlMapper.openSession();
    /* namespace + id를 통해 xml 내 Query 실행 */
    List<MemberVO> membersList = session.selectList("mapper.member.selectMemberByPwd", pwd);;
    return membersList;
}

<select id="selectMemberByPwd" resultMap="memResult" parameterType="int">
    <![CDATA[
    	<!-- pwd를 통해 t_member 조회 -->
    	select * from t_member where pwd=#{pwd}			
    ]]>
</select>

6. insertMember

public int insertMember(MemberVO memberVO) {
    sqlMapper = getInstance();
    SqlSession session = sqlMapper.openSession();
    /* INSERT Query는 resultType이 없더라도 성공여부를 int 형으로 반환한다. */
    int result = session.insert("mapper.member.insertMember", memberVO);
    /* Transaction option이 JDBC로 되어있기 때문에, 수동 commit을 해야한다. */
    session.commit();
    return result;
}

<insert id="insertMember" parameterType="memberVO">
    <![CDATA[
    	<!-- INSERT Query 실행 -->
    	insert into t_member(id, pwd, name, email) values(#{id}, #{pwd}, #{name}, #{email})
    ]]>
</insert>

7. insertMember2

public int insertMember2(Map<String, String> memberMap) {
    sqlMapper = getInstance();
    SqlSession session = sqlMapper.openSession();
    /* INSERT Query는 resultType이 없더라도 성공여부를 int 형으로 반환한다. */
    int result = session.insert("mapper.member.insertMember2", memberMap);
    session.commit();
    return result;
}

<insert id="insertMember2" parameterType="java.util.Map">
    <![CDATA[
    	<!-- INSERT Query 실행, 이때 파라미터를 Map 형태로 받았기 때문에 values에 Map의 key 값을 쓴다. -->
    	insert into t_member(id, pwd, name, email) values(#{id}, #{pwd}, #{name}, #{email})
    ]]>
</insert>

8. updateMember

public int updateMember(MemberVO memberVO) {
    sqlMapper = getInstance();
    SqlSession session = sqlMapper.openSession();
    /* UPDATE Query는 resultType이 없더라도 성공여부를 int 형으로 반환한다. */
    int result = session.update("mapper.member.updateMember", memberVO);
    session.commit();
    return result;
}

<update id="updateMember" parameterType="memberVO">
    <![CDATA[
    	/* UPDATE Query 실행 */
    	update t_member set pwd=#{pwd}, name=#{name}, email=#{email} where id=#{id}
    ]]>
</update>

9. deleteMember

public int deleteMember(String id) {
    sqlMapper = getInstance();
    SqlSession session = sqlMapper.openSession();
    /* DELETE Query는 resultType이 없더라도 성공여부를 int 형으로 반환한다. */
    int result = session.delete("mapper.member.deleteMember", id);
    session.commit();
    return result;
}

<delete id="deleteMember" parameterType="String">
    <![CDATA[
    	<!-- id를 통해 DELETE Query 실행 -->
    	delete from t_member where id=#{id}
    ]]>
</delete>

10. searchMember

public List<MemberVO> searchMember(MemberVO memberVO) {
    sqlMapper = getInstance();
    SqlSession session = sqlMapper.openSession();
    /* SELECT의 결과를 list에 저장 */
    List list = session.selectList("mapper.member.searchMember", memberVO);
    return list;
}

<select id="searchMember" parameterType="memberVO" resultType="memberVO">
    <![CDATA[
    	select * from t_member
    ]]>
    <where>
    	<!-- 파라미터로 들어온 name이 null이나 공백이 아니라면, 검색조건 추가 -->
        <if test="name != '' and name != null">
        	name=#{name}
        </if>
        <!-- 파라미터로 들어온 email이 null이나 공백이 아니라면, 검색조건 추가 -->
        <if test="email != '' and email != null">
        	and email=#{email}
        </if>
    </where>
    <!-- joinDate를 기준으로 내림차순 정렬 -->
    order by joinDate desc
</select>

11. foreachSelect

해당 SELECT 쿼리 내의 <foreach> 태그를 Java 코드로 바꾸면, 다음과 같다.

String tmp = "("
for (String s : item) {
tmp += item
tmp += " ,"
}
tmp += ")"

public List<MemberVO> foreachSelect(List nameList) {
    sqlMapper = getInstance();
    SqlSession session = sqlMapper.openSession();
    List list = session.selectList("mapper.member.foreachSelect", nameList);
    return list;
}

<select id="foreachSelect" resultType="memberVO" parameterType="java.util.Map">
    <![CDATA[
    	select * from t_member  
    ]]>
    where name in
    <!-- name 컬럼에 괄호(item들) 내부의 내용이 있다면, SELECT -->
    <foreach item="item" collection="list" open="(" separator=","
        close=")">
        #{item}
    </foreach>
    <!-- joinDate를 기준으로 내림차순 정렬 -->
    order by joinDate desc
</select>

12. foreachInsert

해당 INSERT 쿼리 내 태그를 Java 코드로 바꾸면, 다음과 같다.

for {

INSERT ALL INTO t_member(id, pwd, name, email)

VALUES (#{item.id}, #{item.pwd}, #{item.name}, #{item.email})

}

SELECT * FROM DUAL

public int foreachInsert(List memList) {
    sqlMapper = getInstance();
    SqlSession session = sqlMapper.openSession();
    int result = session.insert("mapper.member.foreachInsert", memList);
    session.commit();
    return result;
}

<insert id="foreachInsert" parameterType="java.util.Map">
    <foreach item="item" collection="list" open="INSERT ALL" 
    separator=" " close="SELECT * FROM DUAL">
        INTO t_member(id, pwd, name, email)
        VALUES (#{item.id}, #{item.pwd}, #{item.name}, #{item.email})
    </foreach>
</insert>

13. selectLike

해당 쿼리는 검색 쿼리로, like 를 통해 사용자가 검색한 단어가 완전하지 않더라도, 일부만 일치하더라도 검색을 진행할 수 있게 해주는 쿼리이다.

public List<MemberVO> selectLike(String name) {
    sqlMapper = getInstance();
    SqlSession session = sqlMapper.openSession();
    List list = session.selectList("mapper.member.selectLike", name);
    return list;
}	

<select id="selectLike" resultMap="memberVO" parameterType="String">
    <![CDATA[
        select * from t_member
        where
        name like '%' || #{name} || '%'		
    ]]>
</select>

2.  Mybatis 실습_3) Spring Style Controller

스프링 스타일 controller는 기본적으로 model과 view를 dispatcherServlet으로 return 하는 구조로 되어있다.

1. Controller - Service - DAO를 통해 model 완성, ModelAndView에 저장
2. getViewName 메서드를 통해 jsp 파일명 추출, ModelAndView에 저장
3. DispatcherServlet으로 ModelAndView return

 

1. listBoards()

/*
 * 1. 게시글들을 가져오기 위해 boardService의 listBoards() 실행
 * 2. ModelAndView의 model에 boards 저장
 * 3. ModelAndView의 view에 viewName 저장
 */
@Override
public ModelAndView listBoards(HttpServletRequest request, HttpServletResponse response) throws Exception {
    ModelAndView mv = new ModelAndView();
    List<BoardVO> boards = boardService.listBoards();
    mv.addObject("boards", boards);
    mv.setViewName(getViewName(request));
    return mv;
}

2. insertBoard()

/*
 * 1. MultiActionController의 bind 메서드를 통해 request로 넘어온 파라미터와 BoardVO의 필드 변수명이 일치하면, 데이터 저장
 * 2. INSERT Query 실행
 * 3. POST - Redirect - GET 패턴에 따라, POST 요청을 통해 들어온 데이터를 INSERT 후 Redirect  
 */
@Override
public ModelAndView insertBoard(HttpServletRequest request, HttpServletResponse response) throws Exception {
    BoardVO boardVO = new BoardVO();

    bind(request, boardVO);
    boardService.insertBoard(boardVO);
    return new ModelAndView("redirect:/board/listBoards.do");
}

3. deleteBoard()

/*
 * 1. DELETE Query를 실행하는데 필요한 파라미터를 받아와 저장
 * 2. DELETE Query 실행
 * 3. POST - Redirect - GET 패턴에 따라, POST 요청을 통해 들어온 데이터를 DELETE 후 Redirect  
 */
@Override
public ModelAndView deleteBoard(HttpServletRequest request, HttpServletResponse response) throws Exception {
    String articleNo = request.getParameter("articleNo");
    boardService.deleteBoard(articleNo);
    return new ModelAndView("redirect:/board/listBoards.do");
}

4. boardForm()

/*
 * 1. 게시글 작성 버튼을 누를 시, 페이지 이동을 위해 GET 방식 요청이 들어옴
 * 2. 페이지 이동 전, 기존 게시글 번호와 중복되면 안되기 때문에 SELECT Query를 통해 가장 최근 게시글의 번호를 가져와 + 1 
 * 3. ModelAndView의 model에 가장 최근 게시글의 번호 + 1 을 저장
 * 4. ModelAndView의 view에 viewName 저장
 */
@Override
public ModelAndView boardForm(HttpServletRequest request, HttpServletResponse response) throws Exception {
    ModelAndView mv = new ModelAndView();
    mv.addObject("articleNo", boardService.findMaxArticleNo() + 1);
    mv.setViewName(getViewName(request));
    return mv;
}

3. 30일차 후기

DAO와 xml을 mapping하는 실습과, spring 스타일 controller를 작성해보는 실습을 진행하였다.

 

기본적인 spring controller는 ModelAndView를 완성해 return 시킨다. 이때 ModelAndView를 return하면 DispatcherServlet으로 반환되어, 해당 Model을 가지고 View로 rending하는 과정을 거친다. 스프링의 MVC 패턴은 모두 해당 과정을 거치기 때문에, 데이터의 흐름을 놓치지 않고 왜 jsp에서 Model에 담은 데이터를 사용할 수 있는지 확실히 이해해야 한다고 생각한다.

'Bootcamp > Spring' 카테고리의 다른 글

[Spring] 6. STS  (0) 2023.08.19
[Spring] 5. Transaction, Annotation  (0) 2023.08.17
[Spring] 3. Spring JDBC, Mybatis  (0) 2023.08.14
[Spring] 2. MVC  (0) 2023.08.12
[Spring] 1. DI, IOC, AOP  (0) 2023.08.11