[2023.12.07] 개발자 교육 54일 차 : 강의-서블릿&JSP 실습 [구디 아카데미]

DaramGee·2023년 12월 7일
0

복습

POJO 1 소스 리뷰

  • 왜 서블릿을 상속받아야 하는 거지??
    - 서버에 접속하는 클라이언트를 위한 웹서비스를 제공해야 한다.
    - 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이 지원된다


강의 내용

[[POJO 1]] 개선해보기

  • 그나저나 JSP는 액션태그로 객체를 생성할 수 있다고??
<jsp:useBean id = "myCar" class = "com.di.Sonata" scope = page|request|session|application/>
  • notice.xml 수정(for 상세 조회, 전체 조회 관련 DML문 추가()
    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 - 상세보기

JSP 화면구현 with Bootstrap

  • jsp include?
    - include file : 정적, 빠름(but, 파라미터 주기만 가능)
    - include page : 동적, 상대적 느림(파라미터 주고받기 가능)

💡 그러니까 스타일 파일은 file로 하고, 태그 안에는 page로 넣는거네!

[!example] 용어 참고용
m : margin - 외부여백
p : padding - 안쪽여백
t : top
b : bottom
l : left
r : right
x : x축
y : y 축
rem : 루트 크기의 25%(상대적 크기 설정 가능)


DB연동 차이

  • JDBC API
    - Class.forName("oracle.jdbc.driver.oracleDriver") -> Connection -> PreparedStatement -> Resultset
    - while문으로 반복해서 db에 넣고, 가져오는 반복문을 사용해야 함. 
    ========================================================
  • myBatis API
    - 위 연결 과정이 계속해서 반복 -> SqlSessionFactory로 해결(MapperConfig.xml-드라이버, ip, 포트, SID, id, pw, 물리적위치-프로젝트 xml)
    - SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
  • DML에서 while문 생략 가능 왜?? select resultMap = "map"을 통 해 한 행 씩 담을 수 있고, n개의 행들이 들어가는 것은 List에 있다.
    - SqlSession sqlSession = sqlSessionFactory.openSession(); // 메소드 호출로 객체를 주입 받음.(고급)
    - sqlSession.commit(), sqlSession.rollback()
    - sqlSession.selectOne{Object 1건 VO, Map -String}("id")
    - sqlSession.selectMap{Map 1건} -> 우선순위 낮음
    - List = sqlSession.selectList{List n건} -> n건만큼 반복(1건 - Map, Map, Map)
    - 마치 open - cursor - fetch - close처럼 select 되어 리스트맵으로 담는 것
    - 의존 관계 있는 클래스 혹은 인터페이스가 메소드 호출로 객체를 주입함.
    - (parameterMap, resultMap 다르다는 것 알아야 함.)

[!tip] 정리하자면?
JDBC는 DB 작업시 많은 코드 작성이 필요(복잡)
반면, MyBatis 사용 시 jdbc 직접 호출하지 않고, MyBatis에게 일을 시키고, 쿼리문을 xml로 코드를 분리하여(SQL 매핑) 유지보수성이 높다.


포스트맨 활용을 통한 단위테스트

🖥단위테스트 진행 시
어떤 것을 테스트 하고자 하는지 알고 있어야 하고, 로그에 나오는 값 혹은 에러에 따라 어디까지 코드가 실행되었고, 어디에서 에러가 발생했는지 찾고 보완할 수 있도록 로그를 만들고, 보는 연습이 많이 필요하다.

강의 마무리

  • POJO step1 마무리 후, 개선하는 step2 실습 예정

0개의 댓글