본문 바로가기

오픈소스/스프링

[Spring] JNDI 설정법 및 테스트

 JNDI를 통해 Spring에서 데이터베이스의 연결을 외부 리소스인 톰캣으로 바인딩 시키는 방법에 대해 설명하도록 하겠습니다. 

 JNDI 는 자바 네이밍 / 디렉토리 인터페이스인데 J2EE 의 가장 중요한 스펙 중 하나입니다. 

 

 JNDI 를 사용하는 이유는 시스템에 대해 배포후에 , 만약 데이터베이스 정보가 변경해야할 필요가 있을 경우 톰캣에 설정파일만 변경할 수 있습니다. 또한 쿼리문 조차 소스코드를 바꿀 필요없이 외부의 리소스가 존재하기 때문에 외부 리소스를 수정할 수 있어서 아주 편하고 유용한 라이브러리 입니다.

 

 또한 JNDI 를 이용하면 하나의 웹 어플리케이션에서 여러개의 데이터 베이스를 관리할 수 있고 그로 인해 이중화 작업이 가능한 편입니다. 데이터의 손상을 막게 해주는 이중화 작업을 지원함으로써 실무에서는 반드시 사용하고 있는 아주 필수적이고 실용적인 라이브러리 인데요. 이 라이브러리를 간단하게 적용시키는 방법에 대해 설명하고자 합니다.

 

 본 문서는 JNDI 설정법 및 테스트를 진행하기 위한 코드가 추가되었습니다.

 

 

# Contents


  • 톰캣 설정
  • 프로젝트 설정
  • 실행 방법

 

 

# 톰캣 설정


 먼저 톰캣에서 설정하는 방법부터 논하겠습니다. 톰캣에서는 리소스의 정보를 정의해주어야하기 때문에 천천히 따라하면서 설정해보도록 합시다.

 

 다음 코드를 server.xml 에 입력하시기 바랍니다. 

 

 

 

 server.xml을 열어주시고 아래로 내려가다 보시면 GlobalNamingResources 가 존재합니다.

 해당 부분 안에다가 Resource 를 넣어주시기 바랍니다.

 자신의 데이터베이스 정보에 맞게 넣어주시는건 필수! 결과값은 아래와 같습니다.

 

  <GlobalNamingResources>
  
	<Resource auth="Container" 
		driverClassName="oracle.jdbc.OracleDriver" 
		maxActive="20" 
		maxIdle="20" 
		maxWait="5000" 
		minIdle="2" 
		name="jdbc/JUNHO_DB" 
		password="root" 
		type="javax.sql.DataSource" 
		url="jdbc:oracle:thin:@localhost:1521:xe" 
		username="root" 
		validationQuery="select 1 from dual" 
		alidationQueryTimeout="30"/>
    <!-- Editable user database that can also be used by
         UserDatabaseRealm to authenticate users
    -->
    <Resource auth="Container" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase" pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase"/>
  </GlobalNamingResources>

 

 

 다음 코드를 context.xml 에 입력하시기 바랍니다.

 

 

 

 Context 안에다가 넣어주시면 되겠습니다.

 위에서 넣었던 네임을 가져오면 되겠습니다! 결과값은 아래와 같습니다.

 

<ResourceLink global="jdbc/JUNHO_DB" name="jdbc/JUNHO_DB" type="javax.sql.DataSource"/>

 

 

# 프로젝트 설정


 여기서는 톰켓에서 설정한 데이터베이스의 GlobalNamingResources를 이용하여 톰캣에서 설정한 데이터베이스의 정보를 가져오는 코드를 작성하겠습니다. 그리고 간단한 예시를 들어서 데이터베이스가 잘 연동이 되어있는지 확인하는 방법도 알려드리도록 하겠습니다.

 

 여기서 생성할 파일은 classPath 안에 query폴더를 생성할 것입니다. 또한 servlet-context에서 mybatis-context를 매핑해줘서 설정 파일을 분리할 예정입니다. 천천히 정확하게 따라와주시기 바랍니다.

 

 시작하겠습니다.

 


 다음 코드를 web.xml 에 추가해주시기 바랍니다.

 여기도 마찬가지로  위에서 넣었던 네임을 가져오면 되겠습니다! 결과는 아래와 같습니다.

 

	<resource-ref>
		<res-ref-name>jdbc/JUNHO_DB</res-ref-name> <!-- 이름을 정의해주세요. -->
		<res-type>javax.sql.DataSource</res-type>
		<res-auth>Container</res-auth>
	</resource-ref>

 


 

 다음 코드를 servlet-context.xml 에 추가하시기 바랍니다. 설정 파일의 분리를 위함입니다.

 클래스 경로에 config폴더 안에 mybatis-context.xml 로 설정파일을 정의할 것입니다.

 

