본문 바로가기
Framework/MyBatis

[00] 프레임워크 개념 / mybatis 준비 / Filter 활용

by 예스p 2023. 2. 13.

프레임워크

이전의 레거시방식에서 벗어나 프레임 워크를 적용해보자.


Framework 란?

  • 개발자가 소프트웨어를 개발함에 있어 코드를 구현에 드는 시간을 줄이고, 코드의 재사용성을 증가 시키기 위해 일련의 클래스 묶음이나 뼈대 틀을 제공하는 라이브러리를 구현해 놓은 것
  • 프로젝트의 규모가 커질수록 개발자들이 많아짐 >> 다양해진 스타일들로 인해 한계에 부딫힘 >> 통일성 있게 개발할 수 있는 틀을 만들고자 프레임워크 탄생
  • 프레임워크의 등장으로 정형화 됨 >> 개발 당사자가 아니어도 유지보수 가능해짐 >> 유지보수 전문업체들(SM)이 생겨나남

 

 

Framework 의 특징

  1. 개발자가 따라야 하는 가이드를 제공한다
    => 자유롭게 설계하고 프로그래밍하는것이 불가능하다
  2. 개발할 수 있는 범위가 정해져 있다
    =>단 범위는 넓다.
  3. 개발자를 위한 다양한 도구 , 플러그인들을 지원한다
  4. 장점 :
    - 개발 시간을 줄일 수 있음
    - 정형화되어 있어 일정수준 이상의 품질을 기대할 수 있음
    - 유지 보수가 쉬움
    - 오류로부터 자유로워질 수 있다.(단 초기 적응 필요)
  5. 단점
    - 너무 의존하면 개발자들의 능력이 떨어져서 스스로 직접 개발하는 것이 어려워짐
    - 습득에 걸리는 시간이 오래 걸림

 

 

Framework 의 종류

  • 영속성 Framework
    - 데이터의 저장 , 조회 , 변경 , 삭제(CRUD)를 다루는 클래스 및 설정 파일들을 라이브러리화하여 구현한 프레임워크
    - Mybatis, Hibernate, JPA(추가공부하면 좋음)
  • 자바 Framework
    - Java EE를 통한 웹 어플리케이션 개발에 초점을 맞추어 필요한 요소들을 모듈화 하여 제공하는 프레임워크
    - Spring Framework, Spring(전자정부표준), Struts
  • 화면 구현 Framework
    - FrontEnd 를 보다 쉽게 구현할 수 있게 틀을 제공하는 프레임워크
    - Bootstrap, Foundation, MDL
  • 기능 및 지원 Framework
    - 특정기능이나 업무 수행에 도움을 줄 수 있는 기능을 제공하는 프레임워크
    - Log4j, JUnit 5, ANT

 

 


Mybatis

mybatis를 배우기 위한 프로젝트 세팅을 해보자.


MyBatis란?

  • 자바를 위한 영속성 프레임워크
  • DB와 자바객체 사아의 매핑을 단순화하고 SQL 쿼리 실행과 결과 매핑을 처리한다.
  • 주요 역할
    - SQL 매핑: SQL 쿼리를 별도의 파일에 분리하여 관리할 수 있게 한다. 
    - 파라미터 매핑: SQL 쿼리에 전달되는 파라미터와 자바 객체 간의 매핑이 가능하다.
    - 결과 매핑: 쿼리의 결과를 자바 객체로 매핑
    - 트랜잭션 관리: 설정을 통해 커밋 또는 롤백 관리
    - 다양한 데이터베이스 지원: 다양한 DBMS와 작동할 수 있도록 다양한 드라이버와 통합을 제공
  • 공식문서
    한글 : https://mybatis.org/mybatis-3/ko/index.html (번역이 매끄럽지 않을 수 있다.)
    영문 : https://mybatis.org/mybatis-3/index.html

 

 

이클립스 설정

