이클립스 스프링 오라클 연동 - ikeullibseu seupeuling olakeul yeondong

이 책읜 관계형 데이터베이스인 Oralce 11g XE를 이용해서 작성합니다. 오라클 설치는 교재에도 있기에 저는 따로 다루지 않고 설치되어 있다는 가정 하에 시작하겠습니다.

계정 생성


CREATE USER book_ex IDENTIFIED BY book_ex
DEFAULT TABLESPACE USERS
TEMPORARY TABLESPACE TEMP;

SQL Developer에 System 계정으로 접속에 성공한 후에는 예제에서 사용할 계정을 만들기 위해 위의 SQL문을 칩니다. 

- 계정의 이름 :  book_ex

- 비밀번호 : book_ex

- 기본 테이블 스페이스 : USERS

- 임시 테이블 스페이서 : TEMP

GRANT CONNECT, DBA TO BOOK_EX;

8080 포트 변경


오라클의 경우 기본적을 8080 포트를 사용합니다. 하지만 웹 개발에서 많이 사용되는 Tomcat의 기본 포트가 8080 이기 때문에 둘의 충돌을 미연에 방지하고자 오라클의 포트를 변경하도록 하겠습니다.

SELECT dbms_xdb.gethttpport() FROM dual;

위 구문은 현재 사용하는 포트 번호가 몇 번인지 확인합니다. 쿼리의 결과가 8080으로 출력되는경우

exec dbms_xdb.sethttpport(9090);

를 입력하여 포트번호를 변경합니다.

이클립스 스프링 오라클 연동 - ikeullibseu seupeuling olakeul yeondong

다시 조회를 했을 때 9090으로 나온다면 정상적으로 포트번호가 변경 된 것 입니다.

프로젝트의 JDBC 연결


본격적인 예제를 구성하기 위해서는 반드시 JDBC 연결에 문제가 없는지 확인해야 합니다. 우선 JDBC 연결을 하려면 JDBC Driver가 필요합니다. Oracle JDBC Driver는 11g까지는 직접 jar파일을 추가해줘야 합니다.

(SQL Developer를 설치 했다면 jdbc/lib 폴더에 ojdbc8.jar가 존재할 것입니다.)

* 다운로드할 때는 반드시 현재 사용하는 데이터베이스 버전에 맞는 드라이버를 이용해야만 합니다. 가끔 이 사소한 차이가 큰 에러를 발생시킬 수 있습니다.

이클립스 스프링 오라클 연동 - ikeullibseu seupeuling olakeul yeondong

Build Path>Add External JARs를 사용해 ojdbc8.jar를 추가합니다. 

이클립스 스프링 오라클 연동 - ikeullibseu seupeuling olakeul yeondong

나중에 war 파일로 만들어 질 때에도 jar 파일이 포함될 수 있도록 Deployment  Assembly 항목에도 jar 파일을 추가합니다.

* 테스트는 정상 통과하나 Tomcat에서 JDBC 드라이버에 문제가 생겼다고 나온다면 Web Deployment Assembly를 확인해봐야 합니다.)

JDBC 테스트 코드

JDBC 드라이버가 정상적으로 추가되었고, 데이터베이스 연결이 가능하다면 이를 눈으로 확인할 수 있게 테스트 코드를 작성해야 합니다.

org.mido.persistence.JdbcTests 

package org.mido.persistence;

import static org.junit.Assert.fail;

import java.sql.Connection;
import java.sql.DriverManager;

import org.junit.Test;

import lombok.extern.log4j.Log4j;

