Mapper XML 파일에 mybatis가 수행할 SQL 문장을 만들어 저장하는 2가지 방법
1) Mapper XML 파일에 SQL 문장을 저장
- Mapper XML 파일명의 관례 -> 테이블명Mapper.xml ex)BoardMapper.xml
2) 자바 인터페이스의 추상메소드에 저장 ("Mapper Interface" 방식)
- MyBatis가 제공하는 Annotation을 추상메소드 위에 붙이고 이 Annotation 속성으로 SQL 문장을 저장
어제는 1)로 해봤다.
이제 Mapper Interface 방식으로 해보자!
---
org.zerock.myapp.mapper에 EmployeesMapper.java 만들어주자
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.zerock.myapp.mapper.EmployeesMapper">
<select
id="getAllEmployeesNames"
resultType="java.lang.String">
SELECT last_name
FROM employees
WHERE employee_id > 0
</select>
</mapper>
EmployeesMapper.java
이제 root-context.xml에 scan tag를 넣어주자
이클립스에서 namespace - mybatis-spring 체크해서
xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring" 이걸 추가해준다
이후에 vscode에서 <mybatis-spring:scan base-package="org.zerock.myapp.mapper" /> 추가해주자
root-context.xml
* 마이바티스는 아래의 자동실행규칙을 따르는 경우
(1) Mapper Interface의 패키지와 동일한 폴더구조를 생성하라
(2) (1)에서 생성한 폴더 아래에 Mapper Interface의 타입명과 동일한 이름의 Mapper XML 파일을 생성하라
(3) (2)에서 생성한 Mapper XML 파일의 namespace 속성의 값은 Mapper Interface의 FCQN으로 한다
(4) (2)에서 생성한 Mapper XML 파일에 등록한 SQL 문장의 id 속성의 값은 Mapper Interface의 추상메소드 이름과 동일하게 지어라
resources에 org.zerock.myapp.mapper 만들어주자
그 아래에 EmployeesMapper.xml 만들어주자
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.zerock.myapp.mapper.EmployeesMapper">
<select
id="getAllEmployeesNames"
resultType="java.lang.String">
SELECT last_name
FROM employees
WHERE employee_id > 0
</select>
</mapper>
EmployeesMapper.xml
SqlSessionFatoryTests에서 이제 써보자
@Log4j2
@NoArgsConstructor
//테스트 메소드 수행시 스프링 프레임워크까지 함께 구동되도록 해주는 어노테이션 설정 추가
// JUnit5 방식
@ExtendWith(SpringExtension.class)
@ContextConfiguration(locations = {
"file:src/main/webapp/WEB-INF/spring/root-context.xml"
})
@TestInstance(Lifecycle.PER_CLASS)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class SqlSessionFactoryTests {
@Setter(onMethod_= {@Autowired})
private SqlSessionFactory sqlSessionFactory;
@BeforeAll
void boforeAll() {
log.trace("boforeAll() invoked.");
// 필드에 의존성 객체가 주입되었는지 확인 (주입되었다면 null이 아님)
assertNotNull(this.sqlSessionFactory); // 방법1
// Objects.requireNonNull(this.sqlSessionFactory); // 방법2
// assert this.sqlSessionFactory != null; // 방법3
log.info("\t+ this.sqlSessionFactory : {}", this.sqlSessionFactory);
} // boforeAll
// @Disabled
@Test
@Order(1)
@DisplayName("1. testFirstMapperXML")
@Timeout(value = 10, unit = TimeUnit.SECONDS)
void testFirstMapperXML() {
log.trace("testFirstMapperXML() invoked.");
@Cleanup
SqlSession sqlSession = this.sqlSessionFactory.openSession();
// Mapped Statement를 결정하기 위한 요소 2가지
String namespace = "FirstMapper";
String sqlId = "DQL1";
String sql = namespace + "." + sqlId;
// sqlSession.selectList(sql, 130);
List<EmployeeVO> list = sqlSession.<EmployeeVO>selectList(sql, 130);
list.forEach(log::info);
} // testFirstMapperXML
// @Disabled
@Test
@Order(2)
@DisplayName("2. testSecondMapperXML")
@Timeout(value = 20, unit = TimeUnit.SECONDS)
void testSecondMapperXML() {
log.trace("testSecondMapperXML() invoked.");
@Cleanup
SqlSession sqlSession = this.sqlSessionFactory.openSession();
// Mapped Statement를 결정하기 위한 요소 2가지
String namespace = "SecondMapper";
String sqlId = "DQL2";
String sql = namespace + "." + sqlId;
// SQL 문장에 줄 바인딩 변수가 2개! 이러면 Map객체 혹은 자바빈즈 객체를 사용한다.
// 지난번엔 Map 객체로 했다! (90일차) 이번엔 자바빈즈로 해보자 (property가 바인딩 변수명)
@Data
class Parameters { // 로컬 클래스로 자바빈즈 클래스를 만들자
private String email;
private Double sal;
} // end class
// 자바빈즈 객체를 생성하자
Parameters params = new Parameters();
// 바인딩 변수의 값을 넣어주자
params.setEmail("%A%");
params.setSal(7000.0);
// 자바빈즈 객체 params로 전해주자
List<EmployeeVO> list = sqlSession.<EmployeeVO>selectList(sql, params);
list.forEach(log::info);
} // testSecondMapperXML
// @Disabled
@Test
@Order(3)
@DisplayName("3. testGetAllEmployeesInEmployeesMapper")
@Timeout(value = 20, unit = TimeUnit.SECONDS)
void testGetAllEmployeesInEmployeesMapper() {
log.trace("testGetAllEmployeesInEmployeesMapper() invoked.");
@Cleanup
SqlSession sqlSession = this.sqlSessionFactory.openSession();
try (sqlSession) {
// Mapper Interface 방식은 이렇게 한다!
EmployeesMapper mapper = sqlSession.<EmployeesMapper>getMapper(EmployeesMapper.class);
Objects.requireNonNull(mapper);
log.info("\t+ mapper : {}, type : {}", mapper, mapper.getClass().getName() );
mapper.getAllEmployees().forEach(log::info);
} // try-with-resources
} // testGetAllEmployeesInEmployeesMapper
// @Disabled
@Test
@Order(4)
@DisplayName("4. testGetAllEmployeesNames")
@Timeout(value = 20, unit = TimeUnit.SECONDS)
void testGetAllEmployeesNames() {
log.trace("testGetAllEmployeesNames() invoked.");
@Cleanup
SqlSession sqlSession = this.sqlSessionFactory.openSession();
try (sqlSession) {
// Mapper Interface 방식은 이렇게 한다!
EmployeesMapper mapper = sqlSession.getMapper(EmployeesMapper.class);
assertNotNull(mapper);
log.info("\t+ mapper : {}, type : {}", mapper, mapper.getClass().getName() );
mapper.getAllEmployeesNames().forEach(log::info);
} // try-with-resources
} // testGetAllEmployeesNames
} // end class
SqlSessionFatoryTests.java
---
실습해보자!
public interface TimeMapper {
// 방법1) 어노테이션 방식 (바로 테스트 메소드에서 사용가능)
@Select("SELECT to_char(sysdate, 'yyyy/MM/dd HH24:mi:ss') AS now FROM dual")
public abstract String getCurrentTime1();
// 방법2) 자동실행규칙 방식 (TimeMapper.xml 만들어줘야함)
// Mapper XML 파일의 SQL 문장으로 현재시간 반환
public abstract String getCurrentTime2();
} // end interface
TimeMapper.java
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.zerock.myapp.mapper.TimeMapper">
<select
id="getCurrentTime2"
resultType="java.lang.String">
SELECT to_char(current_date, 'yyyy/MM/dd HH24:mi:ss') AS now
FROM dual
</select>
</mapper>
TimeMapper.xml
@Log4j2
@NoArgsConstructor
//테스트 메소드 수행시 스프링 프레임워크까지 함께 구동되도록 해주는 어노테이션 설정 추가
// JUnit5 방식
@ExtendWith(SpringExtension.class)
@ContextConfiguration(locations = {
"file:src/main/webapp/WEB-INF/spring/root-context.xml"
})
@TestInstance(Lifecycle.PER_CLASS)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class TimeMapperTests {
@Setter(onMethod_= {@Autowired})
private SqlSessionFactory sqlSessionFactory;
@BeforeAll
void boforeAll() {
log.trace("boforeAll() invoked.");
// 필드에 의존성 객체가 주입되었는지 확인 (주입되었다면 null이 아님)
assertNotNull(this.sqlSessionFactory); // 방법1
// Objects.requireNonNull(this.sqlSessionFactory); // 방법2
// assert this.sqlSessionFactory != null; // 방법3
log.info("\t+ this.sqlSessionFactory : {}", this.sqlSessionFactory);
} // boforeAll
// @Disabled
@Test
@Order(1)
@DisplayName("1. testGetCurrentTime1")
@Timeout(value = 10, unit = TimeUnit.SECONDS)
void testGetCurrentTime1() {
log.trace("testGetCurrentTime1() invoked.");
SqlSession sqlSession = this.sqlSessionFactory.openSession();
try (sqlSession) {
// Mapper Interface 방식은 이렇게 한다!
TimeMapper mapper = sqlSession.getMapper(TimeMapper.class);
assertNotNull(this.sqlSessionFactory);
log.info("\t+ mapper : {}, type : {}", mapper, mapper.getClass().getName() );
String time = mapper.getCurrentTime1();
log.info("\t+ time : {}", time);
} // try-with-resources
} // testGetCurrentTime1
// @Disabled
@Test
@Order(2)
@DisplayName("2. testGetCurrentTime2")
@Timeout(value = 10, unit = TimeUnit.SECONDS)
void testGetCurrentTime2() {
log.trace("testGetCurrentTime2() invoked.");
SqlSession sqlSession = this.sqlSessionFactory.openSession();
try (sqlSession) {
// Mapper Interface 방식은 이렇게 한다!
TimeMapper mapper = sqlSession.getMapper(TimeMapper.class);
assertNotNull(this.sqlSessionFactory);
log.info("\t+ mapper : {}, type : {}", mapper, mapper.getClass().getName() );
String time = mapper.getCurrentTime2();
log.info("\t+ time : {}", time);
} // try-with-resources
} // testGetCurrentTime2
} // end class
TimeMapperTests.java
---
part2
목차
MVC구조의 이해
스프링 MVC의 다양한 예제의 학습
스프링 MVC를 이용하는 파일 업로드 연습
스프링 MVC의 예외처리
Model 2 Architecture = MVC Pattern
MVC(Model-View-Controller)
대부분의 서블릿 기반 프레임워크들이 사용하는 방식
데이터와 처리, 화면을 분리하는 방식
웹에서는 Model 2 방식으로 표현
---
*웹3계층
1) Presentation Layer 표현계층 => MVC (Spring MVC)
2) Business Layer 서비스계층
3) Persistence Layer 영속성계층
---
이제부터 구현을 배울 Controller라는 것은 MVC 패턴에서 Controller에 해당되며,
요청이 들어왔을 때부터 응답이 나가기까지 모든 흐름을 제어하는 자이다.
은행에 갔다고 가정, 비지니스 로직을 알아보자
0) 요청 : 계좌이체 해주세요
1) 신분증 제시 - 본인확인
2) 통장과 작성한 이체영수증 제시
3) 통장의 유효성 검증
4) 이체 영수증에 있는 대로 통장 안에 잔고가 충분한지 검사
5) 타겟 계좌의 유효성 검증
6) 통장에서 출금
7) 타겟 계좌에 입금
8) 응답 : 계좌이체 완료되었습니다.
chap05에서 main java에 controller 만들어주자...
---
컨트롤러 만들기 전에 아래 내용 이해하고 가자!
스프링 설정파일들
1) web.xml
2) root-context.xml
3) servlet-context.xml
앞으로 배울 컨트롤러의 제작방법은 10~15가지이다. 이렇게 다양한 방법을 배우는 만큼 요청 ~ 응답이 나가기까지의 다양한 처리제어의 방법을 알게된다.
web.xml 파일을 수정해주자
servlet-context.xml 파일도 수정하자
include.jsp 만들자
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
include.jsp
연휴동안 Servlet/Jsp 다시 복습 하세요!
'국비학원' 카테고리의 다른 글
[국비지원] KH 정보교육원 99일차 (0) | 2022.08.18 |
---|---|
[국비지원] KH 정보교육원 98일차 (0) | 2022.08.17 |
[국비지원] KH 정보교육원 96일차 (0) | 2022.08.12 |
[국비지원] KH 정보교육원 95일차 (0) | 2022.08.11 |
[국비지원] KH 정보교육원 92-94일차 (0) | 2022.08.11 |