프로그래밍/JSP

JSP 6일차 - DBCP, JNDI,Mybatis

윤도ri 2022. 1. 27. 00:07

 우리는 지금까지 DB와 자바를 연결하기 위해서 DBConnection을 이용했다. 그런데 여기서 우리는 불편한 점을 느낀다. DBConnection의 경우에는 지었다 부셨다 지었다 부셨다를 반복해야하기 때문이다. 또한 쓸 때마다 마지막에 꼭 클로즈를 해야 한다. 쓰고 반납을 해야 다른 접속자가 쓸 수 있기 때문이다. 그러나 이 과정이 매우 불편하다. 게다가 동시접속자들이 많아지게 되면 그 접속자들의 접속을 보장할 수 없다. 이 불편함 때문에 나온 것이 DBCP이다. 이것은 다리 짓는 과정을 대신하여 지어진 다리를 그대로 갖다 쓰는 기법이다. 더 자세히 알아보자.

 

> DBCP(DataBase Connection Pool)

- 데이터베이스에 대한 연결들이 마치 수영장처럼 모여서 떠있는 곳이라는 의미이다.

- 사용자의 요청이 있을 때마다 DB 연결을 한다면 코드가 복잡해지며 많은 요청이 있을 때 연결 속도가 저하될 수 있다. 따라서 미리 Connection을 만들어 두고 필요시 저장된 공간에서 가져다 쓰고 반납하는 기법이다.

 요약하자면 연결을 여러개 만들어놓고 가져다 쓰는 건데 자동으로 반납까지 해주는 기법이다. 

ex) 20개의 다리를 쓰겠다 라고 정해두면 20명의 동시접속자가 있는 경우 그 사람들의 접속을 보장할 수 있다. 

 

 DBCP는 한 가지 기술을 사용하는데 그것이 JNDI이다.

 

> JNDI(Java Naming and Directory Interface)

- 디렉터리 서비스에서 제공하는 데이터 및 객체를 발견하고 참고하기 위한 자바 API이며 외부에 있는 객체를 가져오기 위한 기술이다.

(지금까지는 객체를 만들기 위해 클래스 만들고 생성자를 통해야 했다. 그런데 자바 안에서만 객체를 만드는 것이 아니다. 외부에서 객체(메모리)를 만들어낼 수 있고 자바 내부에서 쓸 수 있다. 왜냐하면 주 솟값만 알면 자바 내부로 들어올 수 있기 때문이다.)

- 외부 객체에 이름을 지어준다. 그리고 자바 내부에서 타입만 알면 주소 값을 받아왔으므로 가져올 수 있다.

- 말 그대로 이름으로서 다른 디렉터리에 있는 객체를 가져오는 방법이다.
: 그 외부 객체는 web.xml에 만들어 둔다.

 

 지금까지 배운 것은 기본적인 이론을 배웠다. 이제부터 우리는 실제로 우리가 많이 사용하는 DBCP를 응용하는 MyBatis라는 프레임워크를 배우게 될 것이다. 

 

> MyBatis

 우리는 지금까지 db에서 정보를 가지고 올 때 테이블에 있는 정보를 객체로 가져오는 것이 아니라 하나하나 꺼내왔다. 

그 이후 UserDTO를 이용하여 객체를 직접 생성해 주었다. 그래서 자바 내부에서 돌아다니는 객체(모델)와 데이터베이스 간의 좁힐 수 없는 간격이 있었다. 그 괴리감을 없애주고 자연스럽게 소통할 수 있도록 만들어주는 것이 MyBatis이다.

 또한 자바 소스코드 안에 SQL문을 작성 시 코드가 길어지고 유지보수 및 분업이 어려워진다. 특히 자바 개발자들에겐 더더욱이나 불편함을 느낄 것이다. 그래서 Mybatis는 코드를 분업화시켜서 작업효율과 가독성을 좋게 만들어 준다. 

 정리하자면 아래와 같다.

