[Spring] mybatis 방식을 통한 jdbc 예문_select, insert, update, delete
https://jinnnkcoding.tistory.com/179
저번 포스팅을 통해 환경 설정이 완료되었다면,
코드가 어떻게 구성하는지와 실제 URL이 어떻게 매핑이 되는지 알아보겠다.
emp테이블
dept테이블
URL 매핑과 뷰 설정 - @Controller
우선 컨트롤러만 모아둘 패키지 com.mybatis.controller를 생성한다.
생성한 패키지 안에 EmpController란 이름의 클래스를 하나 생성한다.
(자료 찾아보니 다른 사람들은 MainController 라는 이름으로 생성하더라...강사님은 예문으로 Emp테이블을 사용하셔서 저렇게 명명한듯..)
package com.mybatis.controller;
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
/**
* Handles requests for the application home page.
*/
@Controller
public class HomeController {
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
/**
* Simply selects the home view to render by returning its name.
*/
@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
logger.info("Welcome home! The client locale is {}.", locale);
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
String formattedDate = dateFormat.format(date);
model.addAttribute("serverTime", formattedDate );
return "home";
}
}
기본적으로 @Controller가 되어있고, @RequestMapping으로 메소드가 선언되어있다.
value의 값은 현재 '/' 로 루트경로로 되어있다. 그리고 메소드 방식으로 GET방식을 지원하고 있다.
@Controller의 의미는 해당 메소드가 특정 value에 맞는 URL요청이 왔을 시 처리하는 메소드가 된다.
해당 어노테이션이 붙게 되면 스프링 환경에서 인식가능한 파일이라는 'S' 자가 붙게 된다.
@RequestMapping은 매핑정보를 설정하는 어노테이션이다. 이는 기존 JSP환경에서 web.xml에 정의했던 것과 동일하다. 즉 value에는 url-pattern을 명시해주는것이고, RequestMethod는 RESTful API를 설정하게 된다.
정리를 해보면 URL '/' 로 GET요청을 할 시 home이라는 Controller메소드가 실행된다는 의미이다.
마지막에는 return으로 String값을 반환하고 있다. 이는 문자열 반환이 아닌 해당 URL이 가지고 있는 뷰를 명시하게 된다.
즉 home.jsp파일을 호출하겠다는 의미이다
어떻게?
스프링이 알아서 분석하고 자동으로 src/main/webapp/WEB-INF/views 안에 있는 home.jsp와 연결해준다.
이에 관한 설정은 servlet-context.xml에 작성되어 있다.
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
servlet-context.xml을 보면 name=”prefix”로 된 부분에 “/WEB-INF/views“가 적혀있고
name=”suffix”로 된 부분엔 “.jsp“가 작성되어 있다.
이 설정에 따라 “home”을 리턴하면 home의 앞엔 prefix부분이,
뒤엔 suffix부분이 자동으로 붙어 /WEB-INF/views/home.jsp가 완성되는 것이다.
(위에 달린 주석도 번역하자면 "/WEB-INF/views 디렉토리의 .jsp 리소스로 @Controllers가 렌더링하기 위해 선택한 보기를 확인합니다.")
따라서 이러한 방식
EmpController에서 클래스 이름 위에 @Controller 어노테이션을 추가한다.
어노테이션을 입력한 뒤 cntl + shift + o 단축키를 이용하면 자동으로 스프링 프레임워크에서 필요한 부분을 임포트한다.
이제 이 EmpController클래스는 스프링에서 컨트롤러 역할을 하는 클래스가 된 것이다.
* URL 매핑
Emp 테이블의 전체 레코드 값을 가져오는 비즈니스 로직을 작성해본다.
@RequestMapping이란 어노테이션이 사용됐다.
이 어노테이션의 역할은 ()안에 있는 경로와 컨트롤러를 이어주는것(매핑)이다.
“루트/”경로로 접속을 시도하면 EmpController가 담당을 하고 아래 메소드에 있는 경로들은 “루트/” 뒤에 붙는 값이 된다.
EmpDTO.java
package com.spring.model;
import lombok.Data;
@Data
public class EmpDTO {
private int empno;
private String ename;
private String job;
private int mgr;
private String hiredate;
private double sal;
private double comm;
private int deptno;
}
DeptDTO.java
package com.spring.model;
import lombok.Data;
@Data
public class DeptDTO {
private int deptno;
private String dname;
private String loc;
}
@data 애노테이션을 사용하여 getter, setter 메서드를 한번에 생성
EmpDAO.java
package com.spring.model;
import java.util.List;
public interface EmpDAO {
List<EmpDTO> getEmpList(); // 전체 사원 목록 관련 추상메서드
int empInsert(EmpDTO dto); // 사원을 등록(추가)하는 추상메서드
EmpDTO empCont(int empno); // 사원번호에 해당하는 사원의 정보 조회하는 추상메서드
int empUpdate(EmpDTO dto); // 특정 사원의 사원 정보를 수정하는 추상메서드
int empDelete(int empno); // 특정 사원를 emp 테이블에서 삭제하는 추상메서드
List<DeptDTO> getDeptList(); // 부서 테이블 전체 리스트 관련 추상메서드
List<EmpDTO> getMgrList(); // 관리자만을 조회하는 추상메서드
List<String> getJobList(); // 직업 목록을 조회하는 추상메서드
}
일단은 추상메서드로 구현한다.
EmpDAO를 상속받은 클래스, EmpDAOImpl.java 선언
package com.spring.model;
import java.util.List;
public class EmpDAOImpl implements EmpDAO{
@Override
public List<EmpDTO> getEmpList() {
// TODO Auto-generated method stub
return null;
}
@Override
public int empInsert(EmpDTO dto) {
// TODO Auto-generated method stub
return 0;
}
@Override
public EmpDTO empCont(int empno) {
// TODO Auto-generated method stub
return null;
}
@Override
public int empUpdate(EmpDTO dto) {
// TODO Auto-generated method stub
return 0;
}
@Override
public int empDelete(int empno) {
// TODO Auto-generated method stub
return 0;
}
@Override
public List<DeptDTO> getDeptList() {
// TODO Auto-generated method stub
return null;
}
@Override
public List<EmpDTO> getMgrList() {
// TODO Auto-generated method stub
return null;
}
@Override
public List<String> getJobList() {
// TODO Auto-generated method stub
return null;
}
}
일단은 이렇게 override 틀만 잡아놓는다.
https://mybatis.org/spring/ko/sqlsession.html
SqlSession 사용
마이바티스에서는 SqlSession를 생성하기 위해 SqlSessionFactory를 사용한다. 세션을 한번 생성하면 매핑구문을 실행하거나 커밋 또는 롤백을 하기 위해 세션을 사용할수 있다. 마지막으로 더 이상 필요하지 않은 상태가 되면 세션을 닫는다. 마이바티스 스프링 연동모듈을 사용하면 SqlSessionFactory를 직접 사용할 필요가 없다. 왜냐하면, 스프링 트랜잭션 설정에 따라 자동으로 커밋 혹은 롤백을 수행하고 닫혀지는, 쓰레드에 안전한 SqlSession 개체가 스프링 빈에 주입될 수 있기 때문이다.
SqlSessionTemplate
SqlSessionTemplate은 마이바티스 스프링 연동모듈의 핵심이다. SqlSessionTemplate은 SqlSession을 구현하고 코드에서 SqlSession를 대체하는 역할을 한다. SqlSessionTemplate 은 쓰레드에 안전하고 여러개의 DAO나 매퍼에서 공유할수 있다.
getMapper()에 의해 리턴된 매퍼가 가진 메서드를 포함해서 SQL을 처리하는 마이바티스 메서드를 호출할때 SqlSessionTemplate은 SqlSession이 현재의 스프링 트랜잭션에서 사용될수 있도록 보장한다. 추가적으로 SqlSessionTemplate은 필요한 시점에 세션을 닫고, 커밋하거나 롤백하는 것을 포함한 세션의 생명주기를 관리한다. 또한 마이바티스 예외를 스프링의 DataAccessException로 변환하는 작업또한 처리한다.
SqlSessionTemplate은 마이바티스의 디폴트 구현체인 DefaultSqlSession 대신 항상 사용된다. 왜냐하면 템플릿은 스프링 트랜잭션의 일부처럼 사용될 수 있고 여러개 주입된 매퍼 클래스에 의해 사용되도록 쓰레드에 안전하다. 동일한 애플리케이션에서 두개의 클래스간의 전환은 데이터 무결성 이슈를 야기할수 있다.
SqlSessionTemplate은 생성자 인자로 SqlSessionFactory를 사용해서 생성될 수 있다.
SqlSessionTemplate을 사용하기 위해 EmpDAOImpl에 SqlSessionTemplate 변수를 선언해준다.
private SqlSessionTemplate sqlSession;