** 기존설정진행과 동일하게 진행하되, 기존과 다른부분 : 

  1. Window - Perspective - Cutomize Perspective : 
    (오른클릭 - New 했을때 뜨는 파일종류들)
    - Java에 있는 Interface와 Source Foloder를 체크해준다.
      (XML파일등은 Source Folder를 만들어 보관하는것이 좋다.)
    - Web에서 Filter를 선택한다.
  2. views폴더를 webapp이 아닌 WEB-INF안에 만든다
    (스프링 프레임워크와 작업환경을 비슷하게 하기 위해)
    ** jsp페이지가 WEB-INF 폴더 안에 들어가는 순간 WAS가 관리하기 때문에
    포워딩 방식으로만 접근으로만 접근할 수 있다.
    (http://localhost:8888/mybatis/WEB-INF/views/new.jsp >> 불가)
  3. 메인페이지로 활용할 WEB-INF/views/main.jsp를 만든다.
    webapp/index.jsp에 포워드태그를 넣음으로써 간접적으로 메인페이지 역할을 하도록 한다.
    <jsp:forward page="WEB-INF/views/main.jsp" />
  4. 패키지를 만들때 세번째까지 베이스 패키지로 만든다.
    ex) com.br.mybatis.~~
    - common패키지 안에 filter와 template, model.vo 패키지를 만든다.
    - vo 클래스를 만들때 Date타입은 java.sql.Date로 import한다.

 

 

Mybatis 연동

  1. 마이바티스 공식사이트 (이용자가 한글로 번역해놓은 사이트) 들어가기
    (다양한 기능들이 설명되어있으므로 필요한 기능이 있을때 확인하면 좋다.)
  2. 왼쪽목록 [시작하기] >  mybatis-x.x.x.jar 클릭 > 3.5.9 버전 클릭
    > Assets의 zip파일 다운로드
    > 압축 푼 후 mybatis-3.5.9.jar파일을 찾아 lib 폴더에 붙여넣기

 

 

Mybatis사용법 읽어보기

  • 대부분의 프레임워크가 그러하듯, Mybatis도 공식사이트에 사용법이 잘 나와있다.
    왼쪽목록 > [시작하기]에 나와있는 주요 코드들을 살펴보자.
// ***XML에서 SqlSessionFactory 빌드하기***
String resource = "org/mybatis/example/mybatis-config.xml"; // 이때 config == 환경설정 문서
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
/*
 * SqlSessionFactory 객체를 생성하는 방법이다.
 * 해당 객체는 Service단에서 생성을 해주는데, 
 * 반복적인 메소드이므로 Template 클래스에서 static메소드로 만들어 활용해보도록 하자. 
 */
<!-- 환경설정 파일(config)인 만드는 코드가 나와있다. 
해당 파일을 참고해서 mybatis-config 파일을 만든다.-->
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration 
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
      </dataSource>
    </environment>
  </environments>
  <mappers>
    <mapper resource="org/mybatis/example/BlogMapper.xml"/>
  </mappers>
</configuration>

 

 

소스폴더 만들기

  • 소스폴더의 역할
    : 소스폴더는 Eclipse에서 Java 소스를 포함하는 것으로 인식하며, 프로젝트를 컴파일할 때 모든 소스 폴더에서 소스 코드를 찾는다. 일반 폴더는 Java Build Path에 추가함으로써 소스 폴더로 바꿀 수 있다. 
  • 소스폴더 만들기
    : 오른클릭 - New - Source Folder 선택
    프로젝트폴더 바로 하위에 resources라는 이름의 소스폴더를 만든다.
    하위로 일반폴더로 config(환경설정 관련 저장할 곳), mappers(sql 파일 저장할곳)을 만든다.
    SqlSessionFactory객체를 만들때 해당 구조가 필요하기 때문
    (스프링프레임워크에서도 별도로 만들어 두기도 함)
  • 소스폴더 생성확인 : 프로젝트 오른클릭 - Properties- Java BuildPath- Source탭
    해당 소스폴더들에 만들어진 파일들은 Default output folder에 지정한 경로로 동기화 되어 만들어진다.
    ** 종종 깃으로 받아들여지면 소스폴더로 등록이 안되는 경우가 있다.
       이런경우 Add Folder 눌러서 해당 파일을 선택해주면 된다.
  •  

 

 