1. Mybatis는 모델과 DB의 매개체이다. 
2. Mybatis는 기존 JDBC 방식과는 달리 SQL문을 XML 파일에 작성함으로써 코드가 줄어들고 SQL문 수정이 편해진다. 또한 DBCP를 사용하여 커넥션을 여러 개 생성하기 때문에 JDBC만 사용하는 것보다 작업 효율과 가독성이 좋아진다. 

 

<iBatis와 MyBatis>
- iBatis는 2.5 버전이며 JDK 1.4 버전 이상 
- MyBatis는 3.0 버전이며 JDK 1.5 버전 이상에서 지원한다. 
- iBatis와 MyBatis의 차이점은 몇 개의 문법 및 사용 용어(명칭, 단어) 변경 등이다. 

 

직접 객체도 가져오고 db연결도 해줄 수 있고 sql문도 따로 적어주어 효율성을 높인다. 

 

> MyBatis 설치 
https://blog.mybatis.org/p/products.html > MyBatis3 Download > mybatis-3.5.8.zip 클릭

 

MyBatis를 사용하기 전에 먼저 물건을 만드는 공정에 대해 생각해보자. 예를 들어 생수병을 만든다고 생각했을 때 첫 번째로 필요한 것이 무엇일까? 일단 먼저 생수병을 찍어내는 공장이 필요하다. 또한 그 공장을 지을 때 어떤 물건을 만들지 알고 지어야 한다. 즉 그 공장에 대한 특징들이 설계도에 있을 것이다. 그다음엔 공장을 지을 인력들이 필요하다. 

이때 설계도를 읽고 해석해주는 관리자가 필요하고 건축사와 함께 합심하여 공장을 지어내게 될 것이다. 그럼 공장이 지어지고 설계도에 맞게 생수병을 만들어줄 것이다. 

 정리해보자면 1. 설계도 준비, 완성 2. 관리자의 설계도 읽기 3. 건축사와 합심 4. 생수병 생성 이런 과정이 될 것이다. 

 

이걸 MyBatis에 대입해보자면 설계도는 configuration(환경설정)이며 관리자는 reader , 건축사 sqlSessionFactoryBuilder,  생수병은 sqlsession이라고 볼 수 있다.

이제 직접 myBatis를 사용해보자. mybatis를 사용할 때는 mysql.jar build-path 했던 것처럼 똑같이 라이브러리와 WebContent> WEB-INF> lib에 넣어준다. 그래야 이 프레임워크를 사용할 수 있다. 

 

1.DBCP 기법을 이용하여 DB와 연결해준다. (설계도 만들기)

 

1) 패키지로 com.koreait.mybatis를 만든다. 

2) config.xml 파일을 만든다. 

3) config.xml 파일 안에 정해진 코드를 써주면 된다. (mybatis.pdf 파일을 참고하면 된다.)

 

<! DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>     //JDBC 타입이다.
<dataSource type="POOLED">         //DBCP를 사용하겠다는 뜻.(그래서 Mybatis 쓰면 DBCP코드도 함께 작성된다.)
<property name="driver" value="${driver}"/>  //${ a } : a 값을 써줘   
<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>

 

2. config 파일을 읽어와서 factory 생성하기 (설계도 읽어서 공장 짓기)

1) SqlMapConfig.java 파일을 생성한다. 

2) sqlSessionFactoy 타입의 getFactory 메서드를 만든다. 

3) 싱글톤 패턴 사용하여 factory 만들기

*싱글톤 패턴이란?

 생성자가 여러 차례 호출되더라도 실제로 생성되는 객체는 하나이고 최초 생성 이후에 호출된 생성자는 최초의 생성자가 생성한 객체를 리턴한다. 이와 같은 디자인 유형을 싱글턴 패턴이라고 한다.

 

