Spring MyBatis 구현 방법 / DB 관계

S.Sun·2024년 4월 17일

스프링

목록 보기
11/17

질문 내용

  1. 마이바티스 2에서의 사용법과 3에서의 사용법 4가지를 정리하시오.
  2. DB의 아래의 관계에 대하여 설명하시오.
  • 일대일 관계
  • 일대다 관계
  • 다대다 관계
  1. 다음과 같이 나오도록 하시오. 다음과 같이 나오도록 하시오.
  • /emp/salgrade 접속시
  • 이름 월급 월급등급

개인 작성

  • 마이바티스 1번째 사용 방법 : @Service 내 처리 방법
    - interface IBBao를 XML namespace에 매핑
    - sqlSession.getMapper(IBDao.class)를 이용
  • interface
public interface IBDao {
	List<BoardVo> listDao();
}
  • XML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="edu.sejong.ex.one.IBDao">
	<select id="listDao" resultType="BoardVo">
    	<![CDATA[
        	SELECT * FROM MVC_BOARD ORDER BY bgroup desc, bstep asc
        ]]>
	</select>
</mapper>
  • @Service
@Service
public class BService1 {
	
	@Autowired
	//private SqlSession sqlSession;
	private SqlSessionTemplate sqlSession;
	
	public List<BoardVo> selectBoardList() throws Exception{
		IBDao dao = sqlSession.getMapper(IBDao.class);
		return dao.listDao();
	}
}

  • 마이바티스 2번째 사용 방법 : @Service 내 처리 방법
    - interface는 필요가 없음
    - sqlSession에서 제공하는 함수(selectList, selectOne)를 이용함
    - 쿼리 구현을 위한 XML이 필요. 해당 XML의 namespace는 개발자가 정함
    - 해당 방식은, 기존처럼 mapper interface를 따로 만들지 않고 mapper의 namespace와 해당 함수명을 대입하는 것.
    - mapper에서는 namespace와 select태그의 id를 각각 board, selectBoardList로 세팅하고 sql구문을 넣어주면 된다.
    - 해당 방식의 장점
    • .xml로 작성했을 때 List로 리턴되는지, 하나만 리턴되는지를 잘 알 수가 없음
      -> 해당 방식은 sqlSession에서 제공하는 함수를 사용하므로 어떤 값이 리턴되는지를 파악할 수 있음
    • 개발자가 원하는 이름으로 namespace와 함수명을 정할 수 있음.
    • 개발자들이 선호하는 방식 중 하나라서 상당히 자주 볼 수 있다고.
  • XML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="board">
	<select id="selectBoardList" resultType="BoardVo"><!-- edu.sejong.ex.vo.BoardVo -->
    	<![CDATA[
        	SELECT * FROM MVC_BOARD ORDER BY bgroup desc, bstep asc
        ]]>
	</select>
</mapper>
  • @Service
@Service
public class BService2 {
	
	@Autowired
	private SqlSessionTemplate sqlSession;
	
	public List<BoardVo> selectBoardList() throws Exception{
		return sqlSession.selectList("board.selectBoardList");
	}
}

  • 마이바티스 3번째 사용 방법 : @Mapper 내 처리 방법
    - MyBatis 3버전부터 사용할 수 있는 방법
    - annotation을 활용하는 방법.
    - .xml을 구현할 필요가 없다는 장점은 있음.
    - 개발자들이 자주 쓰지는 않는 방법.
  • Mapper Interface
	@Select("SELECT * FROM MVC_BOARD ORDER BY bgroup desc, bstep asc")
	List<BoardVo> selectList2();

  • 마이바티스 4번째 사용방법
    - 기존에 활용하던, xml 활용 방식과 3번째 사용 방법을 필요할 때마다 골라서 사용하는 방식.
    - Mapper 인터페이스를 사용하게 됨으로서, SQLSession 인터페이스를 직접 활용하지 않아도 됨.
    - 개발자가 직접 SqlSession을 사용하는 것이 아니라, Mapper 인터페이스를 통해 간접적으로 SqlSession을 활용
  • Mapper interface
@Mapper
public interface BoardMapper {
	List<BoardVo> selectList();
}
  • XML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="edu.sejong.ex.mapper.BoardMapper">
	<select id="selectList" resultType="BoardVo"><!-- edu.sejong.ex.vo.BoardVo -->
    	<![CDATA[
        	SELECT * FROM MVC_BOARD ORDER BY bgroup desc, bstep asc
        ]]>
	</select>
</mapper>
  • @Service
@Slf4j
@Service
public class BoardServiceImpl implements BoardService {
	@Autowired
	private BoardMapper boardMapper;
	
	@Override
	public List<BoardVo> showList() {
		log.info("showList()..");
		return boardMapper.selectList();
	}
}