<beans:import resource="classpath:/config/mybatis-context.xml" />

 


 

 다음 코드를 classpath:/config/mybatis-context.xml 에 입력하시기 바랍니다. 

 jndiName자신이 정의한 네이밍으로 설정해주시기 바랍니다.

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
	
    <tx:annotation-driven  proxy-target-class="true"/>
      
    <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName" value="jdbc/JUNHO_DB"/>
        <property name="resourceRef" value="true"/>
    </bean>
   
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
      <property name="dataSource" ref="dataSource" />
      <property name="mapperLocations" value="classpath:query/*.xml" />
    </bean>
    
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
      <constructor-arg index="0" ref="sqlSessionFactory" />
    </bean>

     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

</beans>

 


 

폴더를 하나 생성합니다. classpath:query 로 생성하게 되면 그 안에서 쿼리문을 작성할 수 있습니다.

설정은 이로써 완벽하게 끝났습니다. 서버를 진행하게 되면 오류를 찾으면서 해결하시기 바랍니다. 

설정만을 위하신 분은 여기까지이고, 간단한 테스트를 진행하시려면 아래와 같이 따라해주시기 바랍니다.

 

아래 문서는 오라클 데이터베이스와 JNDI 를 이용하여 간단한 테스트를 진행하고자 합니다.

 

 

# 실행 방법


 간단한 실행 방법을 진행하기 위해 우리는 데이터베이스 안에 테이블을 생성할 예정입니다.

 먼저 Member 테이블을 하나 생성해주시기 바랍니다. SQL 문은 아래와 같습니다.

 

CREATE TABLE MEMBER 
( 
    id             VARCHAR2(20),
    password       VARCHAR2(20)
);

 

 그리고 간단하게 테스트 진행을 위해 INSERT 문을 이용하여 테이블에 데이터를 하나 집어넣도록 하겠습니다.

 

INSERT INTO MEMBER VALUES("test", "1234");

 

 테이블이 생성되면, VO 객체를 하나 생성할 예정입니다. 

 vo 패키지를 생성하여 MemberVO.class 를 하나 생성하고, 그 안에 코드를 작성하겠습니다.

 

 

public class MemberVO {
	public String id;
	public String password;
	
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
}

 

 쿼리문도 만들어야 합니다. 쿼리문은 classpath 폴더 안에 query 폴더에서 작성하도록 설정하였습니다.

 여기 폴더 안에서 member.xml을 생성하여 아래 간단한 SQL문을 작성하고 저장하세요.

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
	PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
	"http://mybatis.rog/dtd/mybatis-3-mapper.dtd">
<mapper namespace="member">

	<select id="selectMember" resultType="com.mycom.myapp.vo.MemberVO">
		SELECT *
		FROM MEMBER
	</select>
	
</mapper>

 

 


 MVC 패턴 구성으로 설정하도록 하겠습니다. 간단하지만 실무에서 적용이 바로 가능한 코드로 보여드리도록 하겠습니다.

 먼저 컨트롤러입니다. 컨트롤러에서는 서비스를 호출하여 진행하도록 하겠습니다.

 코드는 아래와 같습니다.

 

	@Autowired
	MemberService memberService;

	@RequestMapping(value = "/test3", method = RequestMethod.GET)
	public ModelAndView test(HttpServletRequest request, HttpServletResponse response) throws JsonGenerationException, JsonMappingException, IOException {
		logger.info("Test" );
		List<MemberVO> memberList = memberService.selectList();
		for (MemberVO memberVO : memberList) {
			logger.info(" Member ID :  " + memberVO.getId());
			logger.info(" Member PassWord :  " + memberVO.getPassword());
		}
		
		return null;
	}

 

 

 아래는 서비스 코드입니다. MemberService 서비스를 하나 생성하여 주시고, 아래 코드를 삽입해주세요.

 

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.mycom.myapp.dao.MemberDAO;
import com.mycom.myapp.vo.MemberVO;

@Service
public class MemberService {
	
	@Autowired
	MemberDAO memberDAO;
	
	public List<MemberVO> selectList() {
		return memberDAO.select();
	}
	
}

 

 마지막 DAO 입니다. MemberDAO를 하나 생성하여 주시고, 아래 코드를 삽입해주세요.

 

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.mycom.myapp.vo.MemberVO;

@Repository
public class MemberDAO {
	@Autowired protected SqlSession sqlSession;
	
	public List<MemberVO> select() {
		return sqlSession.selectList("member.selectMember");
	}

}

 

위 코드를 적용한 결과는 아래와 같습니다.