4) 그대로 getFactory메서드에 넣는다. 

 

 여기서 우리는 의문이 있다. dbconnection 할 때 우리는 connection이 null값인지 확인 후 (다리 지어져 있니? 아니구나!) 지어줬다. 그렇다면 factory 또한 null값인지 매번 확인하며 만들어야 하는가? DBCP의 경우 사용 후 반납도 알아서 해주기 때문에 따로 null값인지 확인하지 않아도 된다. 또한 싱글톤으로 만들게 되면 프로그램이 시작되었을 때 객체를 만들어놓을 것이고 굳이 검사할 필요 없이 그대로 쓰면 된다.

 추가적으로 factory는 설계도를 읽고 지어주는 과정이 있어야 factory가 만들어진다. 그러므로 프로그램이 시작되었을때 그 과정 또한 한번만 시행되어야한다. 이때 우리는 static block을 사용하면 된다.

 (프로그램이 실행되면 클래스를 로딩하면서 가장 먼저 static이 붙여있는 것을 가장 먼저 메모리에 올린다. 즉 static이 올라가는 시기가 프로그램이 시작될 때이다. 그래서 static이라는 블록을 사용할 것이다.) 

 *static block이란? 

- 클래스 초기화 블록이다.

- 클래스가 처음 로딩될 때 한 번만 수행된다. 

 

5) static 블록 안에 config(설계도)를 읽어오는 코드를 작성해준다.

3. 가져온 factory 사용하여 sqlsession 만든다(공장을 만들었으므로 그곳에서 생수병 찍어내기) 

1) com.koreait.test 패키지 생성하기

2) 안에 MybatisTest.java 파일 생성하기 

3) 생성자 이용하여 객체 만들 때마다 sqlsession 만들도록 하기 

 sqlsession = SqlMapConfig.getFactory(). openSession();

4) 시간 읽어오는 메서드 생성하기

5) 메서드 안의 리턴 값에 구별자 id를 적어준다. 

 - sql 이용하여 시간을 읽어와야 하므로 sql문을 써주어야 한다. 그러나 우리가 앞서 말한 것처럼 sql문은 xml파일에 적어준다. 그러므로 이곳에는 이 쿼리문을 읽어주기 위한 구별자 id가 필요하다. 

4.mapper 만들기 : sql문을 xml파일에 적어준다. 

*자바에서 쿼리문을 찾는다 하면 어떤 쿼리문을 원하는지 id를 적어주어 찾아서 연결해주므로 mapper라고 부른다

1) com.koreait.mapper 패키지 생성하기

2) test.xml 파일 생성하기

3) test.xml 파일 안에 정해진 코드를 써주면 된다. (mybatis.pdf 파일을 참고하면 된다.)

 

<! DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.mybatis.example.BlogMapper">
<select id="selectBlog" resultType="Blog">   //select 명령문 쓸 것이다
select * from Blog where id = #{id}             //sql쿼리문 적기
</select>
</mapper>

 

<규칙>

1.mapper의 namespace는 대문자로 적는다.

2.id와 namespace 모두 적어준다.

5. 메인인 JSP파일에 객체 불러와서 시간 불러오는 메서드 사용하기

1) 객체 생성

2) 메서드 호출

 

BUT... 여기서 오류가 생긴다.. 왜일까? sqlsession은 test mapper의 위치를 모른다. 그러므로 위치를 알려주어야 한다.

이때 sqlsession은 factory에서 만들어지므로 factory를 만들어내는 설계도에 위치를 알려주면 된다. 

6.Config파일에 mapper코드 안에 mapper위치 알려주기.

 

그럼 이제 시간이 잘 출력되는 것을 볼 수 있다. 결과 페이지는 생략하겠다. 이렇게 오늘은 mybatis 프레임워크를 이용하여 DB를 연결하고(DBCP) DB의 외부 객체를 데려와서(JNDI) 메서드를 만들고 화면에 구현하는 것을 하였다. 각각 기능에 따라 분업화를 시키니 훨씬 코드가 간결해져서 유지보수가 쉬워지는 것 같다. 아래에 이 과정을 간단하게 정리해보았다.

 

'프로그래밍 > JSP' 카테고리의 다른 글

JSP 팀 프로젝트 끝, 느낀점  (0) 2022.04.19
JSP 7일차 - EL문과 JSTL  (0) 2022.02.05
JSP 5일차 - Session, Ajax  (0) 2022.01.24
JSP 4일차 - 내장객체, 쿠키  (0) 2022.01.21
JSP 3일차 - 액션태그  (0) 2022.01.20