일대일 관계 (One-to-One Relationship):

  • 이 관계에서 하나의 엔티티(instance)는 다른 엔티티와 정확히 하나의 관계만 가진다.
  • 예를 들어 한 사람은 한 번의 운전면허만 가질 수 있고, 한 운전면허는 한 명의 사람에 의해서만 소유될 수 있다.

일대다 관계 (One-to-Many Relationship):

  • 이 관계에서 하나의 엔티티(instance)는 다른 엔티티와 여러 개의 관계를 가질 수 있다.
  • 예를 들어 하나의 회사는 여러 개의 부서를 가질 수 있지만, 각 부서는 하나의 회사에만 속할 수 있다.

다대다 관계 (Many-to-Many Relationship):

  • 이 관계에서 한 엔티티(instance)는 다른 엔티티와 여러 개의 관계를 가질 수 있으며, 그 반대도 마찬가지.
  • 예를 들어 학생과 강의 간의 관계에서 한 명의 학생은 여러 개의 강의를 수강할 수 있고, 하나의 강의에는 여러 명의 학생이 참여할 수 있다.

  • CompanyMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="edu.sejong.ex.mapper.CompanyMapper">
	<select id="selectSalGradeEmpList" resultMap="salGradeEmpMap">
    	<![CDATA[
        	select * from salgrade,emp where sal between losal and hisal
        ]]>       
	</select>
		
	<resultMap id="empMap" type="EmpVo">
		<id column="empno" property="empNo" />
		<result column="ename" property="ename" />
		<result column="job" property="job" />
		<result column="mgr" property="mgr" />
		<result column="hiredate" property="hiredate" />
		<result column="sal" property="sal" />
		<result column="comm" property="comm" />
		<result column="deptno" property="deptno" />  
	</resultMap>
	
	<resultMap id="salGradeEmpMap" type="SalGradeEmpVo">
		<id column="grade" property="grade"/>
    	<result column="losal" property="losal"/>
   		<result column="hisal" property="hisal"/>
   		<collection property="empList" resultMap="empMap" />			
	</resultMap>
</mapper>
  • @Service : CompanyServiceImpl.java
package edu.sejong.ex.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import edu.sejong.ex.mapper.CompanyMapper;
import edu.sejong.ex.vo.DeptEmpVo;
import edu.sejong.ex.vo.SalGradeEmpVo;

@Service
public class CompanyServiceImpl implements CompanyService {

	@Autowired
	CompanyMapper companyMapper;

	@Override
	public List<SalGradeEmpVo> showListWithGrade() {
		return companyMapper.selectSalGradeEmpList();
	}

}
  • @Controller : CompanyController.java
package edu.sejong.ex.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import edu.sejong.ex.service.CompanyService;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Controller
@RequestMapping("/emp")
public class CompanyController {
	
	@Autowired
	private CompanyService companyService;

	@GetMapping("/salgrade")
	public String companyListWithGrade(Model model) {
		log.info("companyListWithGrade()..");
		model.addAttribute("lists", companyService.showListWithGrade());
		return "/company/glist";
	}
}
  • view : /company/glist.jsp
    - 기존에 활용하던 view 파일을 가져와서, 필요한 부분만 수정한 상태.
    - rsp, lotto나 검색은 추가 파일이 없다면 작동하지 않음.
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
        integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"
        crossorigin="anonymous">
    </script>
</head>

