왜 서블릿을 상속받아야 하는 거지??
- 서버에 접속하는 클라이언트를 위한 웹서비스를 제공해야 한다.
- stateless의 장단점 중 단점을 보완하기 위한 [[Session]]과 쿠키(동시접속자 처리 가능)
- http 프로토콜 API -> request, response를 갖고 있기 때문!! 그래야 다음으로 연결이 될 수 있음.
요청객체, 응답객체
- req : request(getParameter : String), getAttribute(세션) : Object
- res : setContentType("text/html:utf-8"); / 응답을 처리하는 건 JSP가 아니라 html(JSP라 쓰고 html이라 읽는다)
- UI솔루션, ReactJS 라이브러리 이종간 활용을 위한 JSON 형전환 필요(JSON.stringify-jsom화, JSON.parse-배열화)
- 이런 방식은 직관적이지 않다. 객체지향규칙(solid규칙)에도 부합하지 않는다.
페이지 전환 시 유의사항 : 유지
한계 :
- 요청을 jsp가 받는 설계([[모델1]]) -> 재사용성, 이식성의 문제 발생
- 결합도가 높은 설계 -> 제어 역전이 아니다
- 컨트롤러에서 getRequestURI()를 통해 결정된 이름으로 메소드를 호출한다
- 메소드마다 url 적용할 수 없어 if문으로 처리함. (upmu[0] = 업무 이름, upmu[1] = 메소드 이름)
- 서블릿단에서 직접 결과값을 내보냄.
개선 :
- 요청을 서블릿이 받는 설계([[모델2]]) [[POJO2]]를 다시 설계해보자
- 요청 처리를 담당할 클래스를 결정하는 일을 전담하는 클래스(or 인터페이스) 설계
- 스프링에서는 메소드마다 매핑을 지원하는 어노테이션이 지원된다
- @RequestMapping, @GetMapping, @PostMapping이 지원된다
<jsp:useBean id = "myCar" class = "com.di.Sonata" scope = page|request|session|application/>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | <?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="com.mybatis.mapper.NoticeMapper"> <insert id="noticeInsert" parameterType="map"> INSERT INTO notice(n_no, n_title, n_content, n_writer) VALUES(seq_notice_no.NEXTVAL, #{n_title}, #{n_content}, #{n_writer}) </insert> <update id="noticeUpdate" parameterType="map"> UPDATE notice set n_title = #{n_title} , n_content = #{n_content} , n_writer = #{n_writer} WHERE n_no = #{n_no} </update> <delete id="noticeDelete" parameterType="map"> DELETE FROM notice WHERE n_no = #{n_no} </delete> <select id="noticeList" parameterType="map" resultType = "map"> select n_no, n_title, n_content, n_writer from notice <where> <if test="n_no!=null">AND n_no=#{n_no}</if> <if test="gubun!=null"> <choose> <when test='gubun.equals("n_title")'> AND n_title LIKE '%'||#{keyword}||'%' </when> <when test='gubun.equals("n_content")'> AND n_title LIKE '%'||#{keyword}||'%' </when> <when test='gubun.equals("n_writer")'> AND n_title LIKE '%'||#{keyword}||'%' </when> </choose> </if> </where> </select> </mapper> | cs |
[!tip] 이게 대체 무엇을 위한 실습인가??
화면이 없어도 나는 개발을 진행할 수 있다. 어떻게? 포스트맨을 통해서 단위테스트가 가능하기 때문이다.
나는 과연 테스트 시나리오를 알고 있는가?? 아래의 설계가 익숙해졌는가?
- 등록, 삭제 : jsp(입력) - 서블릿(insert) - 서블릿(select) - jsp(뷰)
- 수정 : 서블릿(select) - jsp(입력) - 서블릿(update) - 서블릿(select) - jsp(수정하기) 의 설계에 익숙해졌는가
- 전체조회 : 서블릿(select) - jsp - 전체조회
- 상세보기 : jsp - 서블릿(select) - jsp - 상세보기
💡 그러니까 스타일 파일은 file로 하고, 태그 안에는 page로 넣는거네!
[!example] 용어 참고용
m : margin - 외부여백
p : padding - 안쪽여백
t : top
b : bottom
l : left
r : right
x : x축
y : y 축
rem : 루트 크기의 25%(상대적 크기 설정 가능)
- while문으로 반복해서 db에 넣고, 가져오는 반복문을 사용해야 함.
========================================================[!tip] 정리하자면?
JDBC는 DB 작업시 많은 코드 작성이 필요(복잡)
반면, MyBatis 사용 시 jdbc 직접 호출하지 않고, MyBatis에게 일을 시키고, 쿼리문을 xml로 코드를 분리하여(SQL 매핑) 유지보수성이 높다.
🖥단위테스트 진행 시
어떤 것을 테스트 하고자 하는지 알고 있어야 하고, 로그에 나오는 값 혹은 에러에 따라 어디까지 코드가 실행되었고, 어디에서 에러가 발생했는지 찾고 보완할 수 있도록 로그를 만들고, 보는 연습이 많이 필요하다.