mybatis-config 파일 만들기

  1. src/main/resources(소스폴더)/config/mybatis-config.xml을 만든다.
  2. 사용법을 참고하여 태그를 작성한다.
    이때 대소문자는 잘 지켜져야 한다.
  3. <configuration> : 해당 파일의 정체성이며 모든 내용을 감싼다.
  4. <configuration>의 하위태그
    <settings> : mybatis 구동시 선언할 설정들을 작성한다.
    <typeAliases> :하위로 <typeAlias>태그를 두어 풀클래스명 대신 부를 별칭을 등록한다.
    - type 속성 : 풀클래스명입력
    - alias 속성 : 별칭입력
    <environments> : mybatis에서 연동할 db에 대한 정보를 기재한다.
    여러개 지정할 수 있으며, default속성에 기본 연결할 설정의 아이디를 넣는다.
    <mappers> : 실행할 sql문들을 기록해둔 mapper 파일을 등록한다.
  5. <environment>의 하위태그
    <transactionManager type="...">
    : type속성에 JDBC와 MANAGED 둘 중 하나를 선택한다.
    - JDBC : 트랜잭션 처리를 성공여부 판단 후 수동으로 처리하겠다는 설정
    - MANAGED : 트랜잭션에 대해 어떠한 영향력도 행사하지 않겠다는 설정(자동 commit)
    <dataSource type="...">
    : type속성에 POOLED와 UNPOOLED 둘 중 하나를 선택한다.
    이때, POOLED는 ConnectionPool 영역을 사용하겠다는 선언이며, 
    ConnectionPool은 한번 생성된 객체를 담아두고 재사용할 수 있게 한다.
    해당 태그 하위로 <property>태그를 작성하며 키밸류값으로 db연결할 정보를 입력한다.
    <mappers>
    : 실행할 sql문들을 기록해둔 mapper 파일들을 등록하는 영역이다.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-config.dtd"> 
<!-- 이 세줄은 공식홈에서 복사해온다. -->
<!-- 해당 요소에 적법한 문법으로 작성되어있는지 확인해주는 dtd 설정임. -->
<configuration>
    <!-- *settings : mybatis 구동시 선언할 설정들을 작성하는 영역 -->
    <settings>
        <!-- null인데이터가 DB로 들어가려고 하면 오류가 나기때문에 DB에서의 NULL로 인식하도록 태그추가 -->
        <setting name="jdbcTypeForNull" value="NULL" />
    </settings>	
    <!-- *typeAlias : VO(DTO라고도함) 클래스들의 풀클래스명 대신 부를 별칭 지정하는 영역  -->
    <typeAliases> <!-- alias = 별칭 -->
        <typeAlias type="com.br.mybatis.member.model.vo.Member" alias="Member" />
        ...
    </typeAliases>	
    <!-- *environment : mybatis에서 연동할 DB에 대한 정보를 기재 -->
    <environments default="development">
        <!-- environment 1개가 연결할 DB 1개를 지정한다. 테스트용과 실제가 다를 경우 여러개 등록하기도함. 때문에 아이디 필수 -->
        <!-- 바깥 태그의 default 속성으로 여러개의 아이디 중 연결할 DB 지정 -->
        <environment id="development">
            <!-- 
                *transactionManager 는 JDBC와 MANAGED 둘 중 하나 선택
                - JDBC : 트랜잭션 처리를 내가 직접 관리하겠다. (성공여부 판단 후 수동 commit)
                - MANAGED : 트랜잭션에 대해서 어떠한 영향도 행사하지 않겠다. (자동 commit)
            -->
            <transactionManager type="JDBC" />		
            <!-- 
                *dataSource는 POOLED와 UNPOOLED 둘 중 하나를 선택 (ConnectionPool 사용할건지 여부를 결정)
                >>ConnectionPool : Connection 객체를 담아둘 수 있는 영역
                                   한번 생성된 객체를 담아두고 재사용 할 수 있다.
            -->
            <dataSource type="POOLED">
                <!-- db 연결할 값들 입력. 이때 키값(name)은 정해져있음. -->
                <property name="driver" value="oracle.jdbc.driver.OracleDriver" /> <!-- ojdbc6 설치 되어있어야함. -->
                <property name="url" value="jdbc:oracle:thin:@localhost:1521:xe" />
                <property name="username" value="mybatis" />
                <property name="password" value="mybatis" />
            </dataSource>
        </environment>
    </environments>	
    <!-- *mapper : 실행할 sql문들을 기록해둔 mapper 파일들을 등록하는 영역 -->
    <mappers>
        <!-- 아직 비워둔다. -->
    </mappers>