<body class="d-flex flex-column justify-content-between vh-100">
    <header>
        <nav class="navbar navbar-expand-lg bg-body-tertiary" data-bs-theme="dark">
            <div class="container-fluid">
                <a class="navbar-brand" href="#">게임 사이트</a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse"
                    data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent"
                    aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="collapse navbar-collapse" id="navbarSupportedContent">
                    <ul class="navbar-nav me-auto mb-2 mb-lg-0">
                        <li class="nav-item">
                            <a class="nav-link" aria-current="page" href="${pageContext.request.contextPath}/lotto/list">로또</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" href="${pageContext.request.contextPath}/rsp/rsp_game">가위바위보</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link active" href="${pageContext.request.contextPath}/emp/salgrade">게시판</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" href="${pageContext.request.contextPath}/gugudan">구구단</a>
                        </li>
                    </ul>
                    <form class="d-flex" role="search">
                        <input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
                        <button class="btn btn-outline-success" type="submit">Search</button>
                    </form>
                </div>
            </div>
        </nav>
    </header>
    <main>
        <div class="container">
            <!-- Page Heading -->
            <h1 class="h3 m-3 text-gray-800 text-center">자유 게시판</h1>        
            <!-- DataTales Example -->
            <div class="card shadow mb-4">
                <div class="card-header py-3 text-center">
                    <h6 class="m-0 font-weight-bold text-primary">해당 게시판에서는 자유롭게 글을 작성하실 수 있습니다. 그러나 규칙에 어긋날 경우 삭제될 수 있습니다.</h6>
                </div>
                <div class="card-body">
                    <div class="table-responsive">
                        <table class="table table-bordered text-center align-middle" id="dataTable" width="100%" cellspacing="0">
                            <thead>
                                <tr class="table-danger">             
                                    <th>사원이름</th>
                                    <th>월급</th>                         
                                    <th>월급등급</th>                                                                        
                                </tr>
                            </thead>
                            <tfoot>
                                <tr class="table-danger">             
                                    <th>사원이름</th>
                                    <th>월급</th>                         
                                    <th>월급등급</th>                                                                        
                                </tr>
                            </tfoot>
                            <tbody >
                               <c:forEach var="member" items="${lists}">                            
	                             <c:forEach var="emp" items="${member.empList}">
	                             	<tr>
	                             		<td>${emp.ename}</td>										
                                  		<td>${emp.sal}</td>
                                  		<td>${member.grade}</td>                                		
                                	</tr>
                                 </c:forEach>                                                          
                               </c:forEach>
                            </tbody>
                        </table>
                        <div class="">
	                        <nav aria-label="Page navigation example">
								<ul class="pagination justify-content-center">
									<li class="page-item disabled"><a class="page-link">Previous</a></li>
									<li class="page-item"><a class="page-link" href="#">1</a></li>
									<li class="page-item"><a class="page-link" href="#">2</a></li>
									<li class="page-item"><a class="page-link" href="#">3</a></li>
									<li class="page-item"><a class="page-link" href="#">Next</a></li>
								</ul>
							</nav>
						</div>
                    </div>
                </div>
                <div class="card-footer text-center py-2">
             		<button type="button" class="btn btn-success" data-bs-toggle="modal" data-bs-target="#write">
				  		글쓰기
					</button>
                </div>
                <!-- Button to Open the Modal -->				
				<!-- The Modal -->
				<div class="modal" id="write">
				  <div class="modal-dialog modal-dialog-centered modal-dialog-scrollable modal-fullscreen-sm-down">
				    <div class="modal-content">				
				      <!-- Modal Header -->
				      <div class="modal-header d-flex justify-content-between">
				      	<div class="col"></div>
				      	<div class="col text-center">
				        	<h4 class="modal-title">글쓰기</h4>
				        </div>
				        <div class="col d-flex justify-content-end">
				        	<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
				        </div>
				      </div>				
				      <!-- Modal body -->
				      <form action="${pageContext.request.contextPath}/board/write.do" method="post">
					      <div class="modal-body">
					       	<p class="my-2"> Type </p> 
							<p class="my-2">
								<select class="w-100 bg-secondary text-white rounded border-dark-subtle" type="text" readonly="readonly">
									<option class="w-100" value="1">자유 게시판</option>
								</select>
		                   	</p>	                 
		                  	<p class="my-2">이름</p>
		                    <p class="my-2"><input class="w-100 rounded" type="text" name="bname" ></p>
		                    <p class="my-2">제목</p>
		                    <p class="my-2"><input class="w-100 rounded" type="text" name="btitle" ></p>
		                    <p class="my-2 text-left">내용</p>	
		                    <textarea name="bcontent" class="w-100 rounded" rows="6" cols="5"></textarea>
					      </div>				
					      <!-- Modal footer -->
					      <div class="modal-footer d-flex justify-content-between">			      	
				        	<button type="button" class="btn btn-danger" data-bs-dismiss="modal">Close</button>
				        	<button type="submit" class="btn btn-primary">write</button>
					      </div>
				      </form>				
				    </div>
				  </div>
				</div>
            </div>
        </div>
    </main>
    <footer class="text-center ">
    	<hr>
    	<div class="d-flex justify-content-evenly">
	    	<div class="col">
	    	</div>
	        <div class="col align-middle">
	        	<p>© Company 2023-2024 </p>
	        </div>
	        <div class="col">
	        	<p id="nowDate" class=" border p-1 rounded bg-info text-white"></p>
	        </div>
	        <script>
				function time(){
					let nowDate = new Date();
					let nowHour = nowDate.getHours();
					let nowMinute = nowDate.getMinutes();
					let nowSecond = nowDate.getSeconds();
					
					let dateStr = "현재 시각 : "+ nowHour + "시 " + nowMinute + "분 " + nowSecond + "초";
					
					let nowDateElement = document.getElementById("nowDate");				
					nowDateElement.innerHTML = dateStr;
				}			
				setInterval(time,1000);
		    </script>
		</div>
    </footer>
</body>

</html>

profile
두리둥둥

0개의 댓글