1. MyBatis
1) 정의
객체 지향 언어인 자바의 관계형 데이터베이스 프로그래밍을 좀 더 쉽게 할 수 있게 도와 주는 개발 프레임 워크로서 JDBC를 통해 데이터베이스에 엑세스하는 작업을 캡슐화하고 일반 SQL 쿼리, 저장 프로 시저 및 고급 매핑을 지원하며 모든 JDBC 코드 및 매개 변수의 중복작업을 제거 한다. Mybatis에서는 프로그램에 있는 SQL쿼리들을 한 구성파일에 구성하여 프로그램 코드와 SQL을 분리할 수 있는 장점을 가지고 있으므로 분업에 용이하다.
Spring 구조까지 생각해본다면, JSP - Controller - Service - DAO - Mapper(Interface/xml)-DB 경로를 거친다고 할 수 있다. 참고로 DAO앞에 Service단이 존재하는 이유는 하나의 프로세스를 완성하기 위해 동일한 동작을 반복하는 DAO를 중복해서 사용하는 것을 방지하기 위함이다. 즉 프로세스를 이미 작성한 DAO 메서드들을 이용해서 완성시키는 곳이 바로 Service단이다. Service단 없이 DAO를 작성한다고 가정해보자. '게시물 하나를 등록한다'는 프로세스를 완성하기 위해서는 DAO를 작성한다면, '등록(insert)' > '이전에 작성한 목록보여주기(select)'를 작성하게 된다. 한편, '게시물 하나를 삭제한다'는 프로세스를 완성하기 위해서 DAO를 작성한다면, '삭제(delete)' > '이전에 작성한 목록보여주 (select)'를 작성하게 된다. 즉 하나의 DAO에서 '이전에 작성한 목록보여주기(select)'가 중복된다. 이러한 프로세스가 여러개가 있다면 DAO에 중복된 코드가 너무 많게 되고 수정도 힘들게 된다. 그러므로 한번 작성한 DAO를 서비스단에서 필요에 따라 메소드들을 조합하여 하나의 프로세스가 작동하도록 만드는 곳이 Service단이다.
2) 장점
- 복잡한 쿼리나 다이나믹한 쿼리에 강하다 - 반대로 비슷한 쿼리는 남발하게 되는 단점이 있다.
- 프로그램 코드와 SQL 쿼리의 분리로 코드의 간결성 및 유지보수성 향상
- resultType, resultClass등 Vo를 사용하지 않고 조회결과를 사용자 정의 DTO, MAP 등으로 맵핑하여 사용 할 수 있다.
- 빠른 개발이 가능하여 생산성이 향상된다.
2. MyBatis 설정
1) pom.xml에 ojdbc.jar 레퍼런스 주소 삽입
ojdbc는 저작권 문제로 인해 jar파일을 바로 maven에서 설치할 수 없고, 레퍼런스 주소 부터 설정해줘야한다. 아래의 코드 삽입 후 다른 dependency를 추가하기 전에 한 번 저장한다.
2) 동일한 pom.xml의 dependencies 태그의 시작태그와 종료 태그 사이에 mabatis, mybatis-spring, ojdbc6, spring-jdbc의 dependency 추가 한 후 프로젝트가 제대로 동작하는지 확인한다.
프로젝트에 빨간색 'x'나 '!' 표시가 있다면 그것은 maven에서 파일을 정상적으로 다운받지 못 했다는 의미이다. 이 문제를 해결 할 수 있는 방법 중 하나는 C:\Users\설정한User이름\.m2\repository 을 찾은 후 그 아래의 repository 파일을 삭제한 후 문제없이 작동하는 사람의 .m2파일의 repository를 붙여넣기 한 다음, Spring을 종료 후 다시 시작하고 프로젝트 명 오른 쪽 마우스 클릭 > Maven > Update Project > 해당 프로젝트를 선택 한 후 > OK버튼
3).root-context.xml에 다음 문구 삽입
Spring의 Beans 형태로 xml을 작성하면 얻는 이점은 객체간의 의존성을 감소시켜주고, 능률적으로 유지 보수 할 수 있다는 점이다. 만약 작성 후 class에 빨간줄이 생긴다면, 앞과 동일한 방법으로 .m2을 손보면 된다.
4) 3번의 src/main/resources 아래 mapper.xml 파일과 db.properties, mybatis-config.xml파일 넣기
db.properties는 본인의 DB에 맞게 작성해줘야한다. 여기서는 oracle DB의 hr계정을 사용하고 있다. 또한 META-INF파일 아래에 삽입하는 것이 아니라는 점도 유의!
위의 파일 중 mabatis-config.xml의 코드는 이렇게 구성 되어 있다.
Mapper은 두 가지로 구성되어 있다. 하나는 Interface이고, 다른 하나는 xml이다. Interface를 통해 정의되어야할 메소드의 틀을 만들어 주고, xml에서 실제 로직을 구성한다. 그러한 xml을 등록하는 곳이 mabatis-config.xml파일이다. <mappers>태그를 통해 작성한다. 등록할 mapper.xml 파일이 없다면 작성 안 해줘도 무방하다. 그리고 typeAliases태그는 VO의 경로가 너무 길어 작성을 편리하게 하기 위해 별칭으로 등록할 때 작성하는 곳인데 별칭을 따로 작성을 하지 않아고 경로를 작성해주어도 서버 작동에는 큰 문제가 없다. 다만, 작성한 후 서버에서 잘 동작하지 않는다면 mabatis-config.xml에서의 작성 실수가 원인인 경우가 많다. 그러므로 작성에 주의하도록 하자.
다음으로 mapper.xml을 살펴보자. 앞서 말했듯, xml은 로직을 구성하는 곳이다. 여기서는 DAO에 대한 Mapper이기 때문에 DB에 대한 SQL문 로직을 작성할 수있다. 여기에 SQL문을 작성하면 JDBC처럼 동작한다. 그러나 다른 점이 있다면 EL과 달리 #{} 형태로 사용한다는 점(EL은 ${}이다.), 세미콜론(;)을 작성하면 동작하지 않는 다는 점이다. xml의 경우 문법 오류를 검출해주지 않기 때문에 작성시 항상 유의해야 한다.
<insert> 태그가 작성되어 있는데, 매핑할 SQL문에 따라 태그를 바꿔서 작성하면 된다. SELECT라면 <select></select>, DELETE라면 <delete></delete>, UPDATE라면 <update></update> 이런식으로 작성하면 된다. 참고로 insert의 경우 입력 받은 값을 받아 데이터에 저장하므로 parameterType이라는 속성을 사용하고 select의 경우 데이터를 조회해서 가져오기 때문에 resultType이라는 속성을 사용한다. 추가로 예를 들어 select의 태그의 속성으로 resultType="String"을 쓴다고 해서 딱 하나의 데이터만 가져온 것이 아니라 조건에 맞는 데이터를 list형태로 자동으로 가져 오게 된다. 조금 더 자세한 설명은 아래의 링크를 참조하길 바란다.
https://mybatis.org/mybatis-3/ko/sqlmap-xml.html
<mapper>태그의 속성 중 "namespace"는 이 xml 파일이 어떤 것이 몸체인지, 몸체의 경로를 작성해주기 위한 용도이다. 즉, 인터페이스 바인딩을 위한 것이다.
SQL문의 태그의 id 속성은 구문을 찾기 위해 사용될 수 있는 네임스페이스내 유일한 구분자이며, 인터페이스의 메서드 이름을 작성한다. parameterType 속성에는 구문에 전달될 파라미터의 패키지 경로를 포함한 전체 클래스명이나 별칭을 작성한다. 이 역시 인터페이스의 메서드를 참고로 작성하는데 그 메서드가 VO를 파라미터로 받았다면, 그 VO의 경로를 작성해주면 되고, 메소드가 String 타입으로 파라미터를 받았다면 String이라고 작성해주면 된다. 그 외의 다양한 속성의 설명 및 자세한 내용을 바로 위의 링크를 통해서 확인할 수 있다.
3. Mabatis 테스트(Service로직은 제외한 상태에서의 간단한 테스트)
1) Oracle DB의 hr 계정에 테이블 생성
간단한 예시를 위한 작성이므로 sqlplus나 sqldeveloper을 이용해 테이블 생성
2) dao mapper 인터페이스 작성
작성시 package명에 유의해한다. Project를 Settings했을 때 작성했던 topLevelPackage를 기본적으로 작성해주고 뒤에 추가 작성해야한다.
앞서 말했듯, 동일하게 xml에는 method이름, method의 파라미터 타입으로 작성해준다. 또한 namespace는 mapper인터페이스가 있는 경로를 작성해준다. 참고로 tip이 있다면, 경로가 잘 맵핑됐는지 확인하려면 컨트롤 키를 누른 채로 경로를 클릭했을 때 맵핑하고자하는 곳으로 이동하면 잘 맵핑된 것이다. 주의할 점은 경로를 작성할 때 슬래쉬(/)가 아닌 점(.)으로 작성한다는 것이다. 또한 sql구문에서는 대소문자를 구분하지 않지만, 파라미터를 받는 변수(#{})는 대소문자를 구분하므로 주의해서 작성해야한다.
인터페이스와 xml을 잘 작성했다면, 프레임워크에서 인터페이스와 xml을 바탕으로 JDBC문구를 자동으로 작성해 줄 것이다.
3) mybatis-config.xml에 mapper.xml 등록
mybatis-config.xml파일 중 <mappers>태그 사이에 <mapper resouce>를 작성해주고, 컨트롤을 누른 채 클릭하면 mapper.xml로 잘 이동된다면 무사히 등록된 것이다. 참고로 <tyepAliases>태그는 VO 경로가 너무 길어 질 때, 보다 간략하게 경로를 작성하기 위한 별칭을 작성하는 곳으로 생각하면 된다. type속성에는 VO의 경로를 작성해주고, alias속성에는 지정할 별칭을 사용하면 된다. 등록한 별칭은 위의 mapper.xml파일에서 ParameterType, resultType 등에 VO경로 대신 사용할 수 있다. 즉, 별칭을 위한 <tyepAliases>태그는 반드시 작성할 필요는 없다.
4) 데이터를 삽입하는 역할을 해줄 DAO 생성(insertDAO.java 파일)
@Repository 어노테이션 ▶ Bean을 사용하기 위해서 또한 내가 만든 객체를 Bean으로 만들기 위해서는 컴포넌트로 인정을 받아야한다. @Component 어노테이션도 사용가능하나, 로그관리, 트랜잭션 관리 등을 이유로 DAO를 위한 어노테이션으로 @Repository 어노테이션를 많이 사용한다 .
@Autowired 어노테이션 ▶ Bean으로 작성된 객체를 컨테이너가 삽입해주는 어노테이션으로 Bean뿐 아니라 컴포넌트로 인정받은 것들도 이 어노테이션을 통해서 삽입가능하다. 이 어노테이션으로 인해 new를 이용해 메모리를 새로 할당받아 생성할 필요 없으므로 메모리 낭비를 방지할 수 있다. SqlSession객체는 MyBatis의 객체 중 하나로 앞서 우리가 root-context.xml에 설정해 준 하나의 Bean 이다.
Bean을 만드는 방법은 https://nkcnow.tistory.com/229 링크를 참조.
그 외에 spring에서 사용되는 어노테이션이 궁금하다면 아래의 링크를 참조.
https://gmlwjd9405.github.io/2018/12/02/spring-annotation-types.html
여기서의 메소드 명은 앞서 작성했던 mapper 인터페이스와 xml의 작성법과 같이 반드시 동일하게 작성할 필요는 없다. 메소드 작성 후 session을 통해서 mapper을 가져오는데, getMapper메소드의 파라미터로 '인터페이스명.class'로 작성한다. 그럼 인터페이스를 객체로 사용할 수 있다.즉 인터페이스를 객체화시켜서 사용할 수 있다.
5) DAO를 바탕으로 Controller 작성
앞서 설명했듯, new 사용없이 dao를 사용하기 위해서 @Autowired 어노테이션을 작성하였다. (DAO는 @Repository어노테이션으로 인해 bean화 되었으므로, root-context.xml에 bean태그를 이용해 작성하지 않았어도 @Autowired 어노테이션을 통해 new 사용없이 사용가능하다.)
6) home.jsp 작성
간단하게 EL로 결과 프린트해보기
'■ 용어 정리' 카테고리의 다른 글
[용어정리] JavaScript - 조건, 반복, 문자열 (0) | 2020.04.28 |
---|---|
[용어정리] JavaScript - 변수, 연산자, 타입 (0) | 2020.04.28 |
[용어정리] Spring - 파일 구조, 동작 원리 (0) | 2020.04.28 |
[용어정리] GET, POST, forward, redirect (0) | 2020.04.28 |
[용어정리] JSP(Java Server Page) - 페이지의 구성 요소 (0) | 2020.04.28 |