@Log4j
public class JdbcTests {
	static {
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@Test
	public void testConnection() {
		try(Connection con =
				DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE","System","root")){
					log.info(con);
				}catch (Exception e) {
					fail(e.getMessage());
				}
	}
}
이클립스 스프링 오라클 연동 - ikeullibseu seupeuling olakeul yeondong

정상 수행이 됨을 알 수 있다. (Connection 객체가 출력)

커넥션 풀 설정


커넥션 풀(Connection Pool)이란?

- 일반적으로 여러 명의 사용자를 동시에 처리해야 하는 웹 애플리케이션의 경우 데이터베이스 연결을 이용할 때 사용하는 것.

- 스프링에 커넥션 풀을 등록해서 사용해도 좋습니다. DataSource를 통해 매번 데이터 베이스와 연결하는 방식이 아닌 미리 연결을 맺어주고 반환하는 구조를 이용하여 성능 향상을 꾀할 수 있습니다.

- 커넥션 풀의 종류는 여러 가지가 있지만 예제는 HikariCP를 이용하겠습니다.

라이브러리 추가

	<!-- HikariCP -->
		<dependency>
			<groupId>com.zaxxer</groupId>
			<artifactId>HikariCP</artifactId>
			<version>2.7.4</version>
		</dependency>

XML설정) DataSource 설정 -root-context.xml

<?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:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
	
	<!-- Root Context: defines shared resources visible to all other web components -->
	<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
		<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>
		<property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1521:XE"></property>
		<property name="username" value="System"></property>
		<property name="password" value="root"></property>
	</bean>
	<!-- HikariCP configuration -->
	<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
	<constructor-arg ref="hikariConfig"></constructor-arg>
	</bean>	
	<context:component-scan base-package="org.mido.sample">
	</context:component-scan>
</beans>

스프링에서 root-context,xml은 스프링이 로딩되면 서 읽어 들이는 문서이므로, 주로 이미 만들어진 클래스들을 이용해서 스프링의 빈으로 등록할 때 사용합니다.

-> 프로젝트에 직접 작성하는 클래스들은 어노테이션을 이용하는 경우가 많고, 외부 jar 파일 등을 사용하는 클래스들은 <bean>태그를 이용해서 작성하는 경우가 대부분입니다.

Java 설정) RootConfig

package org.mido.config;

import javax.sql.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

@Configuration
@ComponentScan(basePackages = {"org.mido.sample"})
public class RootConfig {
	@Bean
	public DataSource dataSource() {
		HikariConfig hikariConfig = new HikariConfig();
		hikariConfig.setDriverClassName("oracle.jdbc.driver.OracleDriver");
		hikariConfig.setJdbcUrl("jdbc:oracle:thin:@localhost:1521:XE");
		hikariConfig.setUsername("System");
		hikariConfig.setPassword("root");
		
		HikariDataSource dataSource = new HikariDataSource(hikariConfig);
		return dataSource;
	}
}

Java 설정을 이용하는 경우에는 앞에서 작성한 RootConfig 클래스와 @Bean을 이용해서 처리합니다. @Bean은 XML 설정에서의 <bean>과 동일한 역할을 수행하고 @Bean이 선언된 메서드의 실행 결과로 반환된 객체는 스프링의 객체로 등록됩니다.(빈으로 등록됩니다.)

DataSourceTest

package org.mido.persistence;

import java.sql.Connection;

import javax.sql.DataSource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;

import lombok.Setter;
import lombok.extern.log4j.Log4j;

@RunWith(SpringRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml")
// Java로 설정하는 경우
//@ContextConfiguration(classes= {RootConfig.class})
@Log4j
public class DataSourceTest {
	@Setter(onMethod_=@Autowired)
	private DataSource dataSource;
	@Test
	public void testConnection() {
		try(Connection con = dataSource.getConnection()){
			log.info(con);
		}catch (Exception e) {
			org.junit.Assert.fail(e.getMessage());
		}
	}
}

테스트 코드는 스프링에 Bean으로 등록된 DataSource를 사용해 Connection을 제대로 처리할 수 있는지를 확인해 보는용도입니다. testConnection()을 실행해보면 HikariCP가 시작되고, 종료되는 로그를 확인할 수 있습니다.

이클립스 스프링 오라클 연동 - ikeullibseu seupeuling olakeul yeondong