</configuration>

 

 


필터와 템플릿

Filter클래스를 활용해서 서블릿에서 반복되는 코드를 줄이고,

템플릿을 통해서 Service단에서 반복되는 코드를 줄여본다.


Filter 클래스 만들기

  • url을 요청할때마다 서블릿 클래스에 공통적&우선적으로 실행해야하는 코드가 있을 때, 
    해당 코드를 필터에 정의를 해두고 필터를 거쳐서 가도록 할 수 있다.
    ex) 서블릿에서 데이터를 꺼내기 전 하는 인코딩처리는 필터에 정의해둘 수 다. 
        >> 실습해본다.
  • 생성방법 : 오른클릭 new - Filter 선택
    common패키지에 생성한다.
  • 구동원리(라이프사이클) 
    1) init() 으로 필터객체 생성
    2) doFilter 메소드의 안쪽 코드 실행 (코드 작성할 핵심위치)
    3) chain.doFilter(request, response); 실
       : 만약 다른 필터가 있다면 다른 필터를 실행시켜주며,
         마지막 필터일 경우 본격적으로 실행될 서블릿을 구동시켜준다.
  • doFilter() 작성하기 : 
    - 요청전송방식이 post인 경우에만 인코딩을 하도록 조건문을 작성한다.
    - 전달받는 인자 request의 자료형을 보면 ServletRequest임.(HttpServletRequest의 부모)
    >> 다운캐스팅 한 후 getMethod() >> 요청전송방식 반환된다 >> 조건문에 활용
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    // 요청전송방식이 post 또는 POST 일 경우 인코딩 작업을 하게끔
    if(((HttpServletRequest)request).getMethod().equalsIgnoreCase("post")) {
        request.setCharacterEncoding("UTF-8");
    }
    chain.doFilter(request, response);
}

 

 

Filter 클래스 등록하는 방법

  • 방법1) web.xml에 등록하는 방법
    >>원론적인 방법으로 서블릿 클래스도 원래는 해당 방법을 사용했으나 어노테이션 방식으로 대체되었다.
    >>필터클래스 등록 후, 어떤 url 요청 시 해당 필터클래스를 거쳐가게 할건지 등록하는 원리
    1. 우선 필터클래스의 어노테이션을 주석처리 한다.
    2. web.xml을 연 후 source탭으로 들어간다.
    3. filter태그 하위로 filter-name(컨텐츠부로 필터이름), filter-class(컨텐츠부로 클래스 풀네임) 태그를 작성한다.
    4. filter-mapping 태그 하위로 filter-name(3번에서 등록한 이름), url-pattern(실행할 url) 태그를 작성한다.
      이때, /*은 모든 url을 의미한다.(모든 url 요청시 해당 필터클래스가 발동된다)
  • 방법2) 어노테이션 방법
    >>상기 과정은 하단의 1줄로 대체할 수 있다.
    (Filter 클래스의 어노테이션으로 기재)
    @WebFilter(filterName="encodingFilter", urlPatterns="/*")
# web.xml 파일에 등록하는 방법
  <filter>
	 <filter-name>encodingFilter</filter-name>
	 <filter-class>com.br.mybatis.common.filter.EncodingFilter</filter-class>
  </filter>
  <filter-mapping>
  	 <filter-name>encodingFilter</filter-name>
  	 <url-pattern>/*</url-pattern>
  </filter-mapping>

 

 

템플릿 클래스 만들기

  • SqlSession 객체를 만드는 구문을 템플릿화 시켜서 Service단에서 활용할수 있게 해보자.
  • 기존 JDBCTemplate에서는 Connection객체생성, close메소드 오버로딩, commit/rollback 등 여러 메소드를 작성해야 했지만 mybatis에서는 SqlSession객체가 갖고있는 자체 메소드로 해결 가능하므로 해당 객체를 만드는 static 메소드만 만들어도 된다. 
  • Resources 클래스 : Mybatis에서 제공하는 클래스로 getResourceAsStream()메소드의 매개변수로 넣는 경로의 첫 '/'는 소스폴더로 만들었던 resources를 가리킨다.
    >> resources소스폴더를 만들어야 했던 이유!
  • import구문을 보면 ibatis 로 나와있는데, mybatis의 전신이 ibatis로
    아파치에서 구글로 팀이동이 되면서 mybatis로 바뀐 역사의 흔적을 확인해볼 수 있다. 
package com.br.mybatis.common.template;

import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class Template {
	
    public static SqlSession getSqlSession() {
        //기존에는 driver.properties를 읽어들이는 구문이 필요했지만,
        //SqlSession 객체를 생성할 때 mybatis-config.xml파일을 읽어들여서
        //해당 파일이 기재된 DB와 접속된 객체를 바로 만든다.
        SqlSession sqlSession = null;
        try {
            // 1) mybatis-config 파일을 읽어들이기 위한 입력용 스트림 객체 생성하기
            // Resources 클래스 : mybatis에서 제공하는 클래스, import 시 org.apache.ibatis.io.Resources
            // 메소드 내부로 파일을 선택하기 위한 일부 경로 작성하기 : 첫'/' = resources 소스폴더
            InputStream stream = Resources.getResourceAsStream("/config/mybatis-config.xml");
            //new SqlSessionFactoryBuilder().build(Input객체) >> SqlSessionFactory 객체 반환
            // .openSession() >> SqlSession 객체 반환
            //     매개변수로 true/false를 지정할 수 있는데 자동커밋 여부를 지정한다(안넣으면 기본이 false임)            
            sqlSession = new SqlSessionFactoryBuilder().build(stream).openSession(false);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return sqlSession;
    }
}

 

 


인터페이스 활용

구조를 설계하는 사람과 코드를 구현하는 사람이 분리되어 있다면,

Service단을 인터페이스로 설계하는것이 보다 편리할 수 있다.

코드를 짜는 사람은 해당 인터페이스를 구현하는 클래스를 작성하면 된다.


인터페이스로 Service 설계

  • 인터페이스 :
    모든 메소드가 추상메소드로 이루어진 클래스로 모든 메소드는 묵시적으로 public abstract이다.
    (때문에 생략가능하다)
    메소드는 머리부까지만 작성되어있기 때문에 몸통부는 구현하는 클래스에서 완성하게 된다.
  • 서비스측 클래스에 어떤 메소드가 필요한지 생각해보고 설계해보자.
    매개변수와 반환형을 예측을 해서 설계한다.
  • 이미 구현하는 클래스가 작성되었더라도 추가적으로 메소드를 추가할 수 있다.
    (구현클래스측에서 빨간줄이 뜨면서 메소드를 추가하도록 유도함)
public interface MemberService {
	//1. 회원가입서비스
	/*public abstract*/int insertMember(Member m);
	//2. 로그인서비스
	Member loginMember(Member m);
	//3. 회원정보수정서비스
	int updateMember(Member m);
	...
}

 

 

인터페이스 구현해서 Service완성하기

  • 구현하는 클래스의 이름을 지을때는 보통 인터페이스이름 뒤에 Impl을 붙인다.
    ex) MemberService 인터페이스를 구현하는 MemberServiceImpl 클래스
  • 일반 클래스를 만든 후에 클래스명 뒤로 implements MemberService를 입력하면 빨간줄이 뜸
    >> 클릭하면 오버라이드할 메소드들이 자동완성된다.

 

 

 

 

 

이미지 원본 출처 instagram @teaaalexis

댓글