[JSP] MyBatis

oungoo·2020년 12월 21일
0

JSP

목록 보기
3/3
post-thumbnail

20.12.21~24 주제

Mybatis
hibernate validator
EL
custom Tag


회원관리_JDBC

MemberListController
MemberDAOImpl_JDBC.java
개발전에 다이어그램을 먼저 그려보세요

페이징

주요 데이터 요소

  • totalRecord : 총 게시물 수
    • 테이블에서 총 카운트 가져옴
    • ex. 100개
  • screenSize : 한 페이지당 리스트 수
    • 임의의 값. 개발자/디자이너가 결정
    • ex. 10개
  • totalPage : 총페이지 수
    • (totalRecord+(screenSize-1))/screenSize
    • ex. (100+(10-1))/10 = 10
  • currentPage : 현재 페이지
    • 클라이언트가 결정. 없으면 1로 셋팅
    • ex. 8번
  • endRow : 한 페이지에서 종료 게시물
    • screenSize * currentPage
    • ex. 10 * 8 = 80
  • startRow : 한 페이지에서 시작 게시물
    • endRow - (screenSize - 1)
    • 80 - (10-1) = 71
  • blockSize : 한 화면에 보여줄 페이지 수
    • 임의의 값. 개발자/디자이너가 결정.
    • ex. 5개 페이지/1블럭
  • startPage : 한 블럭의 시작페이지
    • ((currentPage - 1) / blockSize) * blockSize
    • ex. ((8-1)/5) * 5 = 6
  • endPage : 한 블럭의 마지막페이지
    • startPage + (blockSize -1)
    • ex. 6 + (5-1) = 10

totalRecord

  • 아래 쿼리는 망한 쿼리
  • 왜 ?
    • rownum은 의사컬럼 : 실시간으로 동적으로 만들어지는 컬럼. 쿼리 실행순서(from-where-select)에 의해 데이터 조회되지 않음 (아직 만들어지지 않은 데이터를 사용하는 격)

  • 의사컬럼을 미리 존재하는 컬럼으로 만들어서 조회
    • 정렬을 위해 한번 더 인라인 뷰 사용함
    • 쿼리 실행 순서 : 7-6-8-5-4-2-11-12-1
      • FROM - WHERE - GROUP BY - HAVING - SELECT - ORDER BY
      • SELECT 보다 늦게 실행되는 것은 ORDER BY 뿐 !
      • SELECT 절의 Alias 는 ORDER BY 절에서만 사용가능.
      • https://data-make.tistory.com/23

myBatis

  • Persistance 레이어와 DB사이에서 동작하는 프렘임웍.
  • SQL mapper = ORM = DM 이라고 부르기도 함
    • 이름의 의미를 생각해보면 어떤 역할을 하는지 알 수 있음.

                 DataMapper               |               SQL Mapper               |               DataMapper              
  • JDBC 드라이버 로딩부터 클로즈까지 6단계 과정이 똑같이 이루어지는데, 직접하지 않고 프레임웍이 해줌
  • IoC / DI 패턴 : 제어 반전, 역제어. 프로그래머가 작성한 프로그램이 재사용 라이브러리의 흐름 제어를 받게 되는 소프트웨어 디자인 패턴(의존관계 역전패턴)
    • 프레임웍과 라이브러리를 구별하는 핵심키워드

회원관리_myBatis

  • https://mybatis.org/mybatis-3/ko/getting-started.html

myBatis는

    1. iBatis가 버전업된 것
    • 클래스패스 리소스 형태로 클래스로드를 통해 접근
    1. iBatis나 myBatis나 내부적으로는 jdbc 프로그래밍.

jdbc 프로그래밍 6단계

    1. 드라이버로딩
    1. connection 생성
    1. query 객체 생성
    1. query 실행
    1. ResultSet 활용
    1. close

시작하기

maven dependency 추가

<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>x.x.x</version>
</dependency>

Configuration.xml

  • xml로 만들기 -> DTD 파일
  • Configuration.xml
<!-- 경우에 따라서 DB를 여러개 사용할 수도 있음. environment's'인 이유 -->
<environments default="dev">
	<environment id="dev">
		<!-- transactionManager : 오토커밋 담당 -->
		<transactionManager type="JDBC" />
		<!-- POOLED : 내부적으로 커넥션 풀링이 이루어짐 -->
		<dataSource type="POOLED">
			<property name="driver" value="${driverClassName}"/>
			<property name="url" value="${url}"/>
			<property name="username" value="${user}"/>
			<property name="password" value="${password}"/>
		</dataSource>
	</environment>
</environments>
  • environments : 여러개의 environment를 가질 수 있음
  • environment : 트랜잭션 관리와 커넥션 풀링을 위한 환경설정
    • POOLED : DB 커넥션 풀링

    커넥션풀 ?

    • 데이터베이스와 연결된 커넥션을 미리 만들어서 풀(pool) 속에 저장해 두고 있다가 필요할 때에 커넥션을 풀에서 가져다 쓰고 다시 풀에 반환하는 기법
    • 특징
      • 풀 속에 미리 커넥션이 생성되어 있기 때문에 커넥션을 생성하는데 드는 연결 시간이 소비되지 않음
      • 커넥션을 계속 재사용하기 때문에 생성되는 커넥션 수가 많지 않음
  • mappers : SQL 코드와 매핑 정의를 가지는 mapper.xml 파일 목록 지정

SqlSessionFactory 빌드하기

  • 데이터베이스에서 session은 통로의 의미
    • iBatis : sqlMapClient
    • myBatis : sqlSession
  • Configuration.xml 파일을 이용한 SqlSessionFactory build
  • mapper.xml 파일은 configuration.xml에 따라옴
-- Class CustomSqlSessionFactoryBuilder--
(싱글톤으로 SqlSessionFactory 빌드)

private static SqlSessionFactory sqlSessionFactory;

static{
	String resource = "configuration.xml 의 qualified name"
    try(
    	Reader reader = Resource.getResourceAsReader(resource);
    ){
    	sqlSessionFactory = new SqlSessionFactoryBuilder().builde(reader);
    }catch(IOException e){
    	// 실시간으로 처리할 수 없는 예외
        // unchk 예외로 바꿔서 서버에 전달
    	throw new RuntimeException(e);
    }
}

public static SqlSessionFactory getSqlSessionFactory(){
	return sqlSessionFactory;
}

-- Class DAOImpl--
private SqlSessionFactory sqlsessionFactory = CustomSqlSessionFactoryBuilder.getSqlSessionFactory();

mapper.xml

  • 전자정부 이클립스에는 이미 myBatis 플러그인이 있음
  • 매핑파일 만들때 사용
  • myBatis는 namespace 필수 ! (ibatis와 차이)
    • namespace 없으면 마이바티스 구조완성이 안됨
    • namespace 로 DAO의 qualified name을 가짐
      • 마이바티스 내부에서 리플렉션 작업 이루어짐
      • DAO의 인터페이스가 어떤 메소드를 가지고 있는지 알게됨.
      • 메소드 : 쿼리 = 1 : 1
    • 후에 매퍼프록시가 만들어져야 하는데, namespace가 이상하면 못만듦.
      • 프록시가 만들어지지 않으면 myBatis는 못쓴다고 봐도 ..
  • myBatis는 typeAlias를 mapper.xml에 만들 수 없음.
    • 모든 xml 에서 사용하기 위해 configuration.xml에 만듦
<typeAliases>
  <package name="패키지">
  <typeAlias name="클래스">
</typeAliases>  
  • 자기 클래스 이름으로 알리아스 잡힘
    • 그래서 qualified name 사용 (아마두?!)
  • 쿼리
    • 크게 select 계열과 update 계열로 나뮈
      • 그래서 < delete > 태그 안에서 update 쿼리 사용할 수 있음
    • 인라인파라미터
      • iBatis : #인라인파라미터#
      • 마이바티스 #{인라인파라미터}
  • Null 값
    • iBatis에서는 null↔"" 서로 변환되어 들어가는데 myBatis는 안됨 => NULL 처리 필요
    • Null을 어떤 타입에 맞춰서 넣을 건지 결정
      • jdbcType의 enum 사용

DAOImpl

  • 옛날방식
    • sqlSession.selectOne("DAO의 qualified name.method", parameter)
    • = queryForObject... insert, update, delete ...
    • 오타때문에 타입안정성이 없음
  • 요즘방식 : Mapper Proxy
    • sqlSession.getMapper(IMemberDAO.class);
      • 위 인터페이스의 퀄러파이드네임에 해당하는 네임스페이스를 찾음

Mapper (쿼리)

OGNL 표기법

  • Object Graph Navigation Language
    • https://commons.apache.org/proper/commons-ognl/language-guide.html
    • 교재, 부교재vhfej, myBatis.org 레퍼런스 참고
  • 일종의 표현언어
  • 내부적으로 스크립트언어 형태
    • 객체에 접근할 때 연산배열로 접근할 수 있음
  • MyBatis 는 XML element를 줄이고 다양한 조건을 처리하기 위해 OGNL 표현식을 사용
    • 동적SQL 처리를 지원하기 위해 지정된 엘리먼트들 제공함
    • if, choose(when, otherwise), trim(where, set), foreach ...
  • static method 호출 방법 : @class@method(argd)
    • ex. StringUtils의 isNotBlank 사용하기
    • @org.apache.commons.lang3.StringUtils@isNotBlank(searchVO.searchWord))
  • iBatis의 다이나믹 엘리먼트 대신 myBatis에서는 OGNL을 다양하게 활용

< ![CDATA][] >

  • 태그 안에서 < 가 일반 문자로 인식되게 함

마이페이지

  • 요구사항 변경 ! 우리 클라이언트는 마이페이지에서 구매한 상품 목록이 보고 싶어짐
  • 기존 VO를 활용해서 2개 이상의 테이블을 조인했을 때 어떻게 가져올까 ?

selectMember

  • 1.도메인 레이어를 각각 따로 만들기
    • ProdVO, memberVO
  • 2.모델링
    • 데이터들의 관계 파악 : has a(1:1), has many(1:n)
      • ex. member와 prod는 1:n 관계 : member has many prod
        ex. prod와 buyer는 1:1 관계 : prod has a buyer
    • VO와 VO 사이에 반영해주기
      • MemberVO 에 포함된 ProdList
      • ProdVO에 포함된 BuyerVO
    1. resultType을 이용한 자동바인딩이 불가해짐 -> 수동바인딩 : resultMap
    • 수동으로 하던 자동으로 하던 반환타입은 memberVO여야됨.
    • autoMapping = true : 규칙성에 따라 자동바인딩
    • 식별성 여부에 따라
      • id : 식별성이 있는 녀석 바인딩. mem_id가 같으면 더 이상 memberVO를 만들지 않음

        → 반환값은 memberVO 인데 중복제거 되지 않은 상태라 '너무많은데이터' 에러가 뜬 것
      • result : 식별성이 없는 녀석 바인딩할 때 사용
    • 1:1, 1:n 관계의 바인딩구조가 다름
      • collection : has many
      • association : has a

미션

  • 중프 소스를 오늘 배운 것으로 바꿔보기 ..

0